@@ -49,6 +49,7 @@ class Sync implements Setup, Assets {
4949 'sync_error ' => '_sync_error ' ,
5050 'cloudinary ' => '_cloudinary_v2 ' ,
5151 'folder_sync ' => '_folder_sync ' ,
52+ 'suffix ' => '_suffix ' ,
5253 'syncing ' => '_cloudinary_syncing ' ,
5354 'downloading ' => '_cloudinary_downloading ' ,
5455 );
@@ -172,13 +173,85 @@ public function get_signature( $post_id ) {
172173 return $ return ;
173174 }
174175
176+ /**
177+ * Generate a new Public ID for an asset.
178+ *
179+ * @param int $attachment_id The attachment ID for the new public ID.
180+ *
181+ * @return string|null
182+ */
183+ public function generate_public_id ( $ attachment_id ) {
184+ $ settings = $ this ->plugin ->config ['settings ' ];
185+ $ cld_folder = trailingslashit ( $ settings ['sync_media ' ]['cloudinary_folder ' ] );
186+ $ file = get_attached_file ( $ attachment_id );
187+ $ file_info = pathinfo ( $ file );
188+ $ public_id = $ cld_folder . $ file_info ['filename ' ];
189+
190+ return $ public_id ;
191+ }
192+
193+ /**
194+ * Maybe add a suffix to the public ID if it's not unique.
195+ *
196+ * @param string $public_id The public ID to maybe add a suffix.
197+ * @param int $attachment_id The attachment ID.
198+ * @param string|null $suffix The suffix to maybe add.
199+ *
200+ * @return string The public ID.
201+ */
202+ public function add_suffix_maybe ( $ public_id , $ attachment_id , $ suffix = null ) {
203+
204+ // Test if asset exists by calling just the head on the asset url, to prevent API rate limits.
205+ $ url = $ this ->plugin ->components ['connect ' ]->api ->cloudinary_url ( $ public_id . $ suffix );
206+ $ req = wp_remote_head ( $ url , array ( 'body ' => array ( 'rdm ' => wp_rand ( 100 , 999 ) ) ) );
207+ $ asset_error = strtolower ( wp_remote_retrieve_header ( $ req , 'x-cld-error ' ) );
208+ $ code = wp_remote_retrieve_response_code ( $ req );
209+
210+ // If the request is not a 404 & does not have a cld-error header stating resource not found, it exists and should be checked that it's not a resync or generate a prefixed ID.
211+ if ( 404 !== $ code && false === strpos ( $ asset_error , 'resource not found ' ) ) {
212+
213+ // Get the attachment type.
214+ if ( wp_attachment_is ( 'image ' , $ attachment_id ) ) {
215+ $ type = 'image ' ;
216+ } elseif ( wp_attachment_is ( 'video ' , $ attachment_id ) ) {
217+ $ type = 'video ' ;
218+ } elseif ( wp_attachment_is ( 'audio ' , $ attachment_id ) ) {
219+ $ type = 'audio ' ;
220+ } else {
221+ // not supported.
222+ return null ;
223+ }
224+ $ cld_asset = $ this ->plugin ->components ['connect ' ]->api ->get_asset_details ( $ public_id , $ type );
225+ if ( ! is_wp_error ( $ cld_asset ) && ! empty ( $ cld_asset ['public_id ' ] ) ) {
226+ $ context_id = null ;
227+
228+ // Exists, check to see if this asset originally belongs to this ID.
229+ if ( ! empty ( $ cld_asset ['context ' ] ) && ! empty ( $ cld_asset ['context ' ]['custom ' ] ) && ! empty ( $ cld_asset ['context ' ]['custom ' ]['wp_id ' ] ) ) {
230+ $ context_id = (int ) $ cld_asset ['context ' ]['custom ' ]['wp_id ' ];
231+ }
232+
233+ // Generate new ID only if context ID is not related.
234+ if ( $ context_id !== $ attachment_id ) {
235+ // Generate a new ID with a uniqueID prefix.
236+ $ suffix = '- ' . uniqid ();
237+
238+ // Return new potential suffixed ID.
239+ return $ this ->add_suffix_maybe ( $ public_id , $ attachment_id , $ suffix );
240+ }
241+ }
242+ }
243+
244+ return $ suffix ;
245+ }
246+
175247 /**
176248 * Additional component setup.
177249 */
178250 public function setup () {
179251 if ( $ this ->plugin ->config ['connect ' ] ) {
180252 $ this ->managers ['upload ' ]->setup ();
181253 $ this ->managers ['delete ' ]->setup ();
254+ $ this ->managers ['push ' ]->setup ();
182255 }
183256 }
184257}
0 commit comments