Add CF7 tag generator buttons for admin form editor (v0.7.1)
All checks were successful
Create Release Package / build-release (push) Successful in 59s

- Register tag generators via wpcf7_admin_init hook
- Add BnB Building select tag generator with first_as_label option
- Add BnB Room select tag generator with building_field and include_price options
- Add BnB Check-in date tag generator with min/max advance options
- Add BnB Check-out date tag generator with checkin_field and min/max nights options
- Add BnB Guests count tag generator with room_field and min/max/default options
- All generators support id and class attribute configuration
- Remove bug from Known Bugs section in CLAUDE.md

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-03 17:00:26 +01:00
parent f61dca5f45
commit a784d92cc9
4 changed files with 583 additions and 3 deletions

View File

@@ -46,6 +46,9 @@ final class CF7 {
// Register custom form tags.
add_action( 'wpcf7_init', array( self::class, 'register_form_tags' ) );
// Register tag generators for admin.
add_action( 'wpcf7_admin_init', array( self::class, 'register_tag_generators' ), 60 );
// Register validation filters.
add_filter( 'wpcf7_validate_bnb_room_select', array( self::class, 'validate_room_select' ), 10, 2 );
add_filter( 'wpcf7_validate_bnb_room_select*', array( self::class, 'validate_room_select' ), 10, 2 );
@@ -119,6 +122,570 @@ final class CF7 {
);
}
/**
* Register tag generators for CF7 admin.
*
* @return void
*/
public static function register_tag_generators(): void {
if ( ! class_exists( 'WPCF7_TagGenerator' ) ) {
return;
}
$tag_generator = \WPCF7_TagGenerator::get_instance();
// Building select tag generator.
$tag_generator->add(
'bnb_building_select',
__( 'BnB building', 'wp-bnb' ),
array( self::class, 'tag_generator_building_select' ),
array( 'version' => '2' )
);
// Room select tag generator.
$tag_generator->add(
'bnb_room_select',
__( 'BnB room', 'wp-bnb' ),
array( self::class, 'tag_generator_room_select' ),
array( 'version' => '2' )
);
// Check-in date tag generator.
$tag_generator->add(
'bnb_date_checkin',
__( 'BnB check-in', 'wp-bnb' ),
array( self::class, 'tag_generator_date_checkin' ),
array( 'version' => '2' )
);
// Check-out date tag generator.
$tag_generator->add(
'bnb_date_checkout',
__( 'BnB check-out', 'wp-bnb' ),
array( self::class, 'tag_generator_date_checkout' ),
array( 'version' => '2' )
);
// Guests count tag generator.
$tag_generator->add(
'bnb_guests',
__( 'BnB guests', 'wp-bnb' ),
array( self::class, 'tag_generator_guests' ),
array( 'version' => '2' )
);
}
/**
* Tag generator callback for building select.
*
* @param \WPCF7_ContactForm $contact_form Contact form object.
* @param array $options Tag generator options.
* @return void
*/
public static function tag_generator_building_select( $contact_form, $options = array() ): void {
$field_id = $options['content'] ?? 'wpcf7-tg-pane-bnb_building_select';
$field_type = 'bnb_building_select';
?>
<header class="description-box">
<h3><?php esc_html_e( 'BnB Building Select', 'wp-bnb' ); ?></h3>
<p><?php esc_html_e( 'Generates a dropdown to select a building. Use this to filter rooms by building.', 'wp-bnb' ); ?></p>
</header>
<div class="control-box">
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-required-legend">
<?php esc_html_e( 'Field type', 'wp-bnb' ); ?>
</legend>
<label>
<input type="checkbox" name="required" aria-describedby="<?php echo esc_attr( $field_id ); ?>-required-legend" />
<?php esc_html_e( 'Required field', 'wp-bnb' ); ?>
</label>
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-name-legend">
<?php esc_html_e( 'Name', 'wp-bnb' ); ?>
</legend>
<input type="text" name="name" class="tg-name oneline" id="<?php echo esc_attr( $field_id ); ?>-name"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-name-legend"
value="building" pattern="[A-Za-z][A-Za-z0-9_\-]*" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-first-as-label-legend">
<?php esc_html_e( 'First option label', 'wp-bnb' ); ?>
</legend>
<input type="text" name="first_as_label" class="option oneline"
id="<?php echo esc_attr( $field_id ); ?>-first-as-label"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-first-as-label-legend"
placeholder="<?php esc_attr_e( '-- Select Building --', 'wp-bnb' ); ?>" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-id-legend">
<?php esc_html_e( 'Id attribute', 'wp-bnb' ); ?>
</legend>
<input type="text" name="id" class="idvalue oneline option"
id="<?php echo esc_attr( $field_id ); ?>-id"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-id-legend" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-class-legend">
<?php esc_html_e( 'Class attribute', 'wp-bnb' ); ?>
</legend>
<input type="text" name="class" class="classvalue oneline option"
id="<?php echo esc_attr( $field_id ); ?>-class"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-class-legend" />
</fieldset>
</div>
<footer class="insert-box">
<div class="flex-container">
<input type="text" name="<?php echo esc_attr( $field_type ); ?>" class="tag code" readonly onfocus="this.select()" />
<button type="button" class="button button-primary tag-generator-insert-button">
<?php esc_html_e( 'Insert Tag', 'wp-bnb' ); ?>
</button>
</div>
<p class="mail-tag-tip">
<?php
printf(
/* translators: %s: mail tag */
esc_html__( 'Use this tag in the Mail tab: %s', 'wp-bnb' ),
'<strong><span class="mail-tag"></span></strong>'
);
?>
</p>
</footer>
<?php
}
/**
* Tag generator callback for room select.
*
* @param \WPCF7_ContactForm $contact_form Contact form object.
* @param array $options Tag generator options.
* @return void
*/
public static function tag_generator_room_select( $contact_form, $options = array() ): void {
$field_id = $options['content'] ?? 'wpcf7-tg-pane-bnb_room_select';
$field_type = 'bnb_room_select';
?>
<header class="description-box">
<h3><?php esc_html_e( 'BnB Room Select', 'wp-bnb' ); ?></h3>
<p><?php esc_html_e( 'Generates a dropdown to select a room. Rooms are grouped by building and include capacity information.', 'wp-bnb' ); ?></p>
</header>
<div class="control-box">
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-required-legend">
<?php esc_html_e( 'Field type', 'wp-bnb' ); ?>
</legend>
<label>
<input type="checkbox" name="required" aria-describedby="<?php echo esc_attr( $field_id ); ?>-required-legend" checked />
<?php esc_html_e( 'Required field', 'wp-bnb' ); ?>
</label>
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-name-legend">
<?php esc_html_e( 'Name', 'wp-bnb' ); ?>
</legend>
<input type="text" name="name" class="tg-name oneline" id="<?php echo esc_attr( $field_id ); ?>-name"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-name-legend"
value="room" pattern="[A-Za-z][A-Za-z0-9_\-]*" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-building-field-legend">
<?php esc_html_e( 'Building field name', 'wp-bnb' ); ?>
</legend>
<input type="text" name="building_field" class="option oneline"
id="<?php echo esc_attr( $field_id ); ?>-building-field"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-building-field-legend"
placeholder="building" />
<p class="description">
<?php esc_html_e( 'Enter the name of a building select field to filter rooms by selected building.', 'wp-bnb' ); ?>
</p>
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-include-price-legend">
<?php esc_html_e( 'Display options', 'wp-bnb' ); ?>
</legend>
<label>
<input type="checkbox" name="include_price" class="option" value="true"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-include-price-legend" />
<?php esc_html_e( 'Include price in room options', 'wp-bnb' ); ?>
</label>
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-id-legend">
<?php esc_html_e( 'Id attribute', 'wp-bnb' ); ?>
</legend>
<input type="text" name="id" class="idvalue oneline option"
id="<?php echo esc_attr( $field_id ); ?>-id"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-id-legend" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-class-legend">
<?php esc_html_e( 'Class attribute', 'wp-bnb' ); ?>
</legend>
<input type="text" name="class" class="classvalue oneline option"
id="<?php echo esc_attr( $field_id ); ?>-class"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-class-legend" />
</fieldset>
</div>
<footer class="insert-box">
<div class="flex-container">
<input type="text" name="<?php echo esc_attr( $field_type ); ?>" class="tag code" readonly onfocus="this.select()" />
<button type="button" class="button button-primary tag-generator-insert-button">
<?php esc_html_e( 'Insert Tag', 'wp-bnb' ); ?>
</button>
</div>
<p class="mail-tag-tip">
<?php
printf(
/* translators: %s: mail tag */
esc_html__( 'Use this tag in the Mail tab: %s', 'wp-bnb' ),
'<strong><span class="mail-tag"></span></strong>'
);
?>
</p>
</footer>
<?php
}
/**
* Tag generator callback for check-in date.
*
* @param \WPCF7_ContactForm $contact_form Contact form object.
* @param array $options Tag generator options.
* @return void
*/
public static function tag_generator_date_checkin( $contact_form, $options = array() ): void {
$field_id = $options['content'] ?? 'wpcf7-tg-pane-bnb_date_checkin';
$field_type = 'bnb_date_checkin';
?>
<header class="description-box">
<h3><?php esc_html_e( 'BnB Check-in Date', 'wp-bnb' ); ?></h3>
<p><?php esc_html_e( 'Generates a date picker for check-in date selection with automatic validation.', 'wp-bnb' ); ?></p>
</header>
<div class="control-box">
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-required-legend">
<?php esc_html_e( 'Field type', 'wp-bnb' ); ?>
</legend>
<label>
<input type="checkbox" name="required" aria-describedby="<?php echo esc_attr( $field_id ); ?>-required-legend" checked />
<?php esc_html_e( 'Required field', 'wp-bnb' ); ?>
</label>
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-name-legend">
<?php esc_html_e( 'Name', 'wp-bnb' ); ?>
</legend>
<input type="text" name="name" class="tg-name oneline" id="<?php echo esc_attr( $field_id ); ?>-name"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-name-legend"
value="check_in" pattern="[A-Za-z][A-Za-z0-9_\-]*" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-min-advance-legend">
<?php esc_html_e( 'Minimum advance booking (days)', 'wp-bnb' ); ?>
</legend>
<input type="number" name="min_advance" class="option oneline" min="0" max="365"
id="<?php echo esc_attr( $field_id ); ?>-min-advance"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-min-advance-legend"
placeholder="0" />
<p class="description">
<?php esc_html_e( 'Minimum days in advance required for booking (0 = today).', 'wp-bnb' ); ?>
</p>
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-max-advance-legend">
<?php esc_html_e( 'Maximum advance booking (days)', 'wp-bnb' ); ?>
</legend>
<input type="number" name="max_advance" class="option oneline" min="1" max="730"
id="<?php echo esc_attr( $field_id ); ?>-max-advance"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-max-advance-legend"
placeholder="365" />
<p class="description">
<?php esc_html_e( 'Maximum days in advance allowed for booking.', 'wp-bnb' ); ?>
</p>
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-id-legend">
<?php esc_html_e( 'Id attribute', 'wp-bnb' ); ?>
</legend>
<input type="text" name="id" class="idvalue oneline option"
id="<?php echo esc_attr( $field_id ); ?>-id"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-id-legend" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-class-legend">
<?php esc_html_e( 'Class attribute', 'wp-bnb' ); ?>
</legend>
<input type="text" name="class" class="classvalue oneline option"
id="<?php echo esc_attr( $field_id ); ?>-class"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-class-legend" />
</fieldset>
</div>
<footer class="insert-box">
<div class="flex-container">
<input type="text" name="<?php echo esc_attr( $field_type ); ?>" class="tag code" readonly onfocus="this.select()" />
<button type="button" class="button button-primary tag-generator-insert-button">
<?php esc_html_e( 'Insert Tag', 'wp-bnb' ); ?>
</button>
</div>
<p class="mail-tag-tip">
<?php
printf(
/* translators: %s: mail tag */
esc_html__( 'Use this tag in the Mail tab: %s', 'wp-bnb' ),
'<strong><span class="mail-tag"></span></strong>'
);
?>
</p>
</footer>
<?php
}
/**
* Tag generator callback for check-out date.
*
* @param \WPCF7_ContactForm $contact_form Contact form object.
* @param array $options Tag generator options.
* @return void
*/
public static function tag_generator_date_checkout( $contact_form, $options = array() ): void {
$field_id = $options['content'] ?? 'wpcf7-tg-pane-bnb_date_checkout';
$field_type = 'bnb_date_checkout';
?>
<header class="description-box">
<h3><?php esc_html_e( 'BnB Check-out Date', 'wp-bnb' ); ?></h3>
<p><?php esc_html_e( 'Generates a date picker for check-out date selection with automatic validation against check-in.', 'wp-bnb' ); ?></p>
</header>
<div class="control-box">
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-required-legend">
<?php esc_html_e( 'Field type', 'wp-bnb' ); ?>
</legend>
<label>
<input type="checkbox" name="required" aria-describedby="<?php echo esc_attr( $field_id ); ?>-required-legend" checked />
<?php esc_html_e( 'Required field', 'wp-bnb' ); ?>
</label>
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-name-legend">
<?php esc_html_e( 'Name', 'wp-bnb' ); ?>
</legend>
<input type="text" name="name" class="tg-name oneline" id="<?php echo esc_attr( $field_id ); ?>-name"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-name-legend"
value="check_out" pattern="[A-Za-z][A-Za-z0-9_\-]*" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-checkin-field-legend">
<?php esc_html_e( 'Check-in field name', 'wp-bnb' ); ?>
</legend>
<input type="text" name="checkin_field" class="option oneline"
id="<?php echo esc_attr( $field_id ); ?>-checkin-field"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-checkin-field-legend"
placeholder="check_in" />
<p class="description">
<?php esc_html_e( 'Enter the name of the check-in date field for date validation.', 'wp-bnb' ); ?>
</p>
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-min-nights-legend">
<?php esc_html_e( 'Minimum nights', 'wp-bnb' ); ?>
</legend>
<input type="number" name="min_nights" class="option oneline" min="1" max="365"
id="<?php echo esc_attr( $field_id ); ?>-min-nights"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-min-nights-legend"
placeholder="1" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-max-nights-legend">
<?php esc_html_e( 'Maximum nights', 'wp-bnb' ); ?>
</legend>
<input type="number" name="max_nights" class="option oneline" min="1" max="365"
id="<?php echo esc_attr( $field_id ); ?>-max-nights"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-max-nights-legend"
placeholder="365" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-id-legend">
<?php esc_html_e( 'Id attribute', 'wp-bnb' ); ?>
</legend>
<input type="text" name="id" class="idvalue oneline option"
id="<?php echo esc_attr( $field_id ); ?>-id"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-id-legend" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-class-legend">
<?php esc_html_e( 'Class attribute', 'wp-bnb' ); ?>
</legend>
<input type="text" name="class" class="classvalue oneline option"
id="<?php echo esc_attr( $field_id ); ?>-class"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-class-legend" />
</fieldset>
</div>
<footer class="insert-box">
<div class="flex-container">
<input type="text" name="<?php echo esc_attr( $field_type ); ?>" class="tag code" readonly onfocus="this.select()" />
<button type="button" class="button button-primary tag-generator-insert-button">
<?php esc_html_e( 'Insert Tag', 'wp-bnb' ); ?>
</button>
</div>
<p class="mail-tag-tip">
<?php
printf(
/* translators: %s: mail tag */
esc_html__( 'Use this tag in the Mail tab: %s', 'wp-bnb' ),
'<strong><span class="mail-tag"></span></strong>'
);
?>
</p>
</footer>
<?php
}
/**
* Tag generator callback for guests count.
*
* @param \WPCF7_ContactForm $contact_form Contact form object.
* @param array $options Tag generator options.
* @return void
*/
public static function tag_generator_guests( $contact_form, $options = array() ): void {
$field_id = $options['content'] ?? 'wpcf7-tg-pane-bnb_guests';
$field_type = 'bnb_guests';
?>
<header class="description-box">
<h3><?php esc_html_e( 'BnB Guests Count', 'wp-bnb' ); ?></h3>
<p><?php esc_html_e( 'Generates a number input for guest count with validation against room capacity.', 'wp-bnb' ); ?></p>
</header>
<div class="control-box">
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-required-legend">
<?php esc_html_e( 'Field type', 'wp-bnb' ); ?>
</legend>
<label>
<input type="checkbox" name="required" aria-describedby="<?php echo esc_attr( $field_id ); ?>-required-legend" checked />
<?php esc_html_e( 'Required field', 'wp-bnb' ); ?>
</label>
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-name-legend">
<?php esc_html_e( 'Name', 'wp-bnb' ); ?>
</legend>
<input type="text" name="name" class="tg-name oneline" id="<?php echo esc_attr( $field_id ); ?>-name"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-name-legend"
value="guests" pattern="[A-Za-z][A-Za-z0-9_\-]*" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-room-field-legend">
<?php esc_html_e( 'Room field name', 'wp-bnb' ); ?>
</legend>
<input type="text" name="room_field" class="option oneline"
id="<?php echo esc_attr( $field_id ); ?>-room-field"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-room-field-legend"
placeholder="room" />
<p class="description">
<?php esc_html_e( 'Enter the name of the room select field to validate against room capacity.', 'wp-bnb' ); ?>
</p>
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-min-legend">
<?php esc_html_e( 'Minimum guests', 'wp-bnb' ); ?>
</legend>
<input type="number" name="min" class="option oneline" min="1" max="50"
id="<?php echo esc_attr( $field_id ); ?>-min"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-min-legend"
placeholder="1" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-max-legend">
<?php esc_html_e( 'Maximum guests', 'wp-bnb' ); ?>
</legend>
<input type="number" name="max" class="option oneline" min="1" max="50"
id="<?php echo esc_attr( $field_id ); ?>-max"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-max-legend"
placeholder="10" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-default-legend">
<?php esc_html_e( 'Default value', 'wp-bnb' ); ?>
</legend>
<input type="number" name="default" class="option oneline" min="1" max="50"
id="<?php echo esc_attr( $field_id ); ?>-default"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-default-legend"
placeholder="1" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-id-legend">
<?php esc_html_e( 'Id attribute', 'wp-bnb' ); ?>
</legend>
<input type="text" name="id" class="idvalue oneline option"
id="<?php echo esc_attr( $field_id ); ?>-id"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-id-legend" />
</fieldset>
<fieldset>
<legend id="<?php echo esc_attr( $field_id ); ?>-class-legend">
<?php esc_html_e( 'Class attribute', 'wp-bnb' ); ?>
</legend>
<input type="text" name="class" class="classvalue oneline option"
id="<?php echo esc_attr( $field_id ); ?>-class"
aria-describedby="<?php echo esc_attr( $field_id ); ?>-class-legend" />
</fieldset>
</div>
<footer class="insert-box">
<div class="flex-container">
<input type="text" name="<?php echo esc_attr( $field_type ); ?>" class="tag code" readonly onfocus="this.select()" />
<button type="button" class="button button-primary tag-generator-insert-button">
<?php esc_html_e( 'Insert Tag', 'wp-bnb' ); ?>
</button>
</div>
<p class="mail-tag-tip">
<?php
printf(
/* translators: %s: mail tag */
esc_html__( 'Use this tag in the Mail tab: %s', 'wp-bnb' ),
'<strong><span class="mail-tag"></span></strong>'
);
?>
</p>
</footer>
<?php
}
/**
* Render building select tag.
*