\WP_Stager_Integration\Event::generate_structured_data(array $event): array

Description

Generates structured data (Schema.org JSON-LD) for an event.

Parameters:

ParameterTypeDescription
$event array The raw Stager event data.

Returns:

array The structured data array.

Information

Fileclass-event.php line 1435

Full Code

/**
 * Generates structured data (Schema.org JSON-LD) for an event.
 *
 * @param array $event The raw Stager event data.
 *
 * @return array The structured data array.
 */
public static function generate_structured_data( $event ) {

    // Get data
    $feature_enabled_seo_features = (bool) Feature::has_feature_seo_features();

    // Bail if feature is not enabled
    if ( ! $feature_enabled_seo_features ) {
        return array();
    }

    // Type casting
    $event = (array) $event;

    // Bail if no event data was passed
    if ( ! $event ) {
        return array();
    }

    // Extract event properties
    $event_id                 = (int) ($event[ 'id' ] ?? 0);
    $event_name               = (string) ($event[ 'name' ] ?? __( 'Untitled event', 'wp-stager-integration' ));
    $event_subtitle           = (string) self::get_subtitle( $event );
    $event_start              = (string) ($event[ 'programStartAt' ] ?? '');
    $event_end                = (string) ($event[ 'programEndAt' ] ?? '');
    $event_description        = (string) (self::get_text_html( $event ) ?: self::get_text( $event ));
    $event_type               = (string) ($event[ 'type' ] ?? '');
    $event_status             = (string) ($event[ 'status' ] ?? Options::STAGER_EVENT_STATUS_CONFIRMED);
    $event_visitors_expected  = (int) ($event[ 'visitorsExpected' ] ?? 0);
    $event_tickets_total      = (int) ($event[ 'ticketsTotalAmount' ] ?? 0);
    $event_shop_url           = (string) ($event[ 'shopUrl' ] ?? '');
    $event_membership_url     = (string) ($event[ 'membershipSalesUrl' ] ?? '');
    $event_labels             = (array) ($event[ 'eventLabels' ] ?? array());
    $event_customer_interests = (array) ($event[ 'customerInterests' ] ?? array());
    $event_media              = (array) ($event[ 'media' ] ?? array());
    $event_spotify_artists    = (array) ($event[ 'spotifyArtists' ] ?? array());
    $event_program_items      = (array) ($event[ 'programItems' ] ?? array());
    $event_ticket_groups      = (array) ($event[ 'ticketGroups' ] ?? array());
    $event_tags               = (string) ($event[ 'tags' ] ?? '');
    $event_organization_id    = (int) ($event[ 'organizationId' ] ?? 0);
    $event_organization_name  = (string) ($event[ 'organizationName' ] ?? '');
    $location                 = (array) ($event[ 'location' ] ?? array());

    // Build Event Schema
    $event_schema = array(
        '@context'  => 'https://schema.org',
        '@type'     => 'Event',
        'name'      => sanitize_text_field( $event_name ),
        'startDate' => sanitize_text_field( $event_start ),
        'endDate'   => sanitize_text_field( $event_end ),
    );

    // Add event ID if available
    if ( $event_id ) {
        $event_schema[ 'identifier' ] = sanitize_text_field( $event_id );
    }

    // Add description if available
    if ( $event_description ) {
        $event_schema[ 'description' ] = sanitize_text_field( wp_strip_all_tags( $event_description ) );
    }

    // Add subtitle as alternative name
    if ( $event_subtitle ) {
        $event_schema[ 'alternateName' ] = sanitize_text_field( $event_subtitle );
    }

    // Add event status (map Stager status to Schema.org status)
    if ( $event_status ) {
        $status_mapping                = array(
            Options::STAGER_EVENT_STATUS_CONFIRMED       => 'EventScheduled',
            Options::STAGER_EVENT_STATUS_CANCELLED       => 'EventCancelled',
            Options::STAGER_EVENT_STATUS_TO_BE_CANCELLED => 'EventScheduled',
            Options::STAGER_EVENT_STATUS_TO_BE_CONFIRMED => 'EventPostponed',
            Options::STAGER_EVENT_STATUS_OPTION          => 'EventScheduled',
        );
        $schema_status                 = $status_mapping[ $event_status ] ?? 'EventScheduled';
        $event_schema[ 'eventStatus' ] = 'https://schema.org/' . $schema_status;
    }

    // Add expected visitors as capacity
    if ( $event_visitors_expected > 0 ) {
        $event_schema[ 'maximumAttendeeCapacity' ] = $event_visitors_expected;
    }

    // Add event labels as keywords
    if ( $event_labels && is_array( $event_labels ) ) {
        $label_names = array();
        foreach ( $event_labels as $label ) {
            if ( isset( $label[ 'name' ] ) ) {
                $label_names[] = sanitize_text_field( $label[ 'name' ] );
            }
        }
        if ( ! empty( $label_names ) ) {
            $event_schema[ 'keywords' ] = sanitize_text_field( implode( ', ', $label_names ) );
        }
    }

    // Add customer interests as additional keywords
    if ( $event_customer_interests && is_array( $event_customer_interests ) ) {
        $interest_names = array();
        foreach ( $event_customer_interests as $interest ) {
            if ( isset( $interest[ 'name' ] ) ) {
                $interest_names[] = sanitize_text_field( $interest[ 'name' ] );
            }
        }
        if ( ! empty( $interest_names ) ) {
            $existing_keywords          = $event_schema[ 'keywords' ] ?? '';
            $event_schema[ 'keywords' ] = $existing_keywords . ($existing_keywords ? ', ' : '') . sanitize_text_field( implode( ', ', $interest_names ) );
        }
    }

    // Add tags as additional keywords
    if ( $event_tags ) {
        $existing_keywords          = $event_schema[ 'keywords' ] ?? '';
        $event_schema[ 'keywords' ] = $existing_keywords . ($existing_keywords ? ', ' : '') . sanitize_text_field( $event_tags );
    }

    // Add media information
    $main_image_url = self::get_main_image_url( $event );

    if ( $main_image_url ) {
        $event_schema[ 'image' ] = esc_url( $main_image_url );
    }

    if ( $event_media && is_array( $event_media ) ) {

        // Add regular URLs as sameAs
        if ( isset( $event_media[ 'regularUrls' ] ) && is_array( $event_media[ 'regularUrls' ] ) ) {
            $urls = array();
            foreach ( $event_media[ 'regularUrls' ] as $url_obj ) {
                if ( isset( $url_obj[ 'url' ] ) ) {
                    $urls[] = esc_url( $url_obj[ 'url' ] );
                }
            }
            if ( ! empty( $urls ) ) {
                $event_schema[ 'sameAs' ] = $urls;
            }
        }
    }

    // Add shop URL as offers
    if ( $event_shop_url ) {
        $event_schema[ 'offers' ] = array(
            '@type'        => 'Offer',
            'url'          => esc_url( $event_shop_url ),
            'availability' => 'https://schema.org/InStock',
        );
    }

    // Add organization as organizer
    if ( $event_organization_name ) {
        $event_schema[ 'organizer' ] = array(
            '@type' => 'Organization',
            'name'  => sanitize_text_field( $event_organization_name ),
        );
    }

    // Add Spotify artists as performers
    if ( $event_spotify_artists && is_array( $event_spotify_artists ) ) {
        $performers = array();
        foreach ( $event_spotify_artists as $artist ) {
            if ( isset( $artist[ 'artist' ] ) ) {
                $performer_data = array(
                    '@type' => 'Person',
                    'name'  => sanitize_text_field( $artist[ 'artist' ] ),
                );
                if ( isset( $artist[ 'spotifyUrl' ] ) ) {
                    $performer_data[ 'sameAs' ] = esc_url( $artist[ 'spotifyUrl' ] );
                }
                if ( isset( $artist[ 'actType' ] ) ) {
                    $performer_data[ 'jobTitle' ] = sanitize_text_field( $artist[ 'actType' ] );
                }
                $performers[] = $performer_data;
            }
        }
        if ( ! empty( $performers ) ) {
            $event_schema[ 'performer' ] = (count( $performers ) === 1 ? $performers[ 0 ] : $performers);
        }
    }

    // Add program items as event schedule
    if ( $event_program_items && is_array( $event_program_items ) ) {
        $schedule_items = array();
        foreach ( $event_program_items as $item ) {
            if ( isset( $item[ 'name' ] ) && isset( $item[ 'showtimeStartsAt' ] ) ) {
                $schedule_item = array(
                    '@type'     => 'Schedule',
                    'name'      => sanitize_text_field( $item[ 'name' ] ),
                    'startDate' => sanitize_text_field( $item[ 'showtimeStartsAt' ] ),
                );
                if ( isset( $item[ 'showtimeEndsAt' ] ) ) {
                    $schedule_item[ 'endDate' ] = sanitize_text_field( $item[ 'showtimeEndsAt' ] );
                }
                $schedule_items[] = $schedule_item;
            }
        }
        if ( ! empty( $schedule_items ) ) {
            $event_schema[ 'eventSchedule' ] = $schedule_items;
        }
    }

    // Add ticket groups as offers
    if ( $event_ticket_groups && is_array( $event_ticket_groups ) ) {
        $offers = array();
        foreach ( $event_ticket_groups as $ticket_group ) {
            if ( isset( $ticket_group[ 'name' ] ) && isset( $ticket_group[ 'priceInCents' ] ) ) {
                $offer = array(
                    '@type'         => 'Offer',
                    'name'          => sanitize_text_field( $ticket_group[ 'name' ] ),
                    'price'         => intval( $ticket_group[ 'priceInCents' ] ) / 100, // Convert cents to currency
                    'priceCurrency' => 'EUR' // Default to EUR, could be made configurable
                );

                if ( isset( $ticket_group[ 'onlineSales' ] ) && $ticket_group[ 'onlineSales' ] ) {
                    $offer[ 'availability' ] = 'https://schema.org/InStock';
                } else {
                    $offer[ 'availability' ] = 'https://schema.org/OutOfStock';
                }

                if ( isset( $ticket_group[ 'onlineSaleEndAt' ] ) ) {
                    $offer[ 'validFrom' ]    = sanitize_text_field( $ticket_group[ 'saleStartAt' ] ?? '' );
                    $offer[ 'validThrough' ] = sanitize_text_field( $ticket_group[ 'onlineSaleEndAt' ] );
                }

                $offers[] = $offer;
            }
        }
        if ( ! empty( $offers ) ) {
            $event_schema[ 'offers' ] = (count( $offers ) === 1 ? $offers[ 0 ] : $offers);
        }
    }

    // Add location information (enhanced with Stager API fields)
    if ( $location ) {
        $location_schema = array(
            '@type' => 'Place',
            'name'  => sanitize_text_field( $location[ 'name' ] ?? '' ),
        );

        // Add address if we have required fields
        if ( isset( $location[ 'street' ] ) && isset( $location[ 'city' ] ) && isset( $location[ 'country' ] ) ) {
            $location_schema[ 'address' ] = array(
                '@type'           => 'PostalAddress',
                'streetAddress'   => sanitize_text_field( $location[ 'street' ] ),
                'addressLocality' => sanitize_text_field( $location[ 'city' ] ),
                'postalCode'      => sanitize_text_field( $location[ 'zipcode' ] ?? '' ),
                'addressCountry'  => sanitize_text_field( $location[ 'country' ] ),
            );
        }

        // Add geo coordinates if available
        if ( isset( $location[ 'latitude' ] ) && isset( $location[ 'longitude' ] ) ) {
            $location_schema[ 'geo' ] = array(
                '@type'     => 'GeoCoordinates',
                'latitude'  => sanitize_text_field( $location[ 'latitude' ] ),
                'longitude' => sanitize_text_field( $location[ 'longitude' ] ),
            );
        }

        // Add URL if available
        if ( isset( $location[ 'url' ] ) ) {
            $location_schema[ 'url' ] = esc_url( $location[ 'url' ] );
        }

        // Add phone if available
        if ( isset( $location[ 'phoneNumber' ] ) ) {
            $location_schema[ 'telephone' ] = sanitize_text_field( $location[ 'phoneNumber' ] );
        }

        $event_schema[ 'location' ] = $location_schema;
    }

    /**
     * Filters the event structured data.
     *
     * This filter hook lets you modify the Event Schema / structured data before it is output on the page. If an empty array is returned, no structured data will be output.
     * If you wish to disable the structured data output, you can use the <code>wpstagerintegration_output_structured_data</code> filter hook.
     *
     * @param array $event_schema The event structured data.
     * @param array $event        The raw Stager event data.
     *
     * @return array The filtered event structured data.
     *
     * @see "wpstagerintegration_output_structured_data" filter hook
     */
    $event_schema = (array) apply_filters( 'wpstagerintegration_event_structured_data', $event_schema, $event );

    return $event_schema;
}

💡 If you ever get stuck or have a question, please check our FAQs, our Free Integration Service, our paid Full Integration Service, or reach out to us!

Get WP Stager Integration

🎁 Limited offer: Use code WELCOME26 to get your first month for free!