✨ feature: Add calendar layout and occurrence handling functionality
- Introduced `calendar-layout.php` to manage month grid generation, occurrence intersection checks, and segment assignments for events. - Added `occurrences.php` for normalizing, validating, and displaying event occurrences, including migration from legacy formats. - Implemented functions for parsing dates, validating occurrence ranges, and formatting occurrences for display. - Established hooks for synchronizing event occurrence data upon saving posts and validating ACF repeater fields.
This commit is contained in:
+185
-2
@@ -9,10 +9,74 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether an ACF field group created in the admin targets the event post type.
|
||||
*
|
||||
* @return bool True if an external field group is assigned to events.
|
||||
*/
|
||||
function events_has_admin_field_group() {
|
||||
if ( ! function_exists( 'acf_get_field_groups' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$groups = acf_get_field_groups( array( 'post_type' => 'event' ) );
|
||||
|
||||
foreach ( $groups as $group ) {
|
||||
if ( isset( $group['active'] ) && ! $group['active'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
isset( $group['key'], $group['local'] )
|
||||
&& 'group_61b0c5f5a3e7e' === $group['key']
|
||||
&& 'php' === $group['local']
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$targets_events = false;
|
||||
foreach ( $group['location'] ?? array() as $location_group ) {
|
||||
foreach ( $location_group as $rule ) {
|
||||
if (
|
||||
isset( $rule['param'], $rule['operator'], $rule['value'] )
|
||||
&& 'post_type' === $rule['param']
|
||||
&& '==' === $rule['operator']
|
||||
&& 'event' === $rule['value']
|
||||
) {
|
||||
$targets_events = true;
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $targets_events || ! function_exists( 'acf_get_fields' ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( (array) acf_get_fields( $group ) as $field ) {
|
||||
if (
|
||||
isset( $field['name'] )
|
||||
&& in_array( $field['name'], array( 'event_datetime', 'event_dates', 'multiple_dates', 'date' ), true )
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the ACF field group.
|
||||
*
|
||||
* Skips registration when an admin-created field group is already
|
||||
* assigned to the event post type, allowing full editorial control.
|
||||
*/
|
||||
function events_register_acf_fields() {
|
||||
if ( events_has_admin_field_group() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( function_exists( 'acf_add_local_field_group' ) ) :
|
||||
|
||||
acf_add_local_field_group(
|
||||
@@ -25,8 +89,8 @@ function events_register_acf_fields() {
|
||||
'label' => 'Event Date & Time',
|
||||
'name' => 'event_datetime',
|
||||
'type' => 'date_time_picker',
|
||||
'instructions' => '',
|
||||
'required' => 1,
|
||||
'instructions' => 'Legacy compatibility field. Use Occurrences for new events.',
|
||||
'required' => 0,
|
||||
'conditional_logic' => 0,
|
||||
'wrapper' => array(
|
||||
'width' => '',
|
||||
@@ -56,6 +120,109 @@ function events_register_acf_fields() {
|
||||
'append' => '',
|
||||
'maxlength' => '',
|
||||
),
|
||||
array(
|
||||
'key' => 'field_61b0c7f0a3e8f',
|
||||
'label' => 'Occurrences',
|
||||
'name' => 'event_dates',
|
||||
'type' => 'repeater',
|
||||
'instructions' => 'Each row is one occurrence. Add an end date for a continuous multi-day event; add more rows when the event recurs.',
|
||||
'required' => 0,
|
||||
'conditional_logic' => 0,
|
||||
'wrapper' => array(
|
||||
'width' => '',
|
||||
'class' => '',
|
||||
'id' => '',
|
||||
),
|
||||
'collapsed' => '',
|
||||
'min' => 0,
|
||||
'max' => 0,
|
||||
'layout' => 'row',
|
||||
'button_label' => 'Add Occurrence',
|
||||
'sub_fields' => array(
|
||||
array(
|
||||
'key' => 'field_61b0c7f1a3e90',
|
||||
'label' => 'Date',
|
||||
'name' => 'date',
|
||||
'type' => 'date_picker',
|
||||
'instructions' => '',
|
||||
'required' => 1,
|
||||
'conditional_logic' => 0,
|
||||
'wrapper' => array(
|
||||
'width' => '25',
|
||||
'class' => '',
|
||||
'id' => '',
|
||||
),
|
||||
'display_format' => 'F j, Y',
|
||||
'return_format' => 'Y-m-d',
|
||||
'first_day' => 1,
|
||||
),
|
||||
array(
|
||||
'key' => 'field_61b0c7f2a3e91',
|
||||
'label' => 'Start Time',
|
||||
'name' => 'start_time',
|
||||
'type' => 'time_picker',
|
||||
'instructions' => '',
|
||||
'required' => 0,
|
||||
'conditional_logic' => 0,
|
||||
'wrapper' => array(
|
||||
'width' => '20',
|
||||
'class' => '',
|
||||
'id' => '',
|
||||
),
|
||||
'display_format' => 'g:i a',
|
||||
'return_format' => 'H:i:s',
|
||||
),
|
||||
array(
|
||||
'key' => 'field_aa_events_end_date',
|
||||
'label' => 'End Date',
|
||||
'name' => 'end_date',
|
||||
'type' => 'date_picker',
|
||||
'instructions' => '',
|
||||
'required' => 0,
|
||||
'conditional_logic' => 0,
|
||||
'wrapper' => array(
|
||||
'width' => '25',
|
||||
'class' => '',
|
||||
'id' => '',
|
||||
),
|
||||
'display_format' => 'F j, Y',
|
||||
'return_format' => 'Y-m-d',
|
||||
'first_day' => 1,
|
||||
),
|
||||
array(
|
||||
'key' => 'field_aa_events_end_time',
|
||||
'label' => 'End Time',
|
||||
'name' => 'end_time',
|
||||
'type' => 'time_picker',
|
||||
'instructions' => '',
|
||||
'required' => 0,
|
||||
'conditional_logic' => 0,
|
||||
'wrapper' => array(
|
||||
'width' => '20',
|
||||
'class' => '',
|
||||
'id' => '',
|
||||
),
|
||||
'display_format' => 'g:i a',
|
||||
'return_format' => 'H:i:s',
|
||||
),
|
||||
array(
|
||||
'key' => 'field_aa_events_all_day',
|
||||
'label' => 'All Day',
|
||||
'name' => 'all_day',
|
||||
'type' => 'true_false',
|
||||
'instructions' => '',
|
||||
'required' => 0,
|
||||
'conditional_logic' => 0,
|
||||
'wrapper' => array(
|
||||
'width' => '10',
|
||||
'class' => '',
|
||||
'id' => '',
|
||||
),
|
||||
'default_value' => 0,
|
||||
'ui' => 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'key' => 'field_61b0c6cba3e83',
|
||||
'label' => 'Online/In-Person',
|
||||
@@ -126,6 +293,22 @@ function events_register_acf_fields() {
|
||||
'rows' => '',
|
||||
'new_lines' => '',
|
||||
),
|
||||
array(
|
||||
'key' => 'field_aa_events_contact_email',
|
||||
'label' => 'Contact Email',
|
||||
'name' => 'event_contact_email',
|
||||
'type' => 'email',
|
||||
'instructions' => '',
|
||||
'required' => 0,
|
||||
'conditional_logic' => 0,
|
||||
'wrapper' => array(
|
||||
'width' => '',
|
||||
'class' => '',
|
||||
'id' => '',
|
||||
),
|
||||
'default_value' => '',
|
||||
'placeholder' => '',
|
||||
),
|
||||
),
|
||||
'location' => array(
|
||||
array(
|
||||
|
||||
Reference in New Issue
Block a user