Search code examples
phpwordpressshortcodewordpress-shortcode

Wordpress, validate for required shortcode attributes


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?


Solution

  • 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 );
        }
    }