Metadata screenshot (#621)

Co-authored-by: Tetsuaki Hamano <tetsuaki.hamano@gmail.com>
This commit is contained in:
Jason Crist 2024-05-10 08:21:09 -04:00 committed by GitHub
parent f3dc5c9f52
commit 6273f0228c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 138 additions and 1 deletions

View file

@ -169,4 +169,63 @@ class Theme_Utils {
return 0;
}

public static function is_valid_screenshot_file( $file_path ) {
return Theme_Utils::get_screenshot_file_extension( $file_path ) !== null;
}

public static function get_screenshot_file_extension( $file_path ) {
$allowed_screenshot_types = array(
'png' => 'image/png',
'gif' => 'image/gif',
'jpg' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'webp' => 'image/webp',
'avif' => 'image/avif',
);
$filetype = wp_check_filetype( $file_path, $allowed_screenshot_types );
if ( in_array( $filetype['type'], $allowed_screenshot_types, true ) ) {
return $filetype['ext'];
}
return null;
}

public static function copy_screenshot( $file_path ) {

$new_screeenshot_id = attachment_url_to_postid( $file_path );

if ( ! $new_screeenshot_id ) {
return new \WP_Error( 'screenshot_not_found', __( 'Screenshot not found', 'create-block-theme' ) );
}

$new_screenshot_metadata = wp_get_attachment_metadata( $new_screeenshot_id );
$upload_dir = wp_get_upload_dir();

$new_screenshot_location = path_join( $upload_dir['basedir'], $new_screenshot_metadata['file'] );

$new_screenshot_filetype = Theme_Utils::get_screenshot_file_extension( $file_path );
$new_location = path_join( get_stylesheet_directory(), 'screenshot.' . $new_screenshot_filetype );

// copy and resize the image
$image_editor = wp_get_image_editor( $new_screenshot_location );
$image_editor->resize( 1200, 900, true );
$image_editor->save( $new_location );

return true;
}

public static function replace_screenshot( $new_screenshot_path ) {
if ( ! Theme_Utils::is_valid_screenshot_file( $new_screenshot_path ) ) {
return new \WP_Error( 'invalid_screenshot', __( 'Invalid screenshot file', 'create-block-theme' ) );
}

// Remove the old screenshot
$old_screenshot = wp_get_theme()->get_screenshot( 'relative' );
if ( $old_screenshot ) {
unlink( path_join( get_stylesheet_directory(), $old_screenshot ) );
}

// Copy the new screenshot
return Theme_Utils::copy_screenshot( $new_screenshot_path );
}

}

View file

@ -418,6 +418,11 @@ class Create_Block_Theme_API {
Theme_Readme::update_readme_txt( $theme )
);

// Replace Screenshot
if ( wp_get_theme()->get_screenshot() !== $theme['screenshot'] ) {
Theme_Utils::replace_screenshot( $theme['screenshot'] );
}

// Relocate the theme to a new folder
$response = Theme_Utils::relocate_theme( $theme['subfolder'] );


View file

@ -6,24 +6,37 @@ import { useState } from '@wordpress/element';
import { useSelect, useDispatch } from '@wordpress/data';
import { store as noticesStore } from '@wordpress/notices';
import {
// eslint-disable-next-line
__experimentalHStack as HStack,
// eslint-disable-next-line
__experimentalVStack as VStack,
// eslint-disable-next-line
__experimentalSpacer as Spacer,
// eslint-disable-next-line
__experimentalText as Text,
BaseControl,
Modal,
Button,
TextControl,
TextareaControl,
ExternalLink,
} from '@wordpress/components';
import { MediaUpload, MediaUploadCheck } from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import { postUpdateThemeMetadata } from '../resolvers';

const ALLOWED_SCREENSHOT_MEDIA_TYPES = [
'image/png',
'image/gif',
'image/jpg',
'image/jpeg',
'image/webp',
'image/avif',
];

export const ThemeMetadataEditorModal = ( { onRequestClose } ) => {
const [ theme, setTheme ] = useState( {
name: '',
@ -48,6 +61,7 @@ export const ThemeMetadataEditorModal = ( { onRequestClose } ) => {
author: themeData.author.raw,
author_uri: themeData.author_uri.raw,
tags_custom: themeData.tags.rendered,
screenshot: themeData.screenshot,
subfolder:
themeData.stylesheet.lastIndexOf( '/' ) > 1
? themeData.stylesheet.substring(
@ -80,6 +94,11 @@ export const ThemeMetadataEditorModal = ( { onRequestClose } ) => {
createErrorNotice( errorMessage, { type: 'snackbar' } );
} );
};

const onUpdateImage = ( image ) => {
setTheme( { ...theme, screenshot: image.url } );
};

return (
<Modal
isFullScreen
@ -195,6 +214,60 @@ Plugin Description`,
setTheme( { ...theme, recommended_plugins: value } )
}
/>
<BaseControl>
<BaseControl.VisualLabel>
{ __( 'Screenshot', 'create-block-theme' ) }
</BaseControl.VisualLabel>
<MediaUploadCheck>
<MediaUpload
title={ __( 'Screenshot', 'create-block-theme' ) }
onSelect={ onUpdateImage }
allowedTypes={ ALLOWED_SCREENSHOT_MEDIA_TYPES }
render={ ( { open } ) => (
<>
{ theme.screenshot ? (
<VStack alignment="left">
<img
src={ theme.screenshot }
style={ {
maxWidth: '200px',
height: 'auto',
aspectRatio: '4 / 3',
objectFit: 'cover',
} }
alt=""
/>
<Button
variant="secondary"
size="compact"
onClick={ open }
>
{ __(
'Replace',
'create-block-theme'
) }
</Button>
</VStack>
) : (
<HStack alignment="left">
<Button
variant="secondary"
size="compact"
onClick={ open }
>
{ __(
'Add screenshot',
'create-block-theme'
) }
</Button>
</HStack>
) }
</>
) }
value={ theme.screenshot }
/>
</MediaUploadCheck>
</BaseControl>
<TextControl
label={ __( 'Theme Subfolder', 'create-block-theme' ) }
value={ theme.subfolder }
@ -204,7 +277,7 @@ Plugin Description`,
/>
</VStack>
<Spacer />
<Button variant="secondary" onClick={ handleUpdateClick }>
<Button variant="primary" onClick={ handleUpdateClick }>
{ __( 'Update', 'create-block-theme' ) }
</Button>
</Modal>