Can't display errors in attachment_fields_to_save

I am writing a plugin for adding a custom field to the image attachment dialogue box, the plugin works for storing valid input data. I have a problem for showing the error message "This is not a valid URL".

I think that I followed the documentation correctly but maybe there is something that I still missing.

class my_plugin {

    public function __construct( ) {

        $this-url_pattern = "/^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?" .
"([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|" . 
"%[a-fA-f\d]{2,2})*)*(\?(?([-+_~.\\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]" . 
"|%[a-fA-f\d]{2,2})*)?$/";

        add_filter("attachment_fields_to_edit", array($this, "videourl_image_attachment_fields_to_edit"), 10, 4);
        add_filter("attachment_fields_to_save", array($this, "videourl_image_attachment_fields_to_save"), 10, 5);

    }

    public function videourl_image_attachment_fields_to_edit($form_fields, $post) {

        $form_fields["videourl"]["label"] = __("Video URL");
        $form_fields["videourl"]["helps"] = "Set a video URL for this image";

        $form_fields["videourl"]["input"] = "text";
        $form_fields["videourl"]["value"] = get_post_meta($post-ID, "_videourl", true);

        return $form_fields;
    }


    function videourl_image_attachment_fields_to_save($post, $attachment) {

        if( isset($attachment['videourl']) ){

            if( mb_strlen ( trim($attachment['videourl']) )  0  preg_match($this-url_pattern, trim($attachment['videourl']))){
                update_post_meta($post['ID'], '_videourl', $attachment['videourl']);
            }elseif(mb_strlen ( trim($attachment['videourl']) ) == 0){
                delete_post_meta($post['ID'], '_videourl');
            }else{
                $post['errors']['videourl']['errors'][] = __('This is not a valid URL.');
            }
        }

        return $post;
    }
}

Topic attachment-fields-to-edit custom-field Wordpress

Category Web


In Edit Media, if we look the admin notice on update attachment, it use redirect function to handle those notice. So, basically we can still handle those error with redirect function too, then hook admin_notices.

Here my approach how to handle error in screen attachment Edit Media.

class my_plugin {

    public function __construct( ) {

        $this->url_pattern = "/^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?" .
"([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|" . 
"%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]" . 
"|%[a-fA-f\d]{2,2})*)?$/";

        add_filter("attachment_fields_to_edit", array($this, "videourl_image_attachment_fields_to_edit"), 10, 4);
        add_filter("attachment_fields_to_save", array($this, "videourl_image_attachment_fields_to_save"), 20, 2);

        /**
         * Hook admin_notices
         *
         */
        add_action( 'admin_notices', array( $this, 'admin_notices' ) );
    }

    /**
     * Fire admin_notices function to show message
     *
     */
    public function admin_notices()
    {
        global $current_screen;

        /**
         * Check current screen
         *
         */
        if ( 'attachment' == $current_screen->id )
        {
            if ( isset( $_GET[ 'error' ] ) && 1 == absint( $_GET[ 'error' ] ) )
            {
                /**
                 * HTML format to show notices
                 *
                 */
                printf ( '<div id="message" class="%1$s notice is-dismissible"><p>%2$s</p><button type="button" class="notice-dismiss"><span class="screen-reader-text">%3$s.</span></button></div>',
                    'error', //type error or updated
                    __( 'Your Error Messages.', 'text-domain' ), //your error text
                    __( 'Dismiss this notice', 'text-domain' ) //for close button
                );
            }

            /**
             * Remove query parameter 'message' and 'error'
             *
             */
            $_SERVER['REQUEST_URI'] = remove_query_arg( array( 'message', 'error' ), $_SERVER['REQUEST_URI'] );
        }
    }

    public function videourl_image_attachment_fields_to_edit($form_fields, $post) {

        $form_fields["videourl"]["label"] = __("Video URL");
        $form_fields["videourl"]["helps"] = "Set a video URL for this image";

        $form_fields["videourl"]["input"] = "text";
        $form_fields["videourl"]["value"] = get_post_meta($post->ID, "_videourl", true);

        return $form_fields;
    }


    public function videourl_image_attachment_fields_to_save( $post, $attachment ) {

        if ( isset( $attachment['videourl'] ) )
        {
            if ( mb_strlen ( trim($attachment['videourl'] ) ) > 0 && preg_match($this->url_pattern, trim($attachment['videourl'] ) ) ) {
                update_post_meta( $post['ID'], '_videourl', $attachment['videourl'] );
            } elseif( mb_strlen ( trim($attachment['videourl']) ) == 0 ){
                delete_post_meta( $post['ID'], '_videourl' );
            }

            /**
             * Handle error if empty 'videourl'
             *
             */
            if ( empty( $attachment['videourl'] ) )
            {
                /**
                 * Build error query for redirection
                 *
                 */
                $location = add_query_arg(
                    array(
                        'error' => 1
                    ),
                    $post['_wp_http_referer']
                );
                wp_safe_redirect( $location ); // wp-admin/post.php?post={id}&action=edit&error=1
                exit;
            }
        }

        return $post;
    }
}

You can change the code suit your needs. It look like a little bit tricky but I hope this helps.


At the time this is a known bug

https://core.trac.wordpress.org/ticket/30687

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.