diff --git a/.forgejo/workflows/phpunit.yml b/.forgejo/workflows/phpunit.yml index b67d8e9..aec7273 100644 --- a/.forgejo/workflows/phpunit.yml +++ b/.forgejo/workflows/phpunit.yml @@ -37,7 +37,7 @@ jobs: path: | ${{ env.WP_CORE_DIR }} ${{ env.WP_TESTS_DIR }} - key: cache-wordpress-5 + key: cache-wordpress-8 - name: Cache Composer id: cache-composer-phpunit @@ -96,5 +96,10 @@ jobs: - name: Run Integration tests for WP Event Manager run: cd /workspace/Event-Federation/wordpress-activitypub-event-bridge/ && ./vendor/bin/phpunit --filter=wp_event_manager + env: + PHP_VERSION: ${{ matrix.php-version }} + + - name: Run Integration tests for Eventin (WP Event Solution) + run: cd /workspace/Event-Federation/wordpress-activitypub-event-bridge/ && ./vendor/bin/phpunit --filter=wp_event_solution env: PHP_VERSION: ${{ matrix.php-version }} \ No newline at end of file diff --git a/bin/install-wp-tests.sh b/bin/install-wp-tests.sh index 0e0e4ad..759ad25 100755 --- a/bin/install-wp-tests.sh +++ b/bin/install-wp-tests.sh @@ -239,6 +239,7 @@ install_wp_plugins() { install_wp_plugin gatherpress install_wp_plugin events-manager install_wp_plugin wp-event-manager + install_wp_plugin wp-event-solution } install_wp diff --git a/composer.json b/composer.json index 1b3bb36..940dff0 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,6 @@ { "name": "menrath/wordpress-activitypub-event-bridge", + "version": "1.0.0", "description": "The ActivityPub Event Bridge help for event custom post types to federate properly.", "type": "wordpress-plugin", "require": { @@ -51,16 +52,19 @@ "@test-the-events-calendar", "@test-gatherpress", "@test-events-manager", - "@test-wp-event-manager" + "@test-wp-event-manager", + "@test-eventin" ], "test-debug": [ "@prepare-test", - "@test-wp-event-manager" + "@test-eventin" ], "test-vs-event-list": "phpunit --filter=vs_event_list", "test-the-events-calendar": "phpunit --filter=the_events_calendar", "test-gatherpress": "phpunit --filter=gatherpress", "test-events-manager": "phpunit --filter=events_manager", - "test-wp-event-manager": "phpunit --filter=wp_event_manager" + "test-wp-event-manager": "phpunit --filter=wp_event_manager", + "test-eventin": "phpunit --filter=eventin", + "test-all": "phpunit" } } diff --git a/includes/activitypub/transformer/class-eventin.php b/includes/activitypub/transformer/class-eventin.php index b95393e..db80179 100644 --- a/includes/activitypub/transformer/class-eventin.php +++ b/includes/activitypub/transformer/class-eventin.php @@ -15,8 +15,12 @@ defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore use Activitypub\Activity\Extended_Object\Place; use ActivityPub_Event_Bridge\Activitypub\Transformer\Event; +use DateTime; +use DateTimeZone; use Etn\Core\Event\Event_Model; +use function Activitypub\esc_hashtag; + /** * ActivityPub Transformer for Events managed with Eventin. * @@ -48,16 +52,115 @@ final class Eventin extends Event { /** * Get the end time from the event object. */ - protected function get_start_time(): string { - return \gmdate( 'Y-m-d\TH:i:s\Z', \time() ); + public function get_start_time(): string { + $datetime = new DateTime( $this->event_model->get_start_datetime(), new DateTimeZone( $this->event_model->get_timezone() ) ); + return \gmdate( 'Y-m-d\TH:i:s\Z', $datetime->getTimestamp() ); } /** - * Get status of the tribe event - * - * @return string status of the event + * Get the end time from the event object. */ - public function get_status(): ?string { - return 'CONFIRMED'; + public function get_end_time(): string { + $datetime = new DateTime( $this->event_model->get_end_datetime(), new DateTimeZone( $this->event_model->get_timezone() ) ); + return \gmdate( 'Y-m-d\TH:i:s\Z', $datetime->getTimestamp() ); + } + + /** + * Get the timezone of the event. + */ + public function get_timezone(): string { + return $this->event_model->get_timezone(); + } + + /** + * Get whether the event is online. + * + * @return bool + */ + public function get_is_online(): bool { + return 'online' === $this->event_model->__get( 'event_type' ) ? true : false; + } + + /** + * Maybe add online link to attachments. + * + * @return array + */ + public function get_attachment(): array { + $attachment = parent::get_attachment(); + + $location = (array) $this->event_model->__get( 'location' ); + if ( array_key_exists( 'integration', $location ) && array_key_exists( $location['integration'], $location ) ) { + $online_link = array( + 'type' => 'Link', + 'mediaType' => 'text/html', + 'name' => $location[ $location['integration'] ], + 'href' => $location[ $location['integration'] ], + ); + $attachment[] = $online_link; + } + return $attachment; + } + + /** + * Compose the events tags. + */ + public function get_tag() { + // The parent tag function also fetches the mentions. + $tags = parent::get_tag(); + + $post_tags = \wp_get_post_terms( $this->wp_object->ID, 'etn_tags' ); + $post_categories = \wp_get_post_terms( $this->wp_object->ID, 'etn_category' ); + + if ( ! is_wp_error( $post_tags ) && $post_tags ) { + foreach ( $post_tags as $term ) { + $tag = array( + 'type' => 'Hashtag', + 'href' => \esc_url( \get_tag_link( $term->term_id ) ), + 'name' => esc_hashtag( $term->name ), + ); + $tags[] = $tag; + } + } + + if ( ! is_wp_error( $post_categories ) && $post_categories ) { + foreach ( $post_categories as $term ) { + $tag = array( + 'type' => 'Hashtag', + 'href' => \esc_url( \get_tag_link( $term->term_id ) ), + 'name' => esc_hashtag( $term->name ), + ); + $tags[] = $tag; + } + } + + if ( empty( $tags ) ) { + return null; + } + + return $tags; + } + + /** + * Get the location. + * + * @return ?Place + */ + public function get_location(): ?Place { + $location = (array) $this->event_model->__get( 'location' ); + + if ( ! array_key_exists( 'address', $location ) ) { + return null; + } + + $place = new Place(); + + $address = $location['address']; + + $place->set_name( $address ); + $place->set_address( $address ); + $place->set_sensitive( null); + + return $place; } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 359543a..ece3323 100755 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -43,6 +43,8 @@ function _manually_load_plugin() { } } + update_option( 'purchase_history_table_structure_migration_done', true ); + $plugin_file = null; // See if we want to run integration tests for a specific event-plugin. switch ( $activitypub_event_extension_integration_filter ) { @@ -55,6 +57,9 @@ function _manually_load_plugin() { case 'events_manager': $plugin_file = 'events-manager/events-manager.php'; break; + case 'eventin': + $plugin_file = 'wp-event-solution/eventin.php'; + break; case 'gatherpress': $plugin_file = 'gatherpress/gatherpress.php'; break; @@ -66,6 +71,7 @@ function _manually_load_plugin() { if ( $plugin_file ) { // Manually load the event plugin. require_once $plugin_dir . $plugin_file; + update_option( 'purchase_history_table_structure_migration_done', true ); $current = get_option( 'active_plugins', array() ); $current[] = $plugin_file; sort( $current ); diff --git a/tests/test-class-plugin-eventin.php b/tests/test-class-plugin-eventin.php new file mode 100644 index 0000000..0303265 --- /dev/null +++ b/tests/test-class-plugin-eventin.php @@ -0,0 +1,64 @@ +activate_activitypub_support_for_active_event_plugins(); + + // Delete all posts afterwards. + _delete_all_posts(); + } + + /** + * Test that the right transformer gets applied. + */ + public function test_eventin_transformer_class() { + // We only test for one event plugin being active at the same time, + // even though we support multiple onces in theory. + // But testing all combinations is beyond scope. + $active_event_plugins = \ActivityPub_Event_Bridge\Setup::get_instance()->get_active_event_plugins(); + $this->assertEquals( 1, count( $active_event_plugins ) ); + + // Enable ActivityPub support for the event plugin. + $this->assertContains( 'etn', get_option( 'activitypub_support_post_types' ) ); + + // Create a Eventin Event without content. + $event_model = new \Etn\Core\Event\Event_Model(); + $event_model->create( + array( + 'post_status' => 'publish', + 'post_title' => 'Eventin Test Event Title', + 'post_content' => 'Eventin Test Event Description', + 'etn_start_date' => \gmdate( 'Y-m-d', strtotime( '+10 days 15:00:00' ) ), + 'etn_end_date' => \gmdate( 'Y-m-d', strtotime( '+10 days 16:00:00' ) ), + 'etn_start_time' => \gmdate( 'H:i', strtotime( '+10 days 15:00:00' ) ), + 'etn_end_time' => \gmdate( 'H:i', strtotime( '+10 days 15:00:00' ) ), + 'etn_timezone' => 'Europe/Vienna', + ) + ); + + // Call the transformer Factory. + $transformer = \Activitypub\Transformer\Factory::get_transformer( $event_model->id ); + + // Check that we got the right transformer. + $this->assertInstanceOf( \ActivityPub_Event_Bridge\Activitypub\Transformer\Eventin::class, $transformer ); + } +}