diff --git a/includes/sp-event-admin-week-filter.php b/includes/sp-event-admin-week-filter.php index 77cc433..b29ff3c 100644 --- a/includes/sp-event-admin-week-filter.php +++ b/includes/sp-event-admin-week-filter.php @@ -18,7 +18,7 @@ if ( ! defined( 'ABSPATH' ) ) { function tony_sportspress_event_filter_defaults() { return array( 'month' => true, - 'week' => true, + 'week' => false, 'team' => true, 'venue' => true, 'league' => true, @@ -37,6 +37,22 @@ function tony_sportspress_event_filter_meta_key( $key ) { return 'tony_sp_event_filter_' . $key; } +/** + * Normalize event filter visibility rules. + * + * Month/Year and Week are mutually exclusive. + * + * @param array $filters Filter states keyed by filter name. + * @return array + */ +function tony_sportspress_normalize_event_filter_states( $filters ) { + if ( ! empty( $filters['month'] ) && ! empty( $filters['week'] ) ) { + $filters['week'] = false; + } + + return $filters; +} + /** * Check whether a filter is enabled for the current user. * @@ -44,7 +60,7 @@ function tony_sportspress_event_filter_meta_key( $key ) { * @return bool */ function tony_sportspress_event_filter_enabled( $key ) { - $defaults = tony_sportspress_event_filter_defaults(); + $defaults = tony_sportspress_normalize_event_filter_states( tony_sportspress_event_filter_defaults() ); if ( ! array_key_exists( $key, $defaults ) ) { return true; } @@ -59,7 +75,15 @@ function tony_sportspress_event_filter_enabled( $key ) { return (bool) $defaults[ $key ]; } - return '1' === (string) $stored; + $states = array(); + foreach ( $defaults as $filter_key => $enabled ) { + $current = get_user_meta( $user_id, tony_sportspress_event_filter_meta_key( $filter_key ), true ); + $states[ $filter_key ] = '' === $current ? (bool) $enabled : '1' === (string) $current; + } + + $states = tony_sportspress_normalize_event_filter_states( $states ); + + return ! empty( $states[ $key ] ); } /** @@ -72,13 +96,21 @@ function tony_sportspress_save_event_filter_screen_options_ajax() { check_ajax_referer( 'tony_sp_event_filters', 'nonce' ); - $defaults = tony_sportspress_event_filter_defaults(); + $defaults = tony_sportspress_normalize_event_filter_states( tony_sportspress_event_filter_defaults() ); $filters = isset( $_POST['filters'] ) && is_array( $_POST['filters'] ) ? $_POST['filters'] : array(); $user_id = get_current_user_id(); + $states = array(); + foreach ( $defaults as $key => $_enabled ) { $value = isset( $filters[ $key ] ) ? sanitize_text_field( wp_unslash( $filters[ $key ] ) ) : '0'; - update_user_meta( $user_id, tony_sportspress_event_filter_meta_key( $key ), '1' === $value ? '1' : '0' ); + $states[ $key ] = '1' === $value; + } + + $states = tony_sportspress_normalize_event_filter_states( $states ); + + foreach ( $states as $key => $enabled ) { + update_user_meta( $user_id, tony_sportspress_event_filter_meta_key( $key ), $enabled ? '1' : '0' ); } wp_send_json_success(); @@ -149,6 +181,66 @@ function tony_sportspress_parse_admin_week_filter() { ); } +/** + * Get available ISO week options from event post dates. + * + * @return array + */ +function tony_sportspress_get_admin_week_filter_options() { + global $wpdb; + + $results = $wpdb->get_results( + $wpdb->prepare( + "SELECT DISTINCT DATE_FORMAT(post_date, '%%x-W%%v') AS iso_week + FROM {$wpdb->posts} + WHERE post_type = %s + AND post_status NOT IN ('auto-draft', 'trash') + AND post_date IS NOT NULL + AND post_date <> '0000-00-00 00:00:00' + ORDER BY iso_week DESC", + 'sp_event' + ), + ARRAY_A + ); + + if ( ! is_array( $results ) || empty( $results ) ) { + return array(); + } + + $options = array(); + $timezone = wp_timezone(); + + foreach ( $results as $result ) { + if ( empty( $result['iso_week'] ) || ! preg_match( '/^(\d{4})-W(0[1-9]|[1-4][0-9]|5[0-3])$/', $result['iso_week'], $matches ) ) { + continue; + } + + $year = (int) $matches[1]; + $week = (int) $matches[2]; + $monday = ( new DateTimeImmutable( 'now', $timezone ) )->setISODate( $year, $week, 1 )->setTime( 0, 0, 0 ); + $sunday = $monday->modify( '+6 days' ); + $start_label = wp_date( 'M j', $monday->getTimestamp(), $timezone ); + $end_label = wp_date( + $monday->format( 'n' ) === $sunday->format( 'n' ) ? 'j' : 'M j', + $sunday->getTimestamp(), + $timezone + ); + + $options[] = array( + 'value' => $result['iso_week'], + /* translators: 1: ISO week code, 2: Monday date, 3: Sunday date. */ + 'label' => sprintf( + __( '%1$s (%2$s to %3$s)', 'tonys-sportspress-enhancements' ), + $result['iso_week'], + $start_label, + $end_label + ), + ); + } + + return $options; +} + /** * Render week filter control in event admin list. * @@ -166,31 +258,22 @@ function tony_sportspress_render_admin_week_filter( $post_type ) { if ( ! empty( $_GET['sp_week_filter'] ) ) { $value = sanitize_text_field( wp_unslash( $_GET['sp_week_filter'] ) ); } - - $summary_text = __( 'Select a week', 'tonys-sportspress-enhancements' ); - $parsed = tony_sportspress_parse_admin_week_filter(); - if ( is_array( $parsed ) ) { - $timezone = wp_timezone(); - $monday = ( new DateTimeImmutable( 'now', $timezone ) )->setISODate( $parsed['year'], $parsed['week'], 1 )->setTime( 0, 0, 0 ); - $sunday = $monday->modify( '+6 days' )->setTime( 23, 59, 59 ); - /* translators: 1: Monday label/date, 2: Sunday label/date. */ - $summary_text = sprintf( - __( '%1$s to %2$s', 'tonys-sportspress-enhancements' ), - wp_date( 'D M j, Y', $monday->getTimestamp(), $timezone ), - wp_date( 'D M j, Y', $sunday->getTimestamp(), $timezone ) - ); - } + $options = tony_sportspress_get_admin_week_filter_options(); ?> - - + > + + + + + - .post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) #sp_week_filter, - .post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) #sp-week-filter-summary { display: none !important; } + .post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) #sp_week_filter { display: none !important; } @media (max-width: 1200px) { .post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) { @@ -258,14 +340,6 @@ function tony_sportspress_admin_week_filter_styles() { .post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) .sp-week-filter-field { min-width: 145px; } - .post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) .sp-week-filter-summary { - display: block; - width: 100%; - margin-top: 2px; - color: #50575e; - font-size: 12px; - line-height: 1.4; - } } ; } } - - const input = document.getElementById('sp_week_filter'); - const summary = document.getElementById('sp-week-filter-summary'); - if (!input || !summary) { - return; - } - - function updateSummary() { - const raw = (input.value || '').trim(); - const match = raw.match(/^(\d{4})-W(\d{2})$/); - if (!match) { - summary.textContent = 'Select a week'; - return; - } - - const year = parseInt(match[1], 10); - const week = parseInt(match[2], 10); - - const jan4 = new Date(Date.UTC(year, 0, 4)); - const jan4Day = jan4.getUTCDay() || 7; - const mondayWeek1 = new Date(jan4); - mondayWeek1.setUTCDate(jan4.getUTCDate() - jan4Day + 1); - - const monday = new Date(mondayWeek1); - monday.setUTCDate(mondayWeek1.getUTCDate() + (week - 1) * 7); - const sunday = new Date(monday); - sunday.setUTCDate(monday.getUTCDate() + 6); - - const fmt = new Intl.DateTimeFormat(undefined, { - weekday: 'short', - month: 'short', - day: 'numeric', - year: 'numeric', - timeZone: 'UTC' - }); - - summary.textContent = fmt.format(monday) + ' to ' + fmt.format(sunday); - } - - input.addEventListener('change', updateSummary); - updateSummary(); })();