@wordpress/editor
Version:
Enhanced block editor for WordPress posts.
165 lines (147 loc) • 4.15 kB
JavaScript
/**
* WordPress dependencies
*/
import { store as coreDataStore } from '@wordpress/core-data';
/**
* Internal dependencies
*/
import { store as editorStore } from '../store';
import { unlock } from '../lock-unlock';
/**
* Gets a list of post meta fields with their values and labels
* to be consumed in the needed callbacks.
* If the value is not available based on context, like in templates,
* it falls back to the default value, label, or key.
*
* @param {Object} select The select function from the data store.
* @param {Object} context The context provided.
* @return {Object} List of post meta fields with their value and label.
*
* @example
* ```js
* {
* field_1_key: {
* label: 'Field 1 Label',
* value: 'Field 1 Value',
* },
* field_2_key: {
* label: 'Field 2 Label',
* value: 'Field 2 Value',
* },
* ...
* }
* ```
*/
function getPostMetaFields( select, context ) {
const { getRegisteredPostMeta } = unlock( select( coreDataStore ) );
const registeredFields = getRegisteredPostMeta( context?.postType );
const metaFields = [];
Object.entries( registeredFields ).forEach( ( [ key, props ] ) => {
// Don't include footnotes or private fields.
if ( key === 'footnotes' || key.charAt( 0 ) === '_' ) {
return;
}
metaFields.push( {
label: props.title || key,
args: { key },
default: props.default,
type: props.type,
} );
} );
return metaFields;
}
function getValue( { select, context, args } ) {
const metaFields = getPostMetaFields( select, context );
const metaField = metaFields.find(
( field ) => field.args.key === args.key
);
// If the meta field was not found, it's either protected, inaccessible, or simply doesn't exist.
if ( ! metaField ) {
return args.key;
}
// Without a postId, we cannot look up a meta value.
if ( ! context?.postId ) {
// Return the default value for the meta field if available.
return metaField.default || metaField.label || args.key;
}
const { getEditedEntityRecord } = select( coreDataStore );
const entityMetaValues = getEditedEntityRecord(
'postType',
context?.postType,
context?.postId
).meta;
return entityMetaValues?.[ args.key ] ?? metaField?.label ?? args.key;
}
/**
* @type {WPBlockBindingsSource}
*/
export default {
name: 'core/post-meta',
getValues( { select, context, bindings } ) {
const newValues = {};
for ( const [ attributeName, binding ] of Object.entries( bindings ) ) {
newValues[ attributeName ] = getValue( {
select,
context,
args: binding.args,
} );
}
return newValues;
},
setValues( { dispatch, context, bindings } ) {
const newMeta = {};
Object.values( bindings ).forEach( ( { args, newValue } ) => {
newMeta[ args.key ] = newValue;
} );
dispatch( coreDataStore ).editEntityRecord(
'postType',
context?.postType,
context?.postId,
{
meta: newMeta,
}
);
},
canUserEditValue( { select, context, args } ) {
// Lock editing in query loop.
if ( context?.query || context?.queryId ) {
return false;
}
// Lock editing when `postType` is not defined.
if ( ! context?.postType ) {
return false;
}
const metaFields = getPostMetaFields( select, context );
const hasMatchingMetaField = metaFields.some(
( field ) => field.args.key === args.key
);
if ( ! hasMatchingMetaField ) {
return false;
}
// Check that custom fields metabox is not enabled.
const areCustomFieldsEnabled =
select( editorStore ).getEditorSettings().enableCustomFields;
if ( areCustomFieldsEnabled ) {
return false;
}
// Check that the user has the capability to edit post meta.
const canUserEdit = select( coreDataStore ).canUser( 'update', {
kind: 'postType',
name: context?.postType,
id: context?.postId,
} );
if ( ! canUserEdit ) {
return false;
}
return true;
},
getFieldsList( { select, context } ) {
const metaFields = getPostMetaFields( select, context );
// Remove 'default' property from meta fields.
return metaFields.map(
( { default: defaultProp, ...otherProps } ) => ( {
...otherProps,
} )
);
},
};