Skip to content

Commit bc53f8c

Browse files
authored
Merge pull request #1019 from cloudinary/add/glb-support
Experimental support for GLB models.
2 parents 0568a4f + 7512b9b commit bc53f8c

File tree

3 files changed

+138
-2
lines changed

3 files changed

+138
-2
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ coverage/html/
4040
# ENV files
4141
.env
4242

43+
# wp-env
44+
.wp-env.json
45+
4346
# IDE
4447
.vscode
4548

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

php/media/class-gallery.php

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)