2

I'm building a plugin that has a meta box. Some of the fields in the meta box are required. Is using jQuery the only method for achieving this? Can I require that a field is filled in using PHP?

1
  • 1
    You can either fill it with a default value, or check if the field is empty, maybe provide the user a notice on that, and don't allow for/apply the default functionality. But maybe you could get a more detailed and useful answer if you provided more information...?
    – tfrommen
    Commented Apr 22, 2013 at 17:23

3 Answers 3

4

You can use Javascript to create a first-line convenience warning, but that is not a secure solution. You will need to interrupt the post save to truly create a required field.

function req_meta_wpse_96762($data){
  $allow_pending = false;
  if (isset($_POST['meta'])) {
    foreach ($_POST['meta'] as $v) {
      if ('your_required_key' === $v['key'] && !empty($v['value'])) {
        $allow_pending = true;
      }
    }
  }
  if (false === $allow_pending) {
    $data['post_status'] = 'draft';
  }
  return $data;
}
add_action('wp_insert_post_data','req_meta_wpse_96762');

That will also reset the post to 'Draft' if the meta field is deleted.

1
  • Fine idea, but as written, this will have side effects. wp_insert_post_data is called when a post is trashed, for instance, and this will break the trash by setting the status to "draft" instead. You need to check if (@$data['post_status'] != 'publish') at the beginning, or check another field to avoid that.
    – Jess Mann
    Commented Apr 25, 2017 at 17:52
1

There is no way to require input per PHP. Only the browser can do that, and the browser gets the output after PHP is done.

You can add the attribute required:

<input name=foo required>

But not all browsers support that, and you have to check the value still in your validation handler.

1
  • The WP publish button seems to ignore this when I created my own meta box. Commented Dec 30, 2016 at 11:59
0

I know this is an old question but it's first result on Google... Here my two cents:

Remember add all javascript fields validations before.

Thanks to @s_ha_dum answer, this is my custom meta box validation method:

        public static function validateMetaBoxesFields($postData, $postArray) {
        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return $postData;
        }
        if (array_key_exists('post_type', $postData) && $postData['post_type'] === 'MY_POST_TYPE') {
            if (array_key_exists('post_status', $postData) && $postData['post_status'] === 'publish') {
                $valid = true;
                // Check meta box fields (in $postArray) if something not valid, set $valid to false;
                if (!$valid) {
                    $postData['post_status'] = 'draft';
                    add_filter('redirect_post_location', array (self::class, 'alterRedirectMessageOnEventSave'));
                }
            }
        }
        return $postData;
    }

Add filter:

add_filter('wp_insert_post_data', array (EventsPostTypeService::class, 'validateMetaBoxesFields'), 99, 2);

Due WordPress is showning post saved message, I need to filter redirect post location query. This is the method:

        public static function alterRedirectMessageOnEventSave($location) {
        $location = remove_query_arg('message', $location);
        // 550 or other number, @see wp-admin/edit-form-advanced.php L:146 - 183
        $location = add_query_arg('message', 550, $location);
        return $location;
    }

And finally we add our custom message:

        public static function addCustomPostUpdateMessages($messages) {
        $messages['post'][550] = __('Post Type cannot be created due empty required fields: %s', 'my_text_domain');
        return $messages;
    }

%s can be replaced with a transient data, or other way you want to save not valid meta box fields.

Remember to add filter:

add_filter('post_updated_messages', array (EventsPostTypeService::class, 'addCustomPostUpdateMessages'), 10, 1);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.