Skip to content

Commit

Permalink
Handle private and cancelled states in event output & listings
Browse files Browse the repository at this point in the history
See #544
  • Loading branch information
joedolson committed Feb 19, 2025
1 parent f55b040 commit fbc730d
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 68 deletions.
19 changes: 18 additions & 1 deletion src/includes/conditionals.php
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,22 @@ function mc_is_single_event() {
return false;
}

/**
* Determine whether event is published.
*
* @param object $event Event object.
*
* @return boolean
*/
function mc_event_published( $event ) {
$state = mc_event_states_type( $event->event_approved );
if ( 'public' === $state || is_user_logged_in() && 'private' === $state ) {
return true;
}

return false;
}

/**
* Check whether an event should be hidden (privacy)
*
Expand Down Expand Up @@ -244,7 +260,8 @@ function mc_event_is_hidden( $event ) {
* @return {bool}
*/
$can_see = apply_filters( 'mc_user_can_see_private_events', is_user_logged_in(), $event );
if ( in_array( $category, $private, true ) && ! $can_see ) {
$state = mc_event_states_type( $event->event_approved );
if ( ( in_array( $category, $private, true ) || 'private' === $state ) && ! $can_see ) {

return true;
}
Expand Down
19 changes: 12 additions & 7 deletions src/includes/date-utilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,8 @@ function mc_ordinal( $number ) {
* @return boolean true if early exit is qualified.
*/
function mc_exit_early( $event, $process_date ) {
// if event is not approved, return without processing.
if ( 1 !== (int) $event->event_approved && ! mc_is_preview() ) {
// if event is in trash, return without processing.
if ( 2 === (int) $event->event_approved && ! mc_is_preview() ) {
return true;
}

Expand Down Expand Up @@ -417,12 +417,17 @@ function mc_private_event( $event, $type = true ) {
if ( ! is_object( $event ) || ! property_exists( $event, 'category_private' ) ) {
return true;
}
if ( $type ) {
// Checking whether this should currently be hidden.
$status = ( 1 === absint( $event->category_private ) && ! is_user_logged_in() ) ? true : false;
// If this event has the private state.
if ( property_exists( $event, 'event_approved' ) && 4 === (int) $event->event_approved ) {
$status = ( is_user_logged_in() ) ? false : true;
} else {
// Checking whether this is supposed to be private.
$status = ( 1 === absint( $event->category_private ) ) ? true : false;
if ( $type ) {
// Checking whether this should currently be hidden.
$status = ( 1 === absint( $event->category_private ) && ! is_user_logged_in() ) ? true : false;
} else {
// Checking whether this is supposed to be private.
$status = ( 1 === absint( $event->category_private ) ) ? true : false;
}
}

/**
Expand Down
44 changes: 22 additions & 22 deletions src/includes/event-utilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ function mcs_check_conflicts( $begin, $time, $end, $endtime, $loc_id ) {
}

/**
* Get all statuses, labels, types. Valid types are 'hidden', 'public', and 'private'. Hidden statuses
* Get all states, labels, types. Valid types are 'hidden', 'public', and 'private'. Hidden statuses
* are not output to public APIs or shown on calendars at all. Private statuses are shown to logged-in users.
*
* @return array
*/
function mc_event_statuses() {
$statuses = array(
function mc_event_states() {
$states = array(
'0' => array(
'type' => 'hidden',
'label' => __( 'Draft', 'my-calendar' ),
Expand All @@ -150,27 +150,27 @@ function mc_event_statuses() {
/**
* Filter available event status types.
*
* @hook mc_event_statuses
* @hook mc_event_states
*
* @param {array} Array of statuses where key is the integer value of the
* status and the value is an array with type and label.
* @param {array} Array of states where key is the integer value of the
* state and the value is an array with type and label.
*
* @return {array}
*/
$statuses = apply_filters( 'mc_event_statuses', $statuses );
$states = apply_filters( 'mc_event_states', $states );

return $statuses;
return $states;
}

/**
* Get an array of statuses by type.
* Get an array of states by type.
*
* @param string $type 'public', 'private', or, 'hidden'.
*
* @return array
*/
function mc_event_status_by_type( $type ) {
$statuses = mc_event_statuses();
function mc_event_states_by_type( $type ) {
$statuses = mc_event_states();
$values = array();
foreach ( $statuses as $key => $value ) {
if ( $type === $value['type'] ) {
Expand All @@ -179,37 +179,37 @@ function mc_event_status_by_type( $type ) {
}

/**
* Filter the display type for event statuses.
* Filter the display type for event states.
*
* @hook mc_event_status_by_type
* @hook mc_event_states_by_type
*
* @param {array} $values Array of integers representing the event statuses that match the passed type.
* @param {array} $values Array of integers representing the event states that match the passed type.
* @param {string} $type Publication type requested.
*/
return apply_filters( 'mc_event_status_by_type', $values, $type );
return apply_filters( 'mc_event_states_by_type', $values, $type );
}

/**
* Get the publication type of a status.
*
* @param int $status An integer status value.
* @param int $state An integer status value.
*
* @return string 'public', 'private', or 'hidden'.
*/
function mc_event_status_type( $status ) {
$statuses = mc_event_statuses();
$return = $statuses[ $status ]['type'];
function mc_event_states_type( $state ) {
$states = mc_event_states();
$return = $states[ $state ]['type'];

/**
* Filter the display conditions of an event status. Events can either be public; private; or hidden.
* Public events are visible to all; private events are visible to logged-in users; and hidden events are not visible.
*
* @hook mc_event_status_type
* @hook mc_event_states_type
*
* @param {string} $return Type for the current status.
* @param {int} $status An integer representation of a status.
* @param {int} $states An integer representation of a status.
*
* @return {string}
*/
return apply_filters( 'mc_event_status_type', $return, $status );
return apply_filters( 'mc_event_states_type', $return, $states );
}
8 changes: 6 additions & 2 deletions src/my-calendar-core.php
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,8 @@ function mc_do_upgrades( $upgrade_path ) {
}
foreach ( $upgrade_path as $upgrade ) {
switch ( $upgrade ) {
case '3.6.0':
// TODO.
case '3.5.0':
// Need to set card display settings. TODO.
$options = get_option( 'my_calendar_options' );
Expand Down Expand Up @@ -1707,8 +1709,8 @@ function mc_update_count_cache() {
global $wpdb;
$all = $wpdb->get_var( 'SELECT count(event_id) FROM ' . my_calendar_table() . ' WHERE event_flagged = 0 AND event_status = 1' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$published = $wpdb->get_var( 'SELECT count(event_id) FROM ' . my_calendar_table() . ' WHERE event_approved = 1 AND event_flagged = 0 AND event_status = 1' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$cancelled = $wpdb->get_var( 'SELECT count(event_id) FROM ' . my_calendar_table() . ' WHERE event_approved = 1 AND event_flagged = 0 AND event_status = 3' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$private = $wpdb->get_var( 'SELECT count(event_id) FROM ' . my_calendar_table() . ' WHERE event_approved = 1 AND event_flagged = 0 AND event_status = 4' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$cancelled = $wpdb->get_var( 'SELECT count(event_id) FROM ' . my_calendar_table() . ' WHERE event_approved = 3 AND event_flagged = 0 AND event_status = 1' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$private = $wpdb->get_var( 'SELECT count(event_id) FROM ' . my_calendar_table() . ' WHERE event_approved = 4 AND event_flagged = 0 AND event_status = 1' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$draft = $wpdb->get_var( 'SELECT count(event_id) FROM ' . my_calendar_table() . ' WHERE event_approved = 0 AND event_flagged = 0 AND event_status = 1' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$trash = $wpdb->get_var( 'SELECT count(event_id) FROM ' . my_calendar_table() . ' WHERE event_approved = 2 AND event_flagged = 0 AND event_status = 1' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$archive = $wpdb->get_var( 'SELECT count(event_id) FROM ' . my_calendar_table() . ' WHERE event_approved != 2 AND event_flagged = 0 AND event_status = 0' ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
Expand All @@ -1719,6 +1721,8 @@ function mc_update_count_cache() {
'draft' => $draft,
'trash' => $trash,
'archive' => $archive,
'cancel' => $cancelled,
'private' => $private,
'spam' => $spam,
);
update_option( 'mc_count_cache', $counts );
Expand Down
10 changes: 7 additions & 3 deletions src/my-calendar-event-editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -920,8 +920,12 @@ function mc_edit_event_form( $mode = 'add', $event_id = false ) {
if ( is_object( $data ) && 1 !== (int) $data->event_approved && 'edit' === $mode ) {
if ( 0 === (int) $data->event_approved ) {
mc_show_notice( __( '<strong>Draft</strong>: Publish this event to show it on the calendar.', 'my-calendar' ), true, false, 'info' );
} else {
} elseif ( 2 === (int) $data->event_approved ) {
mc_show_notice( __( '<strong>Trash</strong>: Remove from the trash to show this event on the calendar.', 'my-calendar' ), true, false, 'info' );
} elseif ( 3 === (int) $data->event_approved ) {
mc_show_notice( __( '<strong>Cancelled</strong>: This event has been cancelled, but is still shown on the calendar.', 'my-calendar' ), true, false, 'info' );
} elseif ( 4 === (int) $data->event_approved ) {
mc_show_notice( __( '<strong>Private</strong>: This event is private, and visible only to logged-in users.', 'my-calendar' ), true, false, 'info' );
}
}

Expand Down Expand Up @@ -2474,7 +2478,7 @@ function mc_check_data( $action, $post, $i, $ignore_required = false ) {
if ( $conflicts ) {
$conflict_id = $conflicts[0]->occur_id;
$conflict_ev = mc_get_event( $conflict_id );
if ( '1' === $conflict_ev->event_approved ) {
if ( 'public' === mc_event_states_type( $conflict_ev->event_approved ) ) {
$conflict = mc_get_permalink( $conflict_ev );
// Translators: URL to event details.
$errors .= mc_show_error( sprintf( __( 'That event conflicts with a <a href="%s">previously scheduled event</a>.', 'my-calendar' ), $conflict ), false, 'conflict' );
Expand Down Expand Up @@ -3146,7 +3150,7 @@ function mc_controls( $mode, $has_data, $event, $position = 'header' ) {
}
}
// Event Status settings: draft, published, trash, (custom).
$statuses = mc_event_statuses();
$statuses = mc_event_states();
if ( 'header' === $position ) {
$status_control = '';
if ( 'edit' === $mode ) {
Expand Down
36 changes: 23 additions & 13 deletions src/my-calendar-event-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ function mc_bulk_action( $action, $events = array() ) {
$sql = 'UPDATE ' . my_calendar_table() . ' SET event_status = 1 WHERE event_id IN (' . $prepared . ')';
break;
case 'cancel':
$sql = 'UPDATE ' . my_calendar_table() . ' SET event_status = 3 WHERE event_id IN (' . $prepared . ')';
$sql = 'UPDATE ' . my_calendar_table() . ' SET event_approved = 3 WHERE event_id IN (' . $prepared . ')';
break;
case 'private':
$sql = 'UPDATE ' . my_calendar_table() . ' SET event_status = 4 WHERE event_id IN (' . $prepared . ')';
$sql = 'UPDATE ' . my_calendar_table() . ' SET event_approved = 4 WHERE event_id IN (' . $prepared . ')';
break;
case 'archive':
$sql = 'UPDATE ' . my_calendar_table() . ' SET event_status = 0 WHERE event_id IN (' . $prepared . ')';
Expand Down Expand Up @@ -569,7 +569,9 @@ function mc_get_event_list_sorting() {
* @return string
*/
function mc_get_event_status_limit() {
$status = ( isset( $_GET['limit'] ) ) ? sanitize_text_field( $_GET['limit'] ) : '';
$status = ( isset( $_GET['limit'] ) ) ? sanitize_text_field( $_GET['limit'] ) : '';
$published = implode( ',', mc_event_states_by_type( 'public' ) );

// Filter by status.
switch ( $status ) {
case 'all':
Expand All @@ -579,7 +581,13 @@ function mc_get_event_status_limit() {
$limit = 'WHERE event_approved = 0';
break;
case 'published':
$limit = 'WHERE event_approved = 1';
$limit = 'WHERE event_approved IN (' . $published . ')';
break;
case 'cancelled':
$limit = 'WHERE event_approved = 3';
break;
case 'private':
$limit = 'WHERE event_approved = 4';
break;
case 'trashed':
$limit = 'WHERE event_approved = 2';
Expand Down Expand Up @@ -728,7 +736,7 @@ function mc_list_events() {
// Get page and pagination values.
$query = mc_get_query_limit();
// Set event status limits.
$limit .= ( 'archived' !== $restrict ) ? ' AND e.event_status = 1' : ' AND e.event_status = 0';
$limit .= ( 'archived' !== $restrict ) ? ' AND e.event_status = 1 ' : ' AND e.event_status = 0';
// Toggle query type depending on whether we're limiting categories, which requires a join.
if ( 'event_category' !== $sortbyvalue ) {
$events = $wpdb->get_results( $wpdb->prepare( 'SELECT e.event_id FROM ' . my_calendar_table() . " AS e $join $limit ORDER BY $sortbyvalue " . 'LIMIT %d, %d', $query['query'], $query['items_per_page'] ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQL.NotPrepared
Expand Down Expand Up @@ -883,10 +891,11 @@ function mc_admin_events_table( $events ) {
$event = $wpdb->get_row( $wpdb->prepare( 'SELECT * FROM ' . my_calendar_table() . ' WHERE event_id = %d', $e->event_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$invalid = true;
}
$class = ( $invalid ) ? 'invalid' : '';
$pending = ( 0 === (int) $event->event_approved ) ? 'pending' : '';
$trashed = ( 2 === (int) $event->event_approved ) ? 'trashed' : '';
$author = ( 0 !== (int) $event->event_author ) ? get_userdata( $event->event_author ) : 'Public Submitter';
$class = ( $invalid ) ? 'invalid' : '';
$pending = ( 0 === (int) $event->event_approved ) ? 'pending' : '';
$trashed = ( 2 === (int) $event->event_approved ) ? 'trashed' : '';
$cancelled = ( 3 === (int) $event->event_approved ) ? 'cancelled' : '';
$author = ( 0 !== (int) $event->event_author ) ? get_userdata( $event->event_author ) : 'Public Submitter';

if ( 1 === (int) $event->event_flagged && ( isset( $_GET['restrict'] ) && 'flagged' === $_GET['restrict'] ) ) {
$spam = 'spam';
Expand All @@ -897,6 +906,7 @@ function mc_admin_events_table( $events ) {

$trash = ( '' !== $trashed ) ? ' - ' . __( 'Trash', 'my-calendar' ) : '';
$draft = ( '' !== $pending ) ? ' - ' . __( 'Draft', 'my-calendar' ) : '';
$cancel = ( '' !== $cancelled ) ? ' - ' . __( 'Cancelled', 'my-calendar' ) : '';
$inv = ( $invalid ) ? ' - ' . __( 'Invalid Event', 'my-calendar' ) : '';
$limit = ( isset( $_GET['limit'] ) ) ? sanitize_text_field( $_GET['limit'] ) : 'all';
$private = ( mc_private_event( $event, false ) ) ? ' - ' . __( 'Private', 'my-calendar' ) : '';
Expand All @@ -912,7 +922,7 @@ function mc_admin_events_table( $events ) {
$can_edit = mc_can_edit_event( $event );
if ( current_user_can( 'mc_manage_events' ) || current_user_can( 'mc_approve_events' ) || $can_edit ) {
?>
<tr class="<?php echo esc_attr( "$class $spam $pending $trashed $problem" ); ?>">
<tr class="<?php echo esc_attr( "$class $spam $pending $trashed $problem $cancelled" ); ?>">
<th scope="row">
<input type="checkbox" value="<?php echo absint( $event->event_id ); ?>" name="mass_edit[]" id="mc<?php echo absint( $event->event_id ); ?>" aria-describedby='event<?php echo absint( $event->event_id ); ?>' />
<label for="mc<?php echo absint( $event->event_id ); ?>">
Expand All @@ -939,7 +949,7 @@ function mc_admin_events_table( $events ) {
echo wp_kses_post( '<br /><strong class="error">' . sprintf( __( 'There is a problem with this event. <a href="%s">Edit</a>', 'my-calendar' ), esc_url( $edit_url ) ) . '</strong>' );
}
}
echo wp_kses_post( $private . $trash . $draft . $inv );
echo wp_kses_post( $private . $trash . $draft . $cancel . $inv );
?>
</strong>

Expand Down Expand Up @@ -975,12 +985,12 @@ function mc_admin_events_table( $events ) {
|
<?php
if ( current_user_can( 'mc_approve_events' ) && $can_edit ) {
if ( 1 === (int) $event->event_approved ) {
if ( 'public' === mc_event_states_type( $event->event_approved ) ) {
$mo = 'reject';
$te = __( 'Trash', 'my-calendar' );
} else {
$mo = 'publish';
$te = __( 'Publish', 'my-calendar' );
$te = ( 'private' === mc_event_states_type( $event->event_approved ) ) ? __( 'Make Public', 'my-calendar' ) : __( 'Publish', 'my-calendar' );
}
?>
<a href="<?php echo esc_url( add_query_arg( '_mcnonce', $mcnonce, admin_url( "admin.php?page=my-calendar-manage&amp;mode=$mo&amp;limit=$limit&amp;event_id=$event->event_id" ) ) ); ?>" class='<?php echo esc_attr( $mo ); ?>' aria-describedby='event<?php echo absint( $event->event_id ); ?>'><?php echo esc_html( $te ); ?></a>
Expand Down
30 changes: 28 additions & 2 deletions src/my-calendar-events.php
Original file line number Diff line number Diff line change
Expand Up @@ -433,10 +433,11 @@ function mc_get_all_holidays( $before, $after ) {
function mc_get_new_events( $cat_id = false ) {
$mcdb = mc_is_remote_db();
$ts_string = mc_ts();
$public = implode( ',', mc_event_states_by_type( 'public' ) );
if ( $cat_id ) {
$cat = "WHERE event_category = $cat_id AND event_approved = 1 AND event_flagged <> 1";
$cat = "WHERE event_category = $cat_id AND event_approved IN (' . $public . ') AND event_flagged <> 1";
} else {
$cat = 'WHERE event_approved = 1 AND event_flagged <> 1';
$cat = 'WHERE event_approved IN (' . $public . ') AND event_flagged <> 1';
}
$exclude_categories = mc_private_categories();
/**
Expand Down Expand Up @@ -1315,6 +1316,19 @@ function mc_status_links( $allow_filters ) {
// Translators: Number of total events.
$arc_text = sprintf( __( 'Archived (%d)', 'my-calendar' ), $counts['archive'] );

$can_text = '';
if ( isset( $counts['cancel'] ) && 0 < (int) $counts['cancel'] ) {
$can_attributes = ( isset( $_GET['limit'] ) && 'cancelled' === $_GET['limit'] ) ? ' aria-current="true"' : '';
// Translators: Number of total events.
$can_text = sprintf( __( 'Cancelled (%d)', 'my-calendar' ), $counts['cancel'] );
}
$pri_text = '';
if ( isset( $counts['private'] ) && 0 < (int) $counts['private'] ) {
$pri_attributes = ( isset( $_GET['limit'] ) && 'private' === $_GET['limit'] ) ? ' aria-current="true"' : '';
// Translators: Number of total events.
$pri_text = sprintf( __( 'Private (%d)', 'my-calendar' ), $counts['private'] );
}

$spa_attributes = ( isset( $_GET['restrict'] ) && 'flagged' === $_GET['restrict'] ) ? ' aria-current="true"' : '';
// Translators: Number of total events.
$spa_text = sprintf( __( 'Spam (%d)', 'my-calendar' ), $counts['spam'] );
Expand All @@ -1336,6 +1350,18 @@ function mc_status_links( $allow_filters ) {
<li>
<a ' . $arc_attributes . ' href="' . mc_admin_url( 'admin.php?page=my-calendar-manage&amp;restrict=archived' ) . '">' . $arc_text . '</a>
</li>';
if ( $can_text ) {
$output .= '
<li>
<a ' . $can_attributes . ' href="' . admin_url( 'admin.php?page=my-calendar-manage&amp;limit=cancelled' ) . '">' . $can_text . '</a>
</li>';
}
if ( $pri_text ) {
$output .= '
<li>
<a ' . $pri_attributes . ' href="' . admin_url( 'admin.php?page=my-calendar-manage&amp;limit=private' ) . '">' . $pri_text . '</a>
</li>';
}
if ( ( function_exists( 'akismet_http_post' ) || ( 0 < (int) $counts['spam'] ) ) && $allow_filters ) {
$output .= '
<li>
Expand Down
Loading

0 comments on commit fbc730d

Please sign in to comment.