';
- endif;
+ $_attendee = $attendee_repo->get_attendee( $event_id, $_user->ID );
+ if ( $_attendee instanceof Attendee ) :
+ echo '
';
endif;
?>
diff --git a/templates/events-header.php b/templates/events-header.php
index 479f513e..ebc547e7 100644
--- a/templates/events-header.php
+++ b/templates/events-header.php
@@ -2,14 +2,12 @@
namespace Wporg\TranslationEvents;
-use GP;
use Wporg\TranslationEvents\Attendee\Attendee;
use Wporg\TranslationEvents\Event\Event;
/** @var Attendee $attendee */
/** @var Event $event */
/** @var string $event_page_title */
-/** @var bool $is_editable_event */
?>
@@ -23,13 +21,7 @@
My Events
current_user_can( 'admin' ) );
- if ( $can_crud_event ) :
+ if ( current_user_can( 'create_translation_event' ) ) :
?>
Create Event
@@ -61,8 +53,7 @@
- is_host() ) || current_user_can( 'edit_post', $event->id() ) ) && $is_editable_event; ?>
-
+ id() ) ) : ?>
diff --git a/tests/event/event-capabilities.php b/tests/event/event-capabilities.php
new file mode 100644
index 00000000..176323fe
--- /dev/null
+++ b/tests/event/event-capabilities.php
@@ -0,0 +1,160 @@
+event_factory = new Event_Factory();
+ $this->stats_factory = new Stats_Factory();
+ $this->attendee_repository = new Attendee_Repository();
+ $this->event_repository = new Event_Repository( $this->attendee_repository );
+ }
+
+ public function test_cannot_create_if_no_crud_permission() {
+ $this->set_normal_user_as_current();
+
+ add_filter( 'gp_translation_events_can_crud_event', '__return_false' );
+
+ $this->assertFalse( current_user_can( 'create_translation_event' ) );
+ }
+
+ public function test_can_create_if_crud_permission() {
+ $this->set_normal_user_as_current();
+ get_current_user_id();
+
+ add_filter( 'gp_translation_events_can_crud_event', '__return_true' );
+
+ $this->assertTrue( current_user_can( 'create_translation_event' ) );
+ }
+
+ public function test_cannot_view_non_published_events() {
+ $this->set_normal_user_as_current();
+
+ $event_id = $this->event_factory->create_active();
+ $event = $this->event_repository->get_event( $event_id );
+ $event->set_status( 'draft' );
+ $this->event_repository->update_event( $event );
+
+ $this->assertFalse( current_user_can( 'view_translation_event', $event_id ) );
+ }
+
+ public function test_gp_admin_can_view_non_published_events() {
+ $this->set_normal_user_as_current();
+
+ $event_id = $this->event_factory->create_active();
+ $event = $this->event_repository->get_event( $event_id );
+ $event->set_status( 'draft' );
+ $this->event_repository->update_event( $event );
+
+ add_filter( 'gp_translation_events_can_crud_event', '__return_true' );
+
+ $this->assertTrue( current_user_can( 'view_translation_event', $event_id ) );
+ }
+
+ public function test_event_id_as_string() {
+ $this->set_normal_user_as_current();
+
+ $event_id = $this->event_factory->create_active();
+
+ $this->assertTrue( current_user_can( 'edit_translation_event', (string) $event_id ) );
+ }
+
+ public function test_author_can_edit() {
+ $this->set_normal_user_as_current();
+
+ $event_id = $this->event_factory->create_active();
+
+ $this->assertTrue( current_user_can( 'edit_translation_event', $event_id ) );
+ }
+
+ public function test_non_author_cannot_edit() {
+ $this->set_normal_user_as_current();
+ $non_author_user_id = get_current_user_id();
+ $this->set_normal_user_as_current(); // This user is the author.
+
+ $event_id = $this->event_factory->create_active();
+
+ $this->assertFalse( user_can( $non_author_user_id, 'edit_translation_event', $event_id ) );
+ }
+
+ public function test_host_can_edit() {
+ $this->set_normal_user_as_current();
+ $non_author_user_id = get_current_user_id();
+ $this->set_normal_user_as_current(); // This user is the author.
+
+ $event_id = $this->event_factory->create_active();
+
+ $attendee = new Attendee( $event_id, $non_author_user_id );
+ $attendee->mark_as_host();
+ $this->attendee_repository->insert_attendee( $attendee );
+
+ $this->assertTrue( user_can( $non_author_user_id, 'edit_translation_event', $event_id ) );
+ }
+
+ public function test_gp_admin_can_edit() {
+ $this->set_normal_user_as_current();
+ $non_author_user_id = get_current_user_id();
+ $this->set_normal_user_as_current(); // This user is the author.
+
+ $event_id = $this->event_factory->create_active();
+ add_filter( 'gp_translation_events_can_crud_event', '__return_true' );
+
+ $this->assertTrue( user_can( $non_author_user_id, 'edit_translation_event', $event_id ) );
+ }
+
+ public function test_cannot_edit_past_event() {
+ $this->set_normal_user_as_current();
+
+ $event_id = $this->event_factory->create_inactive_past();
+
+ $this->assertFalse( current_user_can( 'edit_translation_event', $event_id ) );
+ }
+
+ public function test_cannot_edit_event_with_stats() {
+ $this->set_normal_user_as_current();
+ $author_user_id = get_current_user_id();
+
+ $event_id = $this->event_factory->create_active();
+ $this->stats_factory->create( $event_id, $author_user_id, 1, 'create' );
+
+ $this->assertFalse( current_user_can( 'edit_translation_event', $event_id ) );
+ }
+
+ public function test_cannot_delete_if_cannot_edit() {
+ $this->set_normal_user_as_current();
+ $non_author_user_id = get_current_user_id();
+ $this->set_normal_user_as_current(); // This user is the author.
+
+ $event_id = $this->event_factory->create_active();
+ $this->assertFalse( user_can( $non_author_user_id, 'delete_translation_event', $event_id ) );
+ }
+
+ public function test_cannot_delete_without_delete_post_capability() {
+ $this->set_normal_user_as_current();
+
+ $event_id = $this->event_factory->create_active();
+
+ $this->assertFalse( current_user_can( 'delete_translation_event', $event_id ) );
+ }
+
+ public function test_can_delete_with_delete_post_capability() {
+ $this->set_admin_user_as_current();
+
+ $event_id = $this->event_factory->create_active();
+
+ $this->assertFalse( current_user_can( 'delete_translation_event', $event_id ) );
+ }
+}
diff --git a/wporg-gp-translation-events.php b/wporg-gp-translation-events.php
index 398071cc..bbed37b8 100644
--- a/wporg-gp-translation-events.php
+++ b/wporg-gp-translation-events.php
@@ -26,14 +26,18 @@
use WP_Query;
use Wporg\TranslationEvents\Attendee\Attendee;
use Wporg\TranslationEvents\Attendee\Attendee_Repository;
+use Wporg\TranslationEvents\Event\Event_Capabilities;
use Wporg\TranslationEvents\Event\Event_Form_Handler;
use Wporg\TranslationEvents\Event\Event_Repository_Cached;
use Wporg\TranslationEvents\Event\Event_Repository_Interface;
+use Wporg\TranslationEvents\Stats\Stats_Calculator;
use Wporg\TranslationEvents\Stats\Stats_Listener;
class Translation_Events {
public const CPT = 'translation_event';
+ private Event_Capabilities $event_capabilities;
+
public static function get_instance(): Translation_Events {
static $instance = null;
if ( null === $instance ) {
@@ -75,6 +79,13 @@ public function __construct() {
if ( is_admin() ) {
Upgrade::upgrade_if_needed();
}
+
+ $this->event_capabilities = new Event_Capabilities(
+ self::get_event_repository(),
+ self::get_attendee_repository(),
+ new Stats_Calculator()
+ );
+ $this->event_capabilities->register_hooks();
}
public function gp_init() {
@@ -175,7 +186,7 @@ public function save_event_meta_boxes( int $post_id ) {
* Handle the event form submission for the creation, editing, and deletion of events. This function is called via AJAX.
*/
public function submit_event_ajax() {
- $form_handler = new Event_Form_Handler( self::get_event_repository(), self::get_attendee_repository() );
+ $form_handler = new Event_Form_Handler( self::get_event_repository() );
// Nonce verification is done by the form handler.
// phpcs:ignore WordPress.Security.NonceVerification.Missing
$form_handler->handle( $_POST );