From eba1a3c3841a0e3c6250e20a41ad2df2738cef87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jes=C3=BAs=20Amieiro=20Becerra?=
<1667814+amieiro@users.noreply.github.com>
Date: Fri, 16 Feb 2024 14:23:53 +0100
Subject: [PATCH] Add the delete button in the edit form of an event (#69)
* Add the delete button in the edit form of an event
* Check that a trashed event can not be edited
* Move some logic outside the template
* Fix style
* Check if the show_delete_button variable exists in the template
* Add the delete_event in the action
* Remove some unnecesary conditions
* Fix some problems with the Delete button visibility
* Add a method to know if an event has stats
* Change the $_POST['form_name'] to $action to know if the action is 'delete_event'
* Fix styles
---
assets/js/translation-events.js | 34 ++++++++++--
...lass-wporg-gp-translation-events-route.php | 35 ++++++++----
...gp-translation-events-stats-calculator.php | 17 ++++++
templates/events-form.php | 4 ++
wporg-gp-translation-events.php | 54 +++++++++++++------
5 files changed, 113 insertions(+), 31 deletions(-)
diff --git a/assets/js/translation-events.js b/assets/js/translation-events.js
index 2087e31c..28b7bd4b 100644
--- a/assets/js/translation-events.js
+++ b/assets/js/translation-events.js
@@ -22,6 +22,7 @@ jQuery(document).ready(function($) {
}
$('#event-form-action').val( btnClicked );
var $form = $('.translation-event-form');
+ var $is_creation = $('#form-name').val() == 'create_event' ? true : false;
$.ajax({
type: 'POST',
@@ -41,6 +42,9 @@ jQuery(document).ready(function($) {
$('button[data-event-status="draft"]').text('Update Draft');
}
$('#event-url').removeClass('hide-event-url').find('a').attr('href', response.data.eventUrl).text(response.data.eventUrl);
+ if ( $is_creation ) {
+ $('#delete-button').toggle();
+ }
$gp.notices.success(response.data.message);
}
},
@@ -50,7 +54,27 @@ jQuery(document).ready(function($) {
});
});
- function validateEventDates() {
+ $('.delete-event').on('click', function(e) {
+ e.preventDefault();
+ if ( ! confirm( 'Are you sure you want to delete this event?' ) ) {
+ return;
+ }
+ var $form = $('.translation-event-form');
+ $('#form-name').val('delete_event');
+ $('#event-form-action').val( 'delete' );
+ $.ajax({
+ type: 'POST',
+ url: $translation_event.url,
+ data:$form.serialize(),
+ success: function(response) {
+ window.location = response.data.eventDeleteUrl;
+ },
+ error: function(error) {
+ $gp.notices.error(response.data.message);
+ },
+ });
+ });
+ function validateEventDates() {
var startDateTimeInput = $('#event-start');
var endDateTimeInput = $('#event-end');
if ( ! startDateTimeInput.length || ! endDateTimeInput.length ) {
@@ -65,7 +89,7 @@ jQuery(document).ready(function($) {
});
}
function selectUserTimezone() {
- document.querySelector(`#event-timezone option[value="${Intl.DateTimeFormat().resolvedOptions().timeZone}"]`).selected = true
+ document.querySelector(`#event-timezone option[value="${Intl.DateTimeFormat().resolvedOptions().timeZone}"]`).selected = true
}
function convertToUserLocalTime() {
@@ -80,11 +104,11 @@ jQuery(document).ready(function($) {
var userLocalDateTime = new Date(eventDateObj.getTime() - userTimezoneOffsetMs);
var options = { weekday: 'short', year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: true, timeZoneName: 'short' };
-
+
timeEl.textContent = userLocalDateTime.toLocaleString('en-US', options);
});
}
-
+
});
}( jQuery, $gp )
-);
\ No newline at end of file
+);
diff --git a/includes/class-wporg-gp-translation-events-route.php b/includes/class-wporg-gp-translation-events-route.php
index 7e809ed8..aeb7ecc2 100644
--- a/includes/class-wporg-gp-translation-events-route.php
+++ b/includes/class-wporg-gp-translation-events-route.php
@@ -108,16 +108,18 @@ public function events_create() {
if ( ! is_user_logged_in() ) {
$this->die_with_error( 'You must be logged in to create an event', 403 );
}
- $event_form_title = 'Create Event';
- $event_form_name = 'create_event';
- $css_show_url = 'hide-event-url';
- $event_id = null;
- $event_title = '';
- $event_description = '';
- $event_timezone = '';
- $event_start = '';
- $event_end = '';
- $event_url = '';
+ $event_form_title = 'Create Event';
+ $event_form_name = 'create_event';
+ $css_show_url = 'hide-event-url';
+ $event_id = null;
+ $event_title = '';
+ $event_description = '';
+ $event_timezone = '';
+ $event_start = '';
+ $event_end = '';
+ $event_url = '';
+ $create_delete_button = true;
+ $visibility_delete_button = 'none';
$this->tmpl( 'events-form', get_defined_vars() );
}
@@ -137,6 +139,9 @@ public function events_edit( int $event_id ) {
if ( ! $event || 'event' !== $event->post_type || ! ( current_user_can( 'edit_post', $event->ID ) || intval( $event->post_author ) === get_current_user_id() ) ) {
$this->die_with_error( 'Event does not exist, or you do not have permission to edit it.', 403 );
}
+ if ( 'trash' === $event->post_status ) {
+ $this->die_with_error( 'You cannot edit a trashed event', 403 );
+ }
include ABSPATH . 'wp-admin/includes/post.php';
$event_form_title = 'Edit Event';
@@ -149,6 +154,16 @@ public function events_edit( int $event_id ) {
$permalink = str_replace( '%pagename%', $post_name, $permalink );
$event_url = get_site_url() . gp_url( wp_make_link_relative( $permalink ) );
$event_timezone = get_post_meta( $event_id, '_event_timezone', true ) ?: '';
+ $create_delete_button = false;
+ $visibility_delete_button = 'inline-flex';
+
+ $stats_calculator = new WPORG_GP_Translation_Events_Stats_Calculator();
+ if ( ! $stats_calculator->event_has_stats( $event ) ) {
+ $current_user = wp_get_current_user();
+ if ( $current_user->ID === $event->post_author || current_user_can( 'manage_options' ) ) {
+ $create_delete_button = true;
+ }
+ }
try {
$event_start = self::convertToTimezone( get_post_meta( $event_id, '_event_start', true ), $event_timezone );
diff --git a/includes/class-wporg-gp-translation-events-stats-calculator.php b/includes/class-wporg-gp-translation-events-stats-calculator.php
index e2cfda89..b66e2dc7 100644
--- a/includes/class-wporg-gp-translation-events-stats-calculator.php
+++ b/includes/class-wporg-gp-translation-events-stats-calculator.php
@@ -109,4 +109,21 @@ public function for_event( WP_Post $event ): WPORG_GP_Translation_Events_Event_S
return $stats;
}
+
+ /**
+ * Check if an event has stats.
+ *
+ * @param WP_Post $event The event to check.
+ *
+ * @return bool True if the event has stats, false otherwise.
+ */
+ public function event_has_stats( WP_Post $event ): bool {
+ try {
+ $stats = $this->for_event( $event );
+ } catch ( Exception $e ) {
+ return false;
+ }
+
+ return ! empty( $stats->rows() );
+ }
}
diff --git a/templates/events-form.php b/templates/events-form.php
index 31cce4f4..04100425 100644
--- a/templates/events-form.php
+++ b/templates/events-form.php
@@ -76,5 +76,9 @@
+
+
+
+
diff --git a/wporg-gp-translation-events.php b/wporg-gp-translation-events.php
index 77bd5cfb..e086d8ab 100644
--- a/wporg-gp-translation-events.php
+++ b/wporg-gp-translation-events.php
@@ -140,7 +140,7 @@ function validate_event_dates( string $event_start, string $event_end ): bool {
function submit_event_ajax() {
$event_id = null;
$response_message = '';
- $form_actions = array( 'draft', 'publish' );
+ $form_actions = array( 'draft', 'publish', 'delete' );
$is_nonce_valid = false;
$nonce_name = '_event_nonce';
@@ -179,7 +179,7 @@ function submit_event_ajax() {
wp_send_json_error( 'Form name must be set' );
}
$action = sanitize_text_field( wp_unslash( $_POST['form_name'] ) );
- if ( ! in_array( $action, array( 'create_event', 'edit_event' ), true ) ) {
+ if ( ! in_array( $action, array( 'create_event', 'edit_event', 'delete_event' ), true ) ) {
wp_send_json_error( 'Invalid form name' );
}
@@ -213,18 +213,40 @@ function submit_event_ajax() {
);
$response_message = 'Event updated successfully!';
}
+ if ( 'delete_event' === $action ) {
+ $event_id = sanitize_text_field( wp_unslash( $_POST['event_id'] ) );
+ $event = get_post( $event_id );
+ if ( ! $event || 'event' !== $event->post_type ) {
+ wp_send_json_error( 'Event does not exist' );
+ }
+ if ( ! ( current_user_can( 'delete_post', $event->ID ) || get_current_user_id() === $event->post_author ) ) {
+ wp_send_json_error( 'You do not have permission to delete this event' );
+ }
+ $stats_calculator = new WPORG_GP_Translation_Events_Stats_Calculator();
+ try {
+ $event_stats = $stats_calculator->for_event( $event );
+ } catch ( Exception $e ) {
+ wp_send_json_error( 'Failed to calculate event stats' );
+ }
+ if ( ! empty( $event_stats->rows() ) ) {
+ wp_send_json_error( 'Event has translations and cannot be deleted' );
+ }
+ wp_trash_post( $event_id );
+ $response_message = 'Event deleted successfully!';
+ }
if ( ! $event_id ) {
wp_send_json_error( 'Event could not be created or updated' );
}
- try {
- update_post_meta( $event_id, '_event_start', convert_to_utc( $event_start, $event_timezone ) );
- update_post_meta( $event_id, '_event_end', convert_to_utc( $event_end, $event_timezone ) );
- } catch ( Exception $e ) {
- wp_send_json_error( 'Invalid start or end' );
- }
-
- update_post_meta( $event_id, '_event_timezone', $event_timezone );
+ if ( 'delete_event' !== $_POST['form_name'] ) {
+ try {
+ update_post_meta( $event_id, '_event_start', convert_to_utc( $event_start, $event_timezone ) );
+ update_post_meta( $event_id, '_event_end', convert_to_utc( $event_end, $event_timezone ) );
+ } catch ( Exception $e ) {
+ wp_send_json_error( 'Invalid start or end' );
+ }
+ update_post_meta( $event_id, '_event_timezone', $event_timezone );
+ }
try {
WPORG_GP_Translation_Events_Active_Events_Cache::invalidate();
} catch ( Exception $e ) {
@@ -234,14 +256,14 @@ function submit_event_ajax() {
list( $permalink, $post_name ) = get_sample_permalink( $event_id );
$permalink = str_replace( '%pagename%', $post_name, $permalink );
-
wp_send_json_success(
array(
- 'message' => $response_message,
- 'eventId' => $event_id,
- 'eventUrl' => str_replace( '%pagename%', $post_name, $permalink ),
- 'eventStatus' => $event_status,
- 'eventEditUrl' => esc_url( gp_url( '/events/edit/' . $event_id ) ),
+ 'message' => $response_message,
+ 'eventId' => $event_id,
+ 'eventUrl' => str_replace( '%pagename%', $post_name, $permalink ),
+ 'eventStatus' => $event_status,
+ 'eventEditUrl' => esc_url( gp_url( '/events/edit/' . $event_id ) ),
+ 'eventDeleteUrl' => esc_url( gp_url( '/events/my-events/' ) ),
)
);
}