diff --git a/block.json b/block.json index 8354fd8..638cdec 100644 --- a/block.json +++ b/block.json @@ -30,6 +30,14 @@ "type": "string", "default": "" }, + "customAvatarMediaId": { + "type": "integer", + "default": 0 + }, + "customAvatarMediaUrl": { + "type": "string", + "default": "" + }, "customTitle": { "type": "string", "default": "" diff --git a/src/Block.php b/src/Block.php index c08aad0..094b310 100644 --- a/src/Block.php +++ b/src/Block.php @@ -14,6 +14,52 @@ public function __construct( array $attributes ) { $this->attributes = $attributes; } + /** + * Resolve the repository block avatar URL (custom image or GitHub owner avatar). + * + * Falls back to the repo owner's GitHub avatar for both user- and org-owned repos. + */ + protected function get_repo_avatar_url( object $data ): string { + $media_id = (int) ( $this->attributes['customAvatarMediaId'] ?? 0 ); + + if ( $media_id > 0 && wp_attachment_is_image( $media_id ) ) { + $custom_url = wp_get_attachment_image_url( $media_id, 'medium' ); + + if ( is_string( $custom_url ) && $custom_url !== '' ) { + return $custom_url; + } + } + + return $data->owner->avatar_url; + } + + /** + * Alt text for the repository block avatar image. + */ + protected function get_repo_avatar_alt( object $data ): string { + $media_id = (int) ( $this->attributes['customAvatarMediaId'] ?? 0 ); + + if ( $media_id > 0 ) { + $attachment_alt = get_post_meta( $media_id, '_wp_attachment_image_alt', true ); + + if ( is_string( $attachment_alt ) && $attachment_alt !== '' ) { + return $attachment_alt; + } + } + + $owner_type = isset( $data->owner->type ) && $data->owner->type === 'Organization' + ? __( 'organization', 'blocks-for-github' ) + : __( 'owner', 'blocks-for-github' ); + + return sprintf( + /* translators: 1: repository name, 2: owner or organization label, 3: GitHub login */ + __( '%1$s %2$s avatar (%3$s)', 'blocks-for-github' ), + $data->name, + $owner_type, + $data->owner->login + ); + } + protected function fetchData( string $url, string $keySuffix = '' ) { $key = "blocks_for_github_$keySuffix"; $data = get_transient( $key ); @@ -117,12 +163,15 @@ protected function getOutputOrError( $data, $output ) { * @throws Exception */ public function renderRepo( $data ) { + $avatar_url = $this->get_repo_avatar_url( $data ); + $avatar_alt = $this->get_repo_avatar_alt( $data ); + ob_start(); ?>
- <?php esc_html_e( $data->name ); ?> + <?php echo esc_attr( $avatar_alt ); ?>
diff --git a/src/edit.js b/src/edit.js index 0638518..15327fa 100644 --- a/src/edit.js +++ b/src/edit.js @@ -43,6 +43,8 @@ export default function Edit({attributes, setAttributes}) { showTwitter, mediaId, mediaUrl, + customAvatarMediaId, + customAvatarMediaUrl, preview, } = attributes; @@ -79,11 +81,32 @@ export default function Edit({attributes, setAttributes}) { }); }; + const removeCustomAvatar = () => { + setAttributes({ + customAvatarMediaId: 0, + customAvatarMediaUrl: '', + }); + }; + + const onSelectCustomAvatar = (media) => { + setAttributes({ + customAvatarMediaId: media.id, + customAvatarMediaUrl: media.url, + }); + }; + const media = useSelect( (select) => { return select('core').getMedia(mediaId); }, - [onSelectMedia] + [mediaId] + ); + + const customAvatarMedia = useSelect( + (select) => { + return select('core').getMedia(customAvatarMediaId); + }, + [customAvatarMediaId] ); return ( @@ -134,6 +157,76 @@ export default function Edit({attributes, setAttributes}) { }} /> + +
+

+ +

+ + ( + + )} + /> + +
+ {customAvatarMediaId !== 0 && ( + + ( + + )} + /> + + )} + {customAvatarMediaId !== 0 && ( + + + + )} +
+

+ {__( + 'Optional image for this repo block. When empty, the GitHub owner or organization avatar is used.', + 'stellarpay' + )} +

+
+