I have a code that validate attributes during render of shortcode. But, I need to implement validation for required attributes of shortcode when administrator of the wordpress editing the post(Before save). Is it really hard to make it on wordpress?
Seems like there is no easy way to achieve it. Need to make a lot of staff:
1. Catch post update event:
add_action( 'pre_post_update', [ $this, 'validate_post_short_code_attributes' ], 10, 2 );
2. Parse your shortcode in the post and validate
public function validate_post_short_code_attributes( $post_id, $post_data ) {
# If this is just a revision, don't do anything.
if ( wp_is_post_revision( $post_id ) ) {
return;
}
preg_match_all( '/(\[viatel\s([\S\s]+?)])/', $post_data['post_content'], $matches );
if ( array_key_exists( 2, $matches ) ) {
$attrs = shortcode_parse_atts( $matches[2][0] );
try {
$this->validate_required_attributes( $attrs );
} catch ( LogicException $exception ) {
# Add a notification
update_option(
'viatel_notifications',
json_encode( [ 'error', $exception->getMessage() ] )
);
# And redirect
header( 'Location: ' . get_edit_post_link( $post_id, 'redirect' ) );
exit;
}
}
}
3. Implement hacks with notifications and options
More information from this thread
add_action( 'admin_notices', 'viatel_notice' );
function viatel_notice() {
$notifications = get_option( 'viatel_notifications' );
if ( ! empty( $notifications ) ) {
$notifications = json_decode( $notifications, true );
#notifications[0] = (string) Type of notification: error, updated or update-nag
#notifications[1] = (string) Message
#notifications[2] = (boolean) is_dismissible?
switch ( $notifications[0] ) {
case 'error': # red
case 'updated': # green
case 'update-nag': # ?
$class = $notifications[0];
break;
default:
# Defaults to error just in case
$class = 'error';
break;
}
$is_dismissible = '';
if ( isset( $notifications[2] ) && $notifications[2] == true ) {
$is_dismissible = 'is_dismissible';
}
echo '<div class="' . $class . ' notice ' . $is_dismissible . '">';
echo '<p>' . $notifications[1] . '</p>';
echo '</div>';
# Let's reset the notification
update_option( 'viatel_notifications', false );
}
}