@@ -29,6 +29,15 @@ class Gallery extends Settings_Component {
2929 */
3030 const GALLERY_LIBRARY_HANDLE = 'cld-gallery ' ;
3131
32+ /**
33+ * This is a "false" mime type for GLB files.
34+ *
35+ * Canonically, the correct mime type for GLB files is `model/gltf-binary`,
36+ * however we need to fake an `image/` mime type to make the gallery
37+ * picker to list GLB files.
38+ */
39+ const GALLERY_GLB_MIME_TYPE = 'image/glb ' ;
40+
3241 /**
3342 * Holds the settings slug.
3443 *
@@ -462,6 +471,12 @@ public function prepare_block_render( $content, $block ) {
462471 if ( ! wp_get_attachment_url ( $ attachment ['attachmentId ' ] ) ) {
463472 continue ;
464473 }
474+
475+ // Initialize 3D model support.
476+ if ( self ::GALLERY_GLB_MIME_TYPE === get_post_mime_type ( $ attachment ['attachmentId ' ] ) ) {
477+ $ attachment ['mediaType ' ] = '3d ' ;
478+ }
479+
465480 $ transformations = $ this ->media ->get_transformations ( $ attachment ['attachmentId ' ] );
466481 if ( ! empty ( $ transformations ) ) {
467482 $ attachment ['transformation ' ] = array ( 'transformation ' => $ transformations );
@@ -568,6 +583,105 @@ function_exists( 'has_block' ) && has_block( 'cloudinary/gallery' )
568583 return $ can ;
569584 }
570585
586+ /**
587+ * Allow GLB files to be uploaded.
588+ *
589+ * @param array $mimes The mime types.
590+ *
591+ * @return array
592+ */
593+ public function add_glb_mime ( $ mimes ) {
594+ $ mimes ['glb ' ] = self ::GALLERY_GLB_MIME_TYPE ;
595+
596+ return $ mimes ;
597+ }
598+
599+ /**
600+ * Pass the GLB file type check.
601+ *
602+ * @param array $file_data The file data.
603+ * @param string $file The file.
604+ * @param string $filename The filename.
605+ *
606+ * @return array
607+ */
608+ public function pass_glb_filetype_check ( $ file_data , $ file , $ filename ) {
609+ if ( 'glb ' === pathinfo ( $ filename , PATHINFO_EXTENSION ) ) {
610+ $ file_data ['ext ' ] = 'glb ' ;
611+ $ file_data ['type ' ] = self ::GALLERY_GLB_MIME_TYPE ;
612+ }
613+
614+ return $ file_data ;
615+ }
616+
617+ /**
618+ * Allow GLB files to be uploaded to Cloudinary.
619+ *
620+ * @param array $types The allowed extensions.
621+ *
622+ * @return array
623+ */
624+ public function allow_glb_for_cloudinary ( $ types ) {
625+ $ types [] = 'glb ' ;
626+
627+ return $ types ;
628+ }
629+
630+ /**
631+ * Allow GLB files to be delivered from Cloudinary.
632+ *
633+ * @param bool $is Whether the file is deliverable.
634+ * @param int $attachment_id The attachment ID.
635+ *
636+ * @return bool
637+ */
638+ public function allow_glb_delivery_from_cloudinary ( $ is , $ attachment_id ) {
639+ if ( self ::GALLERY_GLB_MIME_TYPE === get_post_mime_type ( $ attachment_id ) ) {
640+ $ is = true ;
641+ }
642+
643+ return $ is ;
644+ }
645+
646+ /**
647+ * Replace image urls from .glb to .png.
648+ *
649+ * This allows the GLB files to be served as PNG files in the image context.
650+ *
651+ * @param string $url The URL.
652+ * @param int $attachment_id The attachment ID.
653+ *
654+ * @return string
655+ */
656+ public function admin_replace_glb_url ( $ url , $ attachment_id ) {
657+ if ( ! is_admin () ) {
658+ return $ url ;
659+ }
660+
661+ if ( self ::GALLERY_GLB_MIME_TYPE === get_post_mime_type ( $ attachment_id ) ) {
662+ $ url = str_replace ( '.glb ' , '.png ' , $ url );
663+ }
664+ return $ url ;
665+ }
666+
667+ /**
668+ * We pretend that GLB files are images with dimensions of 512x512.
669+ *
670+ * This allows WordPress to correctly render the GLB files as images in the media library.
671+ *
672+ * @param array $metadata The attachment metadata.
673+ * @param int $attachment_id The attachment ID.
674+ *
675+ * @return array
676+ */
677+ public function inject_glb_metadata ( $ metadata , $ attachment_id ) {
678+ if ( self ::GALLERY_GLB_MIME_TYPE === get_post_mime_type ( $ attachment_id ) ) {
679+ $ metadata ['width ' ] = 512 ;
680+ $ metadata ['height ' ] = 512 ;
681+ }
682+ return $ metadata ;
683+ }
684+
571685 /**
572686 * Setup hooks for the gallery.
573687 */
@@ -578,5 +692,24 @@ public function setup_hooks() {
578692 add_action ( 'admin_enqueue_scripts ' , array ( $ this , 'enqueue_admin_scripts ' ) );
579693 add_filter ( 'render_block ' , array ( $ this , 'prepare_block_render ' ), 10 , 2 );
580694 add_filter ( 'cloudinary_admin_pages ' , array ( $ this , 'register_settings ' ) );
695+
696+ /**
697+ * Filter to allow GLB 3D model files to be uploaded.
698+ *
699+ * WARNING: This is an experimental hook. The only place where GLB files can be used
700+ * is in the Cloudinary Gallery block.
701+ *
702+ * @param bool $allow_glb_upload Whether to allow GLB files to be uploaded.
703+ *
704+ * @return bool
705+ */
706+ if ( apply_filters ( 'cloudinary_allow_glb_upload ' , false ) ) {
707+ add_filter ( 'upload_mimes ' , array ( $ this , 'add_glb_mime ' ), 20 , 1 );
708+ add_filter ( 'wp_check_filetype_and_ext ' , array ( $ this , 'pass_glb_filetype_check ' ), 10 , 3 );
709+ add_filter ( 'cloudinary_allowed_extensions ' , array ( $ this , 'allow_glb_for_cloudinary ' ) );
710+ add_filter ( 'cloudinary_is_deliverable ' , array ( $ this , 'allow_glb_delivery_from_cloudinary ' ), 10 , 2 );
711+ add_filter ( 'wp_get_attachment_url ' , array ( $ this , 'admin_replace_glb_url ' ), 11 , 2 );
712+ add_filter ( 'wp_generate_attachment_metadata ' , array ( $ this , 'inject_glb_metadata ' ), 10 , 2 );
713+ }
581714 }
582715}
0 commit comments