phrase with %s, last: weekday => phrase, ordinals: n => text } */ function bcal_weekday_phrases() { return array( 'nth' => array( /* translators: %s: ordinal such as "3rd" */ 1 => __( 'on the %s Monday', 'bearius-calendar' ), /* translators: %s: ordinal such as "3rd" */ 2 => __( 'on the %s Tuesday', 'bearius-calendar' ), /* translators: %s: ordinal such as "3rd" */ 3 => __( 'on the %s Wednesday', 'bearius-calendar' ), /* translators: %s: ordinal such as "3rd" */ 4 => __( 'on the %s Thursday', 'bearius-calendar' ), /* translators: %s: ordinal such as "3rd" */ 5 => __( 'on the %s Friday', 'bearius-calendar' ), /* translators: %s: ordinal such as "3rd" */ 6 => __( 'on the %s Saturday', 'bearius-calendar' ), /* translators: %s: ordinal such as "3rd" */ 7 => __( 'on the %s Sunday', 'bearius-calendar' ), ), 'last' => array( 1 => __( 'on the last Monday', 'bearius-calendar' ), 2 => __( 'on the last Tuesday', 'bearius-calendar' ), 3 => __( 'on the last Wednesday', 'bearius-calendar' ), 4 => __( 'on the last Thursday', 'bearius-calendar' ), 5 => __( 'on the last Friday', 'bearius-calendar' ), 6 => __( 'on the last Saturday', 'bearius-calendar' ), 7 => __( 'on the last Sunday', 'bearius-calendar' ), ), 'ordinals' => array( 1 => _x( '1st', 'ordinal of a weekday in a month', 'bearius-calendar' ), 2 => _x( '2nd', 'ordinal of a weekday in a month', 'bearius-calendar' ), 3 => _x( '3rd', 'ordinal of a weekday in a month', 'bearius-calendar' ), 4 => _x( '4th', 'ordinal of a weekday in a month', 'bearius-calendar' ), ), ); } /** * Labels of the monthly repeat options for a start date. * * @param string $start Local start. * @return array */ function bcal_monthly_labels( $start ) { $ts = $start ? bcal_ts( $start ) : time(); $day = (int) wp_date( 'j', $ts ); $weekday = (int) wp_date( 'N', $ts ); $nth = (int) ceil( $day / 7 ); $phrases = bcal_weekday_phrases(); return array( /* translators: %d: day of the month */ 'day' => sprintf( __( 'Day %d of the month', 'bearius-calendar' ), $day ), 'nth' => bcal_ucfirst( sprintf( $phrases['nth'][ $weekday ], $phrases['ordinals'][ min( 4, $nth ) ] ) ), 'last' => bcal_ucfirst( $phrases['last'][ $weekday ] ), 'nth_ok' => $nth <= 4, 'last_ok' => $day + 7 > (int) wp_date( 't', $ts ), ); } /** * Section header inside the box. * * @param string $icon Icon. * @param string $title Title. * @param string $note Optional note on the right. */ function bcal_ed_head( $icon, $title, $note = '' ) { echo wp_kses( '
' . bcal_admin_icon( $icon ) . '

' . esc_html( $title ) . '

', bcal_kses_html() ); if ( $note ) { echo '' . esc_html( $note ) . ''; } echo '
'; } /** * Meta box markup. * * @param WP_Post $post Post. */ function bcal_render_meta_box( $post ) { $e = bcal_get_event( $post->ID, true ); $state = bcal_rrule_editor_state( $e['rrule'], $e['start'] ); $custom = null === $state; if ( $custom ) { $state = array( 'freq' => 'custom', 'interval' => 1, 'byday' => array(), 'monthly' => 'day', 'until' => '', 'count' => 0, ); } $split = function ( $value ) { return array( $value ? substr( $value, 0, 10 ) : '', $value ? substr( $value, 11, 5 ) : '' ); }; list( $start_date, $start_time ) = $split( $e['start'] ); list( $end_date, $end_time ) = $split( $e['end'] ); $freq = $state['freq']; $interval = (int) $state['interval']; $byday = $state['byday']; $monthly = $state['monthly']; $until = $state['until']; $count = (int) $state['count']; $ends = $until ? 'until' : ( $count ? 'count' : 'never' ); $mlabels = bcal_monthly_labels( $e['start'] ); $duration = bcal_default_duration(); $auto_end = $duration > 0 && '' === $e['end'] && ! $e['all_day']; $currency = (string) get_post_meta( $post->ID, '_bcal_currency', true ); $tile_ts = $e['start'] ? bcal_ts( $e['start'] ) : time(); $repeating = '' !== $freq && ! $custom; wp_nonce_field( 'bcal_save_event', 'bcal_nonce' ); ?>
>
>
__( 'Does not repeat', 'bearius-calendar' ), 'daily' => __( 'Daily', 'bearius-calendar' ), 'weekly' => __( 'Weekly', 'bearius-calendar' ), 'monthly' => __( 'Monthly', 'bearius-calendar' ), 'yearly' => __( 'Yearly', 'bearius-calendar' ), ); if ( $custom ) { $freqs['custom'] = __( 'Custom rule', 'bearius-calendar' ); } foreach ( $freqs as $value => $label ) { printf( '', esc_attr( $value ), checked( $freq, $value, false ), esc_html( $label ) ); } ?>
>

>
>
>
modify( '+' . ( $i - 1 ) . ' days' )->getTimestamp(); printf( '', (int) $i, checked( in_array( $i, $byday, true ), true, false ), esc_html( wp_date( 'D', $day_ts ) ), esc_attr( wp_date( 'l', $day_ts ) ) ); } ?>

    ID, 'bcal_venue', array( 'label' => __( 'Venue', 'bearius-calendar' ), 'placeholder' => __( 'Search venues or add a new one', 'bearius-calendar' ), 'create' => 'modal', 'template' => 'bcal-tpl-venue', ) ); ?>
    ID, 'bcal_city', array( 'label' => __( 'City', 'bearius-calendar' ), 'placeholder' => __( 'Search cities', 'bearius-calendar' ), 'create' => 'inline', ) ); bcal_render_picker( $post->ID, 'bcal_organizer', array( 'label' => __( 'Organizer', 'bearius-calendar' ), 'placeholder' => __( 'Search organizers', 'bearius-calendar' ), 'create' => 'modal', 'template' => 'bcal-tpl-organizer', ) ); ?>
    >
    $label ) : ?>
    >
    'bcal_city', 'hide_empty' => false, 'number' => 500, 'orderby' => 'name', 'fields' => 'names', ) ); $cities = is_wp_error( $cities ) ? array() : $cities; ?> modify( '+1 day' )->format( 'Y-m-d H:i:s' ) : ''; } } if ( $end && $start && $end < $start ) { $end = ''; } $byday = array(); if ( isset( $in['byday'] ) && is_array( $in['byday'] ) ) { $byday = array_map( 'intval', $in['byday'] ); } $ends = $get( 'ends' ); $freq = $get( 'freq' ); $raw_rule = function ( $key ) use ( $get ) { $rule = strtoupper( preg_replace( '/[^A-Za-z0-9=;,:+\-]/', '', $get( $key ) ) ); return ( '' !== $rule && bcal_parse_rrule( $rule ) ) ? $rule : ''; }; if ( 'custom' === $freq ) { // A rule from another calendar, kept exactly as it was. $rrule = $raw_rule( 'rrule_custom' ); $exrule = $rrule ? $raw_rule( 'exrule_custom' ) : ''; } else { $monthly_byday = ''; if ( 'monthly' === $freq && $start && in_array( $get( 'monthly' ), array( 'nth', 'last' ), true ) ) { $ts = bcal_ts( $start ); $codes = bcal_weekday_codes(); $weekday = $codes[ (int) wp_date( 'N', $ts ) ]; $monthly_byday = 'nth' === $get( 'monthly' ) ? min( 4, (int) ceil( (int) wp_date( 'j', $ts ) / 7 ) ) . $weekday : '-1' . $weekday; } $rrule = bcal_build_rrule( $freq, (int) $get( 'interval' ), $byday, ( 'until' === $ends && $date_ok( $get( 'until' ) ) ) ? $get( 'until' ) : '', 'count' === $ends ? (int) $get( 'count' ) : 0, $monthly_byday ); $exrule = $rrule ? $raw_rule( 'exrule_keep' ) : ''; } $rdates = array(); if ( $start && isset( $in['rdates'] ) && is_scalar( $in['rdates'] ) ) { $rdates = bcal_normalize_rdates( sanitize_text_field( (string) $in['rdates'] ), substr( $start, 11 ) ); $rdates = array_values( array_diff( $rdates, array( $start ) ) ); } $exdates = array(); if ( isset( $in['exdates'] ) && is_scalar( $in['exdates'] ) ) { foreach ( preg_split( '/[\s,]+/', (string) $in['exdates'] ) as $date ) { if ( $date_ok( $date ) ) { $exdates[] = $date; } } } sort( $exdates ); $status = sanitize_key( $get( 'status' ) ); if ( ! array_key_exists( $status, bcal_status_labels() ) ) { $status = 'scheduled'; } $values = array( 'start' => $start, 'end' => $end, 'all_day' => $all_day ? 1 : '', 'rrule' => $rrule, 'exrule' => $exrule, 'rdates' => implode( ',', $rdates ), 'exdates' => ( $rrule || $rdates ) ? implode( ',', array_unique( $exdates ) ) : '', 'ticket_url' => $url( 'ticket_url' ), 'ticket_url_2' => $url( 'ticket_url_2' ), 'ticket_label_2' => $get( 'ticket_label_2' ), 'price' => $get( 'price' ), 'currency' => bcal_sanitize_currency( $get( 'currency' ) ), 'status' => $status, 'online' => '1' === $get( 'online' ) ? 1 : '', 'online_url' => $url( 'online_url' ), 'featured' => '1' === $get( 'featured' ) ? 1 : '', 'source_id' => $get( 'source_id' ), ); foreach ( $values as $key => $value ) { if ( '' === $value || null === $value ) { delete_post_meta( $post_id, '_bcal_' . $key ); } else { update_post_meta( $post_id, '_bcal_' . $key, $value ); } } bcal_save_picker_terms( $post_id, $in ); } add_action( 'save_post_' . BCAL_PT, 'bcal_save_meta_box', 10 );