The following code creates a custom post selection field for the WP Form Master plugin, allowing users to select a post from a drop-down list in a form. This field also checks whether a valid selection has been made (if required), saves the ID or title of the selected post, and allows it to be added to forms using a shortcode.
Code
<?php
if (!defined('ABSPATH'))
exit;
class WP_FormMaster_AddCustomField_PostSelect {
private $fieldname = "select-post";
private $isRequired = true;
public function __construct() {
add_filter("allowed_block_types_all", array($this, "setBlocks"), 11, 2);
add_shortcode("wpformmaster-form-post-select", [$this, "postSelectCallback"]);
add_filter("wpfmaster_form_extractfields", array($this, "extractFields"), 10, 4);
add_filter("wpformmaster_field_value", array($this, "getFieldValue"), 10, 7);
add_filter("wpfmaster_form_validate_field", array($this, "addRequiredError"), 10, 8);
}
public function addRequiredError($error, $formID, $key, $type, $field, $errors, $posts, $files) {
if (!$error) {
if ($key && $key === $this->fieldname) {
if ($this->isRequired) {
if (isset($posts[$key])) {
$post = get_post($posts[$key]);
if (!$post || $post->post_type != "post") {
$error = __("Please select an item", "my-domain");
}
}
}
}
}
return $error;
}
public function getFieldValue($value, $key, $type, $attrs, $posts, $files, $getInterpretValue) {
if ($key && $key === $this->fieldname) {
if ($getInterpretValue) {
if (isset($posts[$key]) && $posts[$key]) {
$post = get_post($posts[$key]);
if ($post) {
return sanitize_text_field($post->post_title);
}
}
} else {
if (isset($posts[$key]) && $posts[$key]) {
return intval($posts[$key]);
}
}
}
return $value;
}
public function extractFields($fields, $formID, $posts, $files) {
return array_merge($fields, [
[
"attrs" => [
"type" => "custom-select",
"name" => $this->fieldname
]
]
]);
}
public function postSelectCallback($atts) {
ob_start();
extract(
shortcode_atts(
array(
'title' => __("Article", "my-domain"),
),
$atts
)
);
<div class="formmaster-field" datatype="select" dataname="= $this->fieldname; ">
<div class="formmaster-select">
<select name="= $this->fieldname; ">
<option value="">= $title . ($this->isRequired ? "*" : ""); </option>
$posts = get_posts([
'post_type' => array("post"),
'post_status' => 'publish',
'suppress_filters' => false,
'posts_per_page' => -1,
"orderby" => array(
"title" => "ASC"
)
]);
foreach ($posts as $post) {
<option value="= $post->ID; ">= $post->post_title; </option>
}
</select>
</div>
</div>
return ob_get_clean();
}
public function setBlocks($allowed_blocks, $editor_context) {
if ($editor_context->post && $editor_context->post->post_type === "fmaster_form") {
return array_merge($allowed_blocks, [
'core/shortcode'
]);
}
return $allowed_blocks;
}
}
new WP_FormMaster_AddCustomField_PostSelect();
Explanations
Overall class structure
The WP_FormMaster_AddCustomField_PostSelect
class defines and registers a new custom field that displays a drop-down list of posts. This field uses several WordPress filters and shortcuts to integrate with the form, control display, and manage validation.
Class variables
$fieldname
: Stores the field name, here“select-post”
.$isRequired
: Indicates whether the field is required, here set totrue
.
Class constructor
The class constructor adds several filters and a shortcode to integrate the custom field into the form:
allowed_block_types_all
: Used to define which blocks are allowed in the WordPress form.wpformmaster-form-post-select
: Creates a shortcode to display the drop-down list of posts in the form.wpfmaster_form_extractfields
: Adds custom field attributes to the form.wpformmaster_field_value
: Extracts and interprets the value selected in the field for data recording.wpfmaster_form_validate_field
: Manages field validation to ensure that a post has been selected if the field is required.
Class methods
1. addRequiredError
This method is used to add an error message if the user does not select a post in the required field:
- Parameters: It receives several parameters such as
$formID
,$key
(field name),$type
,$field
,$errors
,$posts
, and$files
. - How it works:
- First, it checks whether the field is mandatory.
- Then it checks whether a valid post is selected (existing and of type post).
- If the field is empty or contains an invalid selection, it returns an error message:
“Please select an item”
.
2. getFieldValue
This method determines the value of the field to be saved in the form:
- Parameters: In addition to
$value
,$key
,$type
,$attrs
,$posts
,$files
, it also takes$getInterpretValue
to indicate whether the value should be interpreted. - How it works:
- If
$getInterpretValue
istrue
, it returns the title of the selected post. - Otherwise, it simply returns the post ID (as an integer).
- If the field is empty, it returns the default value of
$value
.
- If
3. extractFields
This method adds this field to the table of fields extracted by WP Form Master :
- How it works:
- It adds a new field with a
custom-select
attribute and the name defined in$fieldname
. - This field will then be available for the form, with the appropriate name to be identified when sending.
- It adds a new field with a
4. postSelectCallback
This method defines the HTML display of the selection field in the form:
- Parameters: It takes
$atts
to accept custom attributes passed to the shortcode. - How it works:
- Uses
get_posts
to retrieve all published posts. - Creates an HTML drop-down list where each option represents a post, displaying its title and storing its ID as a value.
- If
$isRequired
istrue
, the field title will be marked with an asterisk to indicate that it is mandatory.
- Uses
5. setBlocks
This method authorizes certain blocks for the WordPress block editor (Gutenberg) when the form is modified:
- How it works:
- If the editor is in the context of a WP Form Master form (here identified by the post type
fmaster_form
), it authorizes thecore/shortcode
block. - This allows you to use the shortcode to add this specific field in the block editor.
- If the editor is in the context of a WP Form Master form (here identified by the post type
Class instantiation
The line new WP_FormMaster_AddCustomField_PostSelect();
creates a new instance of the class and activates the custom field when the code is executed.
Back-office
