Skip to content

Commit bf8fbc4

Browse files
committed
[Block Library - Site Logo]: Add permissions handling
1 parent 41bd403 commit bf8fbc4

File tree

3 files changed

+112
-43
lines changed

3 files changed

+112
-43
lines changed

lib/init.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,30 @@ function register_site_icon_url( $response ) {
188188

189189
add_filter( 'rest_index', 'register_site_icon_url' );
190190

191+
/**
192+
* Exposes the site logo to the Gutenberg editor through the WordPress REST
193+
* API. This is used for fetching this information when user has no rights
194+
* to update settings.
195+
*
196+
* @since 10.9
197+
*
198+
* @param WP_REST_Response $response Response data served by the WordPress REST index endpoint.
199+
* @return WP_REST_Response
200+
*/
201+
function register_site_logo_to_rest_index( $response ) {
202+
$data = $response->data;
203+
$logo_id = get_theme_mod( 'custom_logo' );
204+
$data['site_logo'] = array(
205+
'id' => $logo_id,
206+
'url' => wp_get_attachment_image_url( $logo_id, 'full' ),
207+
'alt' => get_post_meta( $logo_id, '_wp_attachment_image_alt', true ),
208+
);
209+
$response->set_data( $data );
210+
return $response;
211+
}
212+
213+
add_filter( 'rest_index', 'register_site_logo_to_rest_index' );
214+
191215
add_theme_support( 'widgets-block-editor' );
192216

193217
/**

packages/block-library/src/site-logo/edit.js

Lines changed: 69 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
ResizableBox,
1818
Spinner,
1919
ToggleControl,
20+
Icon,
2021
} from '@wordpress/components';
2122
import { useViewportMatch } from '@wordpress/compose';
2223
import {
@@ -73,7 +74,7 @@ const SiteLogo = ( {
7374
title: siteEntities.title,
7475
...pick( getSettings(), [ 'imageSizes', 'maxWidth' ] ),
7576
};
76-
} );
77+
}, [] );
7778

7879
function onResizeStart() {
7980
toggleSelection( false );
@@ -255,40 +256,65 @@ export default function LogoEdit( {
255256
const [ logoUrl, setLogoUrl ] = useState();
256257
const [ error, setError ] = useState();
257258
const ref = useRef();
258-
const { mediaItemData, siteLogo, url } = useSelect( ( select ) => {
259+
const { siteLogo, mediaItemData } = useSelect( ( select ) => {
259260
const siteSettings = select( coreStore ).getEditedEntityRecord(
260261
'root',
261262
'site'
262263
);
263-
const mediaItem = siteSettings.site_logo
264-
? select( coreStore ).getEntityRecord(
265-
'root',
266-
'media',
267-
siteSettings.site_logo
268-
)
269-
: null;
264+
const mediaItem =
265+
siteSettings.site_logo &&
266+
select( coreStore ).getEntityRecord(
267+
'root',
268+
'media',
269+
siteSettings.site_logo
270+
);
270271
return {
271272
mediaItemData: mediaItem && {
272273
url: mediaItem.source_url,
273274
alt: mediaItem.alt_text,
274275
},
275276
siteLogo: siteSettings.site_logo,
276-
url: siteSettings.url,
277277
};
278278
}, [] );
279-
279+
/**
280+
* Data for users with no proper rights have to be fetched
281+
* from REST `index` endpoint, which is public for all.
282+
*/
283+
const {
284+
canUserEdit,
285+
readOnlyLogo,
286+
readOnlyLogoMediaItemData,
287+
url,
288+
} = useSelect( ( select ) => {
289+
const { canUser, getEntityRecord } = select( coreStore );
290+
const siteData = getEntityRecord( 'root', '__unstableBase' );
291+
return {
292+
canUserEdit: canUser( 'update', 'settings' ),
293+
url: siteData?.url,
294+
readOnlyLogo: siteData?.site_logo?.id,
295+
readOnlyLogoMediaItemData: siteData?.site_logo && {
296+
url: siteData?.site_logo?.url,
297+
alt: siteData?.site_logo?.alt,
298+
},
299+
};
300+
}, [] );
280301
const { editEntityRecord } = useDispatch( coreStore );
281302
const setLogo = ( newValue ) =>
282303
editEntityRecord( 'root', 'site', undefined, {
283304
site_logo: newValue,
284305
} );
285306

286307
let alt = null;
287-
if ( mediaItemData ) {
308+
if ( canUserEdit && mediaItemData ) {
288309
alt = mediaItemData.alt;
289310
if ( logoUrl !== mediaItemData.url ) {
290311
setLogoUrl( mediaItemData.url );
291312
}
313+
} else if ( readOnlyLogoMediaItemData ) {
314+
alt = readOnlyLogoMediaItemData.alt;
315+
if ( logoUrl !== readOnlyLogoMediaItemData.url ) {
316+
setLogoUrl( readOnlyLogoMediaItemData.url );
317+
}
292318
}
293319

294320
const onSelectLogo = ( media ) => {
@@ -311,7 +337,7 @@ export default function LogoEdit( {
311337
setError( message[ 2 ] ? message[ 2 ] : null );
312338
};
313339

314-
const controls = logoUrl && (
340+
const controls = canUserEdit && logoUrl && (
315341
<BlockControls group="other">
316342
<MediaReplaceFlow
317343
mediaURL={ logoUrl }
@@ -325,10 +351,9 @@ export default function LogoEdit( {
325351

326352
const label = __( 'Site Logo' );
327353
let logoImage;
328-
if ( siteLogo === undefined ) {
354+
if ( canUserEdit && siteLogo === undefined ) {
329355
logoImage = <Spinner />;
330356
}
331-
332357
if ( !! logoUrl ) {
333358
logoImage = (
334359
<SiteLogo
@@ -343,45 +368,46 @@ export default function LogoEdit( {
343368
/>
344369
);
345370
}
346-
347-
const mediaPlaceholder = (
348-
<MediaPlaceholder
349-
icon={ <BlockIcon icon={ icon } /> }
350-
labels={ {
351-
title: label,
352-
instructions: __(
353-
'Upload an image, or pick one from your media library, to be your site logo'
354-
),
355-
} }
356-
onSelect={ onSelectLogo }
357-
accept={ ACCEPT_MEDIA_STRING }
358-
allowedTypes={ ALLOWED_MEDIA_TYPES }
359-
mediaPreview={ logoImage }
360-
notices={
361-
error && (
362-
<Notice status="error" isDismissible={ false }>
363-
{ error }
364-
</Notice>
365-
)
366-
}
367-
onError={ onUploadError }
368-
/>
369-
);
370-
371371
const classes = classnames( className, {
372372
'is-default-size': ! width,
373373
} );
374-
375374
const blockProps = useBlockProps( {
376375
ref,
377376
className: classes,
378377
} );
379-
380378
return (
381379
<div { ...blockProps }>
382380
{ controls }
383381
{ logoUrl && logoImage }
384-
{ ! logoUrl && mediaPlaceholder }
382+
{ ! canUserEdit && ! readOnlyLogo && (
383+
<div className="site-logo_placeholder">
384+
<Icon icon={ icon } />
385+
<p> { __( 'Site Logo' ) }</p>
386+
</div>
387+
) }
388+
{ canUserEdit && ! logoUrl && (
389+
<MediaPlaceholder
390+
icon={ <BlockIcon icon={ icon } /> }
391+
labels={ {
392+
title: label,
393+
instructions: __(
394+
'Upload an image, or pick one from your media library, to be your site logo'
395+
),
396+
} }
397+
onSelect={ onSelectLogo }
398+
accept={ ACCEPT_MEDIA_STRING }
399+
allowedTypes={ ALLOWED_MEDIA_TYPES }
400+
mediaPreview={ logoImage }
401+
notices={
402+
error && (
403+
<Notice status="error" isDismissible={ false }>
404+
{ error }
405+
</Notice>
406+
)
407+
}
408+
onError={ onUploadError }
409+
/>
410+
) }
385411
</div>
386412
);
387413
}

packages/block-library/src/site-logo/editor.scss

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,22 @@
8080
}
8181
}
8282
}
83+
.editor-styles-wrapper {
84+
.site-logo_placeholder {
85+
display: flex;
86+
flex-direction: row;
87+
align-items: flex-start;
88+
border-radius: $radius-block-ui;
89+
background-color: $white;
90+
box-shadow: inset 0 0 0 $border-width $gray-900;
91+
padding: $grid-unit-15;
92+
svg {
93+
margin-right: $grid-unit-15;
94+
}
95+
p {
96+
font-family: $default-font;
97+
font-size: $default-font-size;
98+
margin: 0;
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)