Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 17 additions & 14 deletions modules/calendar/calendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,13 +217,30 @@ public function enqueue_admin_scripts() {
if ( 'index.php' === $pagenow && isset( $_GET['page'] ) && 'calendar' === $_GET['page'] ) {
$this->enqueue_datepicker_resources();

/**
* Powering the new React interface.
* Must be enqueued first because it registers the 'edit-flow/calendar' data store
* that calendar.js depends on for drag-and-drop functionality.
*/
$asset_file = EDIT_FLOW_ROOT . '/build/calendar-react.asset.php';
$asset = file_exists( $asset_file ) ? require $asset_file : [ 'dependencies' => [], 'version' => EDIT_FLOW_VERSION ];

wp_enqueue_script(
'edit-flow-calendar-react-js',
EDIT_FLOW_URL . 'build/calendar-react.js',
$asset['dependencies'],
$asset['version'],
true
);

$js_libraries = array(
'jquery',
'jquery-ui-core',
'jquery-ui-sortable',
'jquery-ui-draggable',
'jquery-ui-droppable',
'wp-data',
'edit-flow-calendar-react-js', // Required for the 'edit-flow/calendar' data store.
);
foreach ( $js_libraries as $js_library ) {
wp_enqueue_script( $js_library );
Expand All @@ -233,20 +250,6 @@ public function enqueue_admin_scripts() {
$ef_cal_js_params = array( 'can_add_posts' => current_user_can( $this->create_post_cap ) ? 'true' : 'false' );
wp_localize_script( 'edit-flow-calendar-js', 'ef_calendar_params', $ef_cal_js_params );

/**
* Powering the new React interface
*/
$asset_file = EDIT_FLOW_ROOT . '/build/calendar-react.asset.php';
$asset = file_exists( $asset_file ) ? require $asset_file : [ 'dependencies' => [], 'version' => EDIT_FLOW_VERSION ];

wp_enqueue_script(
'edit-flow-calendar-react-js',
EDIT_FLOW_URL . 'build/calendar-react.js',
$asset['dependencies'],
$asset['version'],
true
);

wp_add_inline_script(
'edit-flow-calendar-react-js',
'var EF_CALENDAR = ' . wp_json_encode( $this->get_calendar_frontend_config() ),
Expand Down
23 changes: 20 additions & 3 deletions modules/calendar/lib/calendar.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
const dispatch = wp.data.dispatch;

/**
* Safely dispatch an action to the edit-flow/calendar store.
* Returns a no-op object if the store isn't registered yet.
*/
function getCalendarDispatch() {
const calendarStore = dispatch( 'edit-flow/calendar' );
if ( calendarStore ) {
return calendarStore;
}
// Return no-op functions if store isn't available
return {
setCalendarIsLoading: () => {},
setPostSaved: () => {},
clearCalendarSnackbarMessage: () => {},
};
}

jQuery( document ).ready( function ( $ ) {
$( 'a.show-more' ).on( 'click', function () {
const parent = $( this ).closest( 'td.day-unit' );
Expand Down Expand Up @@ -219,7 +236,7 @@ jQuery( document ).ready( function ( $ ) {
const next_date = next_date_id.substr( 'date-'.length );
const nonce = $( document ).find( '#ef-calendar-modify' ).val();
$( '.edit-flow-message' ).remove();
dispatch( 'edit-flow/calendar' ).setCalendarIsLoading( true );
getCalendarDispatch().setCalendarIsLoading( true );
// $('li.ajax-actions .waiting').show();
// make ajax request
const params = {
Expand All @@ -234,10 +251,10 @@ jQuery( document ).ready( function ( $ ) {
clearTimeout( snackbarMessageTimeout );
}

dispatch( 'edit-flow/calendar' ).setPostSaved( response.message );
getCalendarDispatch().setPostSaved( response.message );

snackbarMessageTimeout = setTimeout( () => {
dispatch( 'edit-flow/calendar' ).clearCalendarSnackbarMessage();
getCalendarDispatch().clearCalendarSnackbarMessage();
}, 2500 );

setTimeout( edit_flow_calendar_hide_message, 10000 );
Expand Down
126 changes: 126 additions & 0 deletions tests/Integration/CalendarModuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -424,4 +424,130 @@ public function test_week_with_saturday_start() {
// Should return Friday, January 17, 2025
$this->assertEquals( '2025-01-17', $ending );
}

/**
* Test that posts scheduled at exactly the same time are both retrieved.
*
* This is a regression test for issue #770 where posts with the same
* date/time would only show one on the calendar.
*/
public function test_posts_with_same_timestamp_both_retrieved() {
global $edit_flow;

wp_set_current_user( self::$admin_user_id );

// Use a date in the current week for the test.
$test_date = date( 'Y-m-d', strtotime( '+1 day' ) );
$test_datetime = $test_date . ' 10:00:00';

// Create two posts with the exact same timestamp.
$post1_id = self::factory()->post->create(
[
'post_author' => self::$admin_user_id,
'post_status' => 'draft',
'post_title' => 'Test Post 1 - Same Time',
'post_date' => $test_datetime,
]
);

$post2_id = self::factory()->post->create(
[
'post_author' => self::$admin_user_id,
'post_status' => 'draft',
'post_title' => 'Test Post 2 - Same Time',
'post_date' => $test_datetime,
]
);

// Set the calendar start date to include our test date.
$edit_flow->calendar->start_date = $test_date;

// Get posts for the week.
$week_posts = $edit_flow->calendar->get_calendar_posts_for_week(
[
'post_status' => 'draft',
]
);

// Verify both posts are in the result.
$this->assertArrayHasKey( $test_date, $week_posts, 'The test date should have posts' );
$this->assertCount( 2, $week_posts[ $test_date ], 'Both posts with same timestamp should be returned' );

// Verify we got the correct posts.
$returned_ids = array_map(
function ( $post ) {
return $post->ID;
},
$week_posts[ $test_date ]
);

$this->assertContains( $post1_id, $returned_ids, 'Post 1 should be in the results' );
$this->assertContains( $post2_id, $returned_ids, 'Post 2 should be in the results' );
}

/**
* Test that scheduled (future) posts at exactly the same time are both retrieved.
*
* This is a regression test for issue #770 where posts with the same
* date/time would only show one on the calendar.
*/
public function test_future_posts_with_same_timestamp_both_retrieved() {
global $edit_flow;

wp_set_current_user( self::$admin_user_id );

// Use a date in the future for scheduled posts.
$test_date = date( 'Y-m-d', strtotime( '+3 days' ) );
$test_datetime = $test_date . ' 14:30:00';

// Create two scheduled posts with the exact same timestamp.
$post1_id = self::factory()->post->create(
[
'post_author' => self::$admin_user_id,
'post_status' => 'future',
'post_title' => 'Scheduled Post 1 - Same Time',
'post_date' => $test_datetime,
'post_date_gmt' => get_gmt_from_date( $test_datetime ),
]
);

$post2_id = self::factory()->post->create(
[
'post_author' => self::$admin_user_id,
'post_status' => 'future',
'post_title' => 'Scheduled Post 2 - Same Time',
'post_date' => $test_datetime,
'post_date_gmt' => get_gmt_from_date( $test_datetime ),
]
);

// Verify both posts were created with 'future' status.
$this->assertEquals( 'future', get_post_status( $post1_id ) );
$this->assertEquals( 'future', get_post_status( $post2_id ) );

// Set the calendar start date to include our test date.
$edit_flow->calendar->start_date = $test_date;

// Get posts for the week.
$week_posts = $edit_flow->calendar->get_calendar_posts_for_week(
[
'post_status' => 'future',
]
);

// Verify both posts are in the result.
$this->assertArrayHasKey( $test_date, $week_posts, 'The test date should have posts' );
$this->assertCount( 2, $week_posts[ $test_date ], 'Both scheduled posts with same timestamp should be returned' );

// Verify we got the correct posts.
$returned_ids = array_map(
function ( $post ) {
return $post->ID;
},
$week_posts[ $test_date ]
);

$this->assertContains( $post1_id, $returned_ids, 'Scheduled Post 1 should be in the results' );
$this->assertContains( $post2_id, $returned_ids, 'Scheduled Post 2 should be in the results' );
}
}
Loading