@@ -57,11 +57,12 @@ public function __construct( \Cloudinary\Plugin $plugin ) {
5757
5858 // Define the sync types and their option keys.
5959 $ sync_types = array (
60+ 'cloud_name ' => 'upload ' ,
61+ 'folder ' => 'upload ' ,
6062 'file ' => 'upload ' ,
63+ 'public_id ' => 'rename ' ,
6164 'breakpoints ' => 'explicit ' ,
6265 'options ' => 'context ' ,
63- 'folder ' => 'upload ' ,
64- 'cloud_name ' => 'upload ' ,
6566 );
6667 $ this ->sync_types = apply_filters ( 'cloudinary_sync_types ' , $ sync_types );
6768
@@ -303,15 +304,15 @@ private function get_sync_type( $attachment ) {
303304
304305 $ type = 'upload ' ;
305306 // Check for explicit (has public_id, but no breakpoints).
306- $ attachment_signature = $ attachment ->{Sync:: META_KEYS [ ' signature ' ]} ;
307+ $ attachment_signature = $ this -> plugin -> components [ ' sync ' ]-> get_signature ( $ attachment -> ID ) ;
307308 if ( empty ( $ attachment_signature ) ) {
308309 if ( ! empty ( $ attachment ->{Sync::META_KEYS ['public_id ' ]} ) ) {
309310 // Has a public id but no signature, explicit update to complete download.
310311 $ type = 'explicit ' ;
311312 }
312313 // fallback to upload.
313314 } else {
314- // Has signature. Compare and find if different .
315+ // Has signature find differences and use specific sync method .
315316 $ required_signature = $ this ->plugin ->components ['sync ' ]->generate_signature ( $ attachment ->ID );
316317 foreach ( $ required_signature as $ key => $ signature ) {
317318 if ( ( ! isset ( $ attachment_signature [ $ key ] ) || $ attachment_signature [ $ key ] !== $ signature ) && isset ( $ this ->sync_types [ $ key ] ) ) {
@@ -350,6 +351,9 @@ public function prepare_upload( $post, $down_sync = false ) {
350351 return new \WP_Error ( 'attachment_post_expected ' , __ ( 'An attachment post was expected. ' , 'cloudinary ' ) );
351352 }
352353
354+ // Get the media component.
355+ $ media = $ this ->plugin ->components ['media ' ];
356+
353357 // First check if this has a file and it can be uploaded.
354358 $ file = get_attached_file ( $ post ->ID );
355359 $ file_size = 0 ;
@@ -358,7 +362,7 @@ public function prepare_upload( $post, $down_sync = false ) {
358362 } elseif ( ! file_exists ( $ file ) ) {
359363 // May be an old upload type.
360364 $ src = get_post_meta ( $ post ->ID , '_wp_attached_file ' , true );
361- if ( $ this -> plugin -> components [ ' media ' ] ->is_cloudinary_url ( $ src ) ) {
365+ if ( $ media ->is_cloudinary_url ( $ src ) ) {
362366 // Download first maybe.
363367 if ( true === $ down_sync ) {
364368 $ download = $ this ->plugin ->components ['sync ' ]->managers ['download ' ]->down_sync ( $ post ->ID );
@@ -383,36 +387,44 @@ public function prepare_upload( $post, $down_sync = false ) {
383387
384388 // translators: variable is file size.
385389 $ error = sprintf ( __ ( 'File size exceeds the maximum of %s. This media asset will be served from WordPress. ' , 'cloudinary ' ), $ max_size_hr );
386- $ this -> plugin -> components [ ' media ' ] ->delete_post_meta ( $ post ->ID , Sync::META_KEYS ['pending ' ] ); // Remove Flag.
390+ $ media ->delete_post_meta ( $ post ->ID , Sync::META_KEYS ['pending ' ] ); // Remove Flag.
387391
388392 return new \WP_Error ( 'upload_error ' , $ error );
389393 }
390394
391395 // If it's got a public ID, then this is an explicit update.
396+ $ settings = $ this ->plugin ->config ['settings ' ];
392397 $ public_id = $ post ->{Sync::META_KEYS ['public_id ' ]}; // use the __get method on the \WP_Post to get post_meta.
393- $ dirs = wp_get_upload_dir ();
394- $ cld_folder = false ;
395- $ folder = trailingslashit ( $ dirs ['cloudinary_folder ' ] );
396- if ( '/ ' === $ dirs ['cloudinary_folder ' ] ) {
397- $ folder = '' ;
398- }
398+ $ cld_folder = trailingslashit ( $ settings ['sync_media ' ]['cloudinary_folder ' ] );
399399 if ( empty ( $ public_id ) ) {
400400 $ file_info = pathinfo ( $ file );
401- $ public_id = $ folder . $ file_info ['filename ' ];
402- }
403-
404- // Check if cloudinary folder is in public_id.
405- $ parts = explode ( '/ ' , $ public_id );
406- if ( untrailingslashit ( $ dirs ['cloudinary_folder ' ] ) === $ parts [0 ] ) {
407- $ cld_folder = $ dirs ['cloudinary_folder ' ];
401+ $ public_id = $ cld_folder . $ file_info ['filename ' ];
408402 }
409403
404+ // Assume that the public_id is a root item.
405+ $ public_id_folder = '' ;
406+ $ public_id_file = $ public_id ;
410407
408+ // Check if in a lower level.
409+ if ( false !== strpos ( $ public_id , '/ ' ) ) {
410+ // Split the public_id into path and filename to allow filtering just the ID and not giving access to the path.
411+ $ public_id_info = pathinfo ( $ public_id );
412+ $ public_id_folder = trailingslashit ( $ public_id_info ['dirname ' ] );
413+ $ public_id_file = $ public_id_info ['filename ' ];
414+ }
415+ // Check if this asset is a folder sync.
416+ $ folder_sync = $ media ->get_post_meta ( $ post ->ID , Sync::META_KEYS ['folder_sync ' ], true );
417+ if ( ! empty ( $ folder_sync ) ) {
418+ $ public_id_folder = $ cld_folder ; // Ensure the public ID folder is constant.
419+ } else {
420+ // Not folder synced, so set the folder to the folder that the asset originally came from.
421+ $ cld_folder = $ public_id_folder ;
422+ }
411423 // Prepare upload options.
412424 $ options = array (
413425 'unique_filename ' => false ,
414426 'resource_type ' => $ resource_type ,
415- 'public_id ' => $ public_id ,
427+ 'public_id ' => $ public_id_file ,
416428 'context ' => array (
417429 'caption ' => esc_attr ( $ post ->post_title ),
418430 'alt ' => $ post ->_wp_attachment_image_alt ,
@@ -434,17 +446,17 @@ public function prepare_upload( $post, $down_sync = false ) {
434446 $ imagesize = getimagesize ( $ file );
435447 $ meta ['width ' ] = $ imagesize [0 ];
436448 }
437- $ max_width = $ this -> plugin -> components [ ' media ' ] ->get_max_width ();
449+ $ max_width = $ media ->get_max_width ();
438450 // Add breakpoints request options.
439- if ( ! empty ( $ this -> plugin -> config [ ' settings ' ] ['global_transformations ' ]['enable_breakpoints ' ] ) ) {
451+ if ( ! empty ( $ settings ['global_transformations ' ]['enable_breakpoints ' ] ) ) {
440452 $ options ['responsive_breakpoints ' ] = array (
441453 'create_derived ' => true ,
442- 'bytes_step ' => $ this -> plugin -> config [ ' settings ' ] ['global_transformations ' ]['bytes_step ' ],
443- 'max_images ' => $ this -> plugin -> config [ ' settings ' ] ['global_transformations ' ]['breakpoints ' ],
454+ 'bytes_step ' => $ settings ['global_transformations ' ]['bytes_step ' ],
455+ 'max_images ' => $ settings ['global_transformations ' ]['breakpoints ' ],
444456 'max_width ' => $ meta ['width ' ] < $ max_width ? $ meta ['width ' ] : $ max_width ,
445- 'min_width ' => $ this -> plugin -> config [ ' settings ' ] ['global_transformations ' ]['min_width ' ],
457+ 'min_width ' => $ settings ['global_transformations ' ]['min_width ' ],
446458 );
447- $ transformations = $ this -> plugin -> components [ ' media ' ] ->get_transformation_from_meta ( $ post ->ID );
459+ $ transformations = $ media ->get_transformation_from_meta ( $ post ->ID );
448460 if ( ! empty ( $ transformations ) ) {
449461 $ options ['responsive_breakpoints ' ]['transformation ' ] = Api::generate_transformation_string ( $ transformations );
450462 }
@@ -474,14 +486,19 @@ public function prepare_upload( $post, $down_sync = false ) {
474486 $ breakpoints ['context ' ] = http_build_query ( $ breakpoints ['context ' ], null , '| ' );
475487 }
476488
477- $ return = array (
489+ // Restructure the path to the filename to allow correct placement in Cloudinary.
490+ $ public_id = $ public_id_folder . $ options ['public_id ' ];
491+ $ return = array (
478492 'file ' => $ file ,
479493 'folder ' => $ cld_folder ,
494+ 'public_id ' => $ public_id ,
480495 'breakpoints ' => array (),
481496 'options ' => $ options ,
482497 );
498+ $ return ['options ' ]['public_id ' ] = $ public_id ;
483499 if ( ! empty ( $ breakpoints ) ) {
484- $ return ['breakpoints ' ] = $ breakpoints ;
500+ $ return ['breakpoints ' ] = $ breakpoints ;
501+ $ return ['breakpoints ' ]['public_id ' ] = $ public_id ; // Stage public ID to folder for breakpoints.
485502 }
486503 $ this ->upload_options [ $ post ->ID ] = $ return ;
487504
@@ -519,6 +536,8 @@ public function push_attachments( $attachments ) {
519536 'total ' => count ( $ attachments ),
520537 'processed ' => 0 ,
521538 );
539+ // Get media component.
540+ $ media = $ this ->plugin ->components ['media ' ];
522541
523542 // Go over each attachment.
524543 foreach ( $ attachments as $ attachment ) {
@@ -560,7 +579,7 @@ public function push_attachments( $attachments ) {
560579 if ( 'explicit ' === $ sync_type ) {
561580 // Explicit update.
562581 $ args = array (
563- 'public_id ' => $ upload ['options ' ][ ' public_id ' ],
582+ 'public_id ' => $ upload ['public_id ' ],
564583 'type ' => 'upload ' ,
565584 );
566585 if ( ! empty ( $ upload ['options ' ]['responsive_breakpoints ' ] ) ) {
@@ -570,6 +589,13 @@ public function push_attachments( $attachments ) {
570589 $ args ['context ' ] = $ upload ['options ' ]['context ' ];
571590 }
572591 $ result = $ this ->plugin ->components ['connect ' ]->api ->explicit ( $ args );
592+ } elseif ( 'rename ' === $ sync_type ) {
593+ // Rename an asset.
594+ $ args = array (
595+ 'from_public_id ' => $ media ->get_post_meta ( $ attachment ->ID , Sync::META_KEYS ['public_id ' ] ),
596+ 'to_public_id ' => $ upload ['public_id ' ],
597+ );
598+ $ result = $ this ->plugin ->components ['connect ' ]->api ->{$ upload ['options ' ]['resource_type ' ]}( 'rename ' , 'POST ' , $ args );
573599 } else {
574600 // dynamic sync type..
575601 $ result = $ this ->plugin ->components ['connect ' ]->api ->{$ sync_type }( $ upload ['file ' ], $ upload ['options ' ] );
@@ -583,7 +609,7 @@ public function push_attachments( $attachments ) {
583609 if ( is_wp_error ( $ result ) ) {
584610 $ error = $ result ->get_error_message ();
585611 $ stats ['fail ' ][] = $ error ;
586- $ this -> plugin -> components [ ' media ' ] ->update_post_meta ( $ attachment ->ID , Sync::META_KEYS ['sync_error ' ], $ error );
612+ $ media ->update_post_meta ( $ attachment ->ID , Sync::META_KEYS ['sync_error ' ], $ error );
587613 continue ;
588614 }
589615
@@ -597,8 +623,8 @@ public function push_attachments( $attachments ) {
597623 if ( ! empty ( $ result ['version ' ] ) ) {
598624 $ meta_data [ Sync::META_KEYS ['version ' ] ] = $ result ['version ' ];
599625 }
600- $ this -> plugin -> components [ ' media ' ] ->delete_post_meta ( $ attachment ->ID , Sync::META_KEYS ['pending ' ] );
601- $ this -> plugin -> components [ ' media ' ] ->delete_post_meta ( $ attachment ->ID , Sync::META_KEYS ['sync_error ' ], false );
626+ $ media ->delete_post_meta ( $ attachment ->ID , Sync::META_KEYS ['pending ' ] );
627+ $ media ->delete_post_meta ( $ attachment ->ID , Sync::META_KEYS ['sync_error ' ], false );
602628 if ( ! empty ( $ this ->plugin ->config ['settings ' ]['global_transformations ' ]['enable_breakpoints ' ] ) ) {
603629 if ( ! empty ( $ result ['responsive_breakpoints ' ] ) ) { // Images only.
604630 $ meta_data [ Sync::META_KEYS ['breakpoints ' ] ] = $ result ['responsive_breakpoints ' ][0 ]['breakpoints ' ];
@@ -619,7 +645,7 @@ public function push_attachments( $attachments ) {
619645 $ meta = wp_get_attachment_metadata ( $ attachment ->ID , true );
620646 $ meta [ Sync::META_KEYS ['cloudinary ' ] ] = $ meta_data ;
621647 wp_update_attachment_metadata ( $ attachment ->ID , $ meta );
622- $ this -> plugin -> components [ ' media ' ] ->update_post_meta ( $ attachment ->ID , Sync::META_KEYS ['public_id ' ], $ upload ['options ' ]['public_id ' ] );
648+ $ media ->update_post_meta ( $ attachment ->ID , Sync::META_KEYS ['public_id ' ], $ upload ['options ' ]['public_id ' ] );
623649 // Search and update link references in content.
624650 $ content_search = new \WP_Query ( array ( 's ' => 'wp-image- ' . $ attachment ->ID , 'fields ' => 'ids ' , 'posts_per_page ' => 1000 ) );
625651 if ( ! empty ( $ content_search ->found_posts ) ) {
0 commit comments