Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/wp-event-solution/base/Enqueue/admin.php
+++ b/wp-event-solution/base/Enqueue/admin.php
@@ -134,7 +134,7 @@
wp_localize_script( 'etn-onboard-index', 'localized_data_obj', $localize_data );
wp_enqueue_style( 'etn-icon' );
// Enque block editor style in events create and edit pages only
- if ( isset( $_GET['page'] ) && $_GET['page'] === 'eventin' ) {
+ if ( isset( $_GET['page'] ) && $_GET['page'] === 'eventin' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- admin script enqueue condition; page param compared to a literal string only.
wp_enqueue_style( 'wp-block-editor' );
}
}
--- a/wp-event-solution/base/Enqueue/register.php
+++ b/wp-event-solution/base/Enqueue/register.php
@@ -194,7 +194,7 @@
}
// Parse the URL
- $url_parts = parse_url( $url );
+ $url_parts = wp_parse_url( $url );
// Check if the URL has a path component
if ( ! isset( $url_parts['path'] ) ) {
@@ -204,7 +204,7 @@
$clean_path = str_replace( '.js', '.asset.php', $url_parts['path'] );
// Get the file path from the URL path
- $file_path = $_SERVER['DOCUMENT_ROOT'] . $clean_path;
+ $file_path = ( isset( $_SERVER['DOCUMENT_ROOT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['DOCUMENT_ROOT'] ) ) : '' ) . $clean_path; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- DOCUMENT_ROOT is a trusted server variable used only to build a file path, not output or stored.
// Check if the file exists
if ( ! file_exists( $file_path ) ) {
--- a/wp-event-solution/base/Exporter/CSVExporter.php
+++ b/wp-event-solution/base/Exporter/CSVExporter.php
@@ -58,7 +58,7 @@
fputcsv( $output, $colunms );
- fclose( $output );
+ fclose( $output ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose -- php://output stream, WP_Filesystem cannot handle output streams.
return ob_get_clean();
}
@@ -71,7 +71,7 @@
protected function export_rows() {
$data = $this->data;
ob_clean();
- $buffer = fopen( 'php://output', 'w' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_read_fopen
+ $buffer = fopen( 'php://output', 'w' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
ob_start();
array_walk( $data, array( $this, 'export_row' ), $buffer );
@@ -111,7 +111,7 @@
* @return void
*/
protected function send_content( $content ) {
- echo $content;
+ echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Raw CSV file output sent with text/csv headers; HTML escaping would corrupt the CSV.
}
/**
--- a/wp-event-solution/base/Exporter/JsonExporter.php
+++ b/wp-event-solution/base/Exporter/JsonExporter.php
@@ -68,7 +68,7 @@
$data = $this->data;
$output = json_encode( $data, JSON_PRETTY_PRINT );
- echo $output;
+ echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Raw JSON output sent with application/json headers; HTML escaping would corrupt the JSON.
die();
}
}
--- a/wp-event-solution/base/Importer/CSVReader.php
+++ b/wp-event-solution/base/Importer/CSVReader.php
@@ -48,7 +48,7 @@
$file = $this->file;
$csv_data = [];
- $handle = fopen( $file, 'r' );
+ $handle = fopen( $file, 'r' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- binary CSV file read, WP_Filesystem::get_contents() does not support line-by-line streaming.
$headers = fgetcsv( $handle );
if ( ! $headers ) {
@@ -70,7 +70,7 @@
}
}
- fclose( $handle );
+ fclose( $handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
return $csv_data;
}
--- a/wp-event-solution/base/Importer/ReaderFactory.php
+++ b/wp-event-solution/base/Importer/ReaderFactory.php
@@ -15,8 +15,15 @@
public static function get_reader( $file ) {
$file_name = ! empty( $file['tmp_name'] ) ? $file['tmp_name'] : '';
- $finfo = new finfo( FILEINFO_MIME_TYPE );
- $real_mime = $finfo->file( $file_name );
+ $finfo = class_exists( 'finfo' ) ? new finfo( FILEINFO_MIME_TYPE ) : null;
+ $real_mime = ( $finfo instanceof finfo ) ? $finfo->file( $file_name ) : '';
+
+ if ( ! $real_mime ) {
+ $ext_map = [ 'csv' => 'text/csv', 'json' => 'application/json' ];
+ $ext = strtolower( pathinfo( $file['name'] ?? '', PATHINFO_EXTENSION ) );
+ $real_mime = $ext_map[ $ext ] ?? '';
+ }
+
$allowed = [ 'text/plain', 'text/csv', 'application/json' ];
if ( ! in_array( $real_mime, $allowed, true ) ) {
--- a/wp-event-solution/build/js/dashboard.asset.php
+++ b/wp-event-solution/build/js/dashboard.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-media-utils', 'wp-primitives', 'wp-url'), 'version' => '3aed6612f3ca89d5b655');
+<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-media-utils', 'wp-primitives', 'wp-url'), 'version' => '23ba72a2d0b5dd395a86');
--- a/wp-event-solution/build/js/event-manager-public.asset.php
+++ b/wp-event-solution/build/js/event-manager-public.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('wp-i18n'), 'version' => '0c6a01f0cce61c75f533');
+<?php return array('dependencies' => array('wp-i18n'), 'version' => 'fe5a7d6ff27e8b4a0ba4');
--- a/wp-event-solution/build/js/gutenberg-blocks.asset.php
+++ b/wp-event-solution/build/js/gutenberg-blocks.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-media-utils', 'wp-primitives', 'wp-server-side-render', 'wp-url'), 'version' => '3ecef035bd9777832793');
+<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-media-utils', 'wp-primitives', 'wp-server-side-render', 'wp-url'), 'version' => '67ba0ac6a53e0abfd677');
--- a/wp-event-solution/build/js/index-calendar.asset.php
+++ b/wp-event-solution/build/js/index-calendar.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-element', 'wp-html-entities', 'wp-i18n'), 'version' => 'cb825ee223c3f913e8d1');
+<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-element', 'wp-html-entities', 'wp-i18n'), 'version' => 'c0bd8be4898fcf716766');
--- a/wp-event-solution/build/js/index-onboard.asset.php
+++ b/wp-event-solution/build/js/index-onboard.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-media-utils', 'wp-primitives', 'wp-url'), 'version' => '673fdceb8069bc1b2de3');
+<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-media-utils', 'wp-primitives', 'wp-url'), 'version' => '9e2d53c3c2580820510b');
--- a/wp-event-solution/build/js/module-purchase.asset.php
+++ b/wp-event-solution/build/js/module-purchase.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-media-utils', 'wp-primitives', 'wp-url'), 'version' => '94f079ed63fdcf8a6d29');
+<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-dom-ready', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-media-utils', 'wp-primitives', 'wp-url'), 'version' => 'c904dd14e9535705e6eb');
--- a/wp-event-solution/build/js/packages.asset.php
+++ b/wp-event-solution/build/js/packages.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-media-utils', 'wp-primitives', 'wp-url'), 'version' => '74927a9b8c0cad8472e7');
+<?php return array('dependencies' => array('moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-block-editor', 'wp-block-library', 'wp-blocks', 'wp-components', 'wp-compose', 'wp-core-data', 'wp-data', 'wp-element', 'wp-hooks', 'wp-html-entities', 'wp-i18n', 'wp-keyboard-shortcuts', 'wp-media-utils', 'wp-primitives', 'wp-url'), 'version' => 'fcfa4e541e917a165434');
--- a/wp-event-solution/build/js/template-builder-header-toolbar.asset.php
+++ b/wp-event-solution/build/js/template-builder-header-toolbar.asset.php
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-compose', 'wp-data', 'wp-edit-post', 'wp-element', 'wp-html-entities', 'wp-i18n', 'wp-plugins', 'wp-url'), 'version' => '78655f7068d817cbe16e');
+<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-compose', 'wp-data', 'wp-edit-post', 'wp-element', 'wp-html-entities', 'wp-i18n', 'wp-plugins', 'wp-url'), 'version' => 'fc313dbebe121f23b0fa');
--- a/wp-event-solution/core/Admin/EventReminder.php
+++ b/wp-event-solution/core/Admin/EventReminder.php
@@ -131,7 +131,7 @@
'post_status' => 'any',
'posts_per_page' => -1,
- 'meta_query' => [
+ 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
[
'key' => 'etn_event_id',
'value' => $event_id,
--- a/wp-event-solution/core/Admin/Menu.php
+++ b/wp-event-solution/core/Admin/Menu.php
@@ -89,41 +89,35 @@
'position' => 2,
],
[
+ 'title' => __( 'Bookings', 'eventin' ),
+ 'capability' => 'etn_manage_order',
+ 'url' => 'admin.php?page=' . $this->menu_slug . '#/bookings',
+ 'position' => 3,
+ ],
+ [
'title' => __( 'Speaker & Organizer', 'eventin' ),
'capability' => 'etn_manage_organizer',
'url' => 'admin.php?page=' . $this->menu_slug . '#/speakers',
- 'position' => 3,
+ 'position' => 5,
],
[
'title' => __( 'Schedules', 'eventin' ),
'capability' => 'etn_manage_schedule',
'url' => 'admin.php?page=' . $this->menu_slug . '#/schedules',
- 'position' => 4,
- ],
- [
- 'title' => __( 'Bookings', 'eventin' ),
- 'capability' => 'etn_manage_order',
- 'url' => 'admin.php?page=' . $this->menu_slug . '#/bookings',
- 'position' => 5,
- ],
- [
- 'title' => __( 'Settings', 'eventin' ),
- 'capability' => 'etn_manage_setting',
- 'url' => 'admin.php?page=' . $this->menu_slug . '#/settings',
- 'position' => 7,
+ 'position' => 6,
],
[
'title' => __( 'Template Builder', 'eventin' ),
'capability' => 'etn_manage_template',
'url' => 'admin.php?page=' . $this->menu_slug . '#/template-builder',
- 'position' => 8,
+ 'position' => 7,
],
[
- 'title' => __( 'Shortcodes', 'eventin' ),
- 'capability' => 'etn_manage_shortcode',
- 'url' => 'admin.php?page=' . $this->menu_slug . '#/shortcodes',
+ 'title' => __( 'Settings', 'eventin' ),
+ 'capability' => 'etn_manage_setting',
+ 'url' => 'admin.php?page=' . $this->menu_slug . '#/settings',
'position' => 9,
- ],
+ ],
[
'title' => __( 'Extensions', 'eventin' ),
'capability' => 'etn_manage_addons',
@@ -131,6 +125,12 @@
'position' => 10,
],
[
+ 'title' => __( 'Shortcodes', 'eventin' ),
+ 'capability' => 'etn_manage_shortcode',
+ 'url' => 'admin.php?page=' . $this->menu_slug . '#/shortcodes',
+ 'position' => 11,
+ ],
+ [
'title' => __( 'About Us', 'eventin' ),
'capability' => 'etn_manage_get_help',
'url' => 'admin.php?page=' . $this->menu_slug . '#/get-help',
@@ -145,7 +145,7 @@
'title' => __( 'Attendees', 'eventin' ),
'capability' => 'etn_manage_attendee',
'url' => 'admin.php?page=' . $this->menu_slug . '#/attendees',
- 'position' => 6,
+ 'position' => 4,
];
}
@@ -222,7 +222,7 @@
public function render_menu_page() {
?>
<div class="wrap">
- <div id="eventin-dashboard" style="background-color: #fff; min-height: 100vh;"></div>
+ <div id="eventin-dashboard"></div>
</div>
<?php
}
@@ -249,7 +249,7 @@
'etn-speaker'
];
- $post_type = isset( $_GET['post_type'] ) ? sanitize_text_field( $_GET['post_type'] ) : '';
+ $post_type = isset( $_GET['post_type'] ) ? sanitize_text_field( wp_unslash( $_GET['post_type'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- admin menu active-state helper; post_type used only for in_array() comparison.
if ( $pagenow == 'post-new.php' && in_array( $post_type, $post_types ) ) {
$parent_file = 'eventin'; // Parent menu slug
--- a/wp-event-solution/core/Admin/hooks.php
+++ b/wp-event-solution/core/Admin/hooks.php
@@ -69,16 +69,6 @@
new EtnCoreEventApi();
- add_action( 'rest_api_init', function () {
- register_rest_route( 'eventin/v1', '/nonce', [
- 'methods' => WP_REST_Server::READABLE,
- 'permission_callback' => '__return_true',
- 'callback' => function () {
- nocache_headers();
- return rest_ensure_response( [ 'nonce' => wp_create_nonce( 'wp_rest' ) ] );
- },
- ] );
- } );
// Todo: Temporary added this function for version compatibility. Need to remove this after 4.0.21
add_action( 'admin_notices', [ $this, 'eventin_pro_admin_notice' ] );
@@ -283,7 +273,7 @@
'post_status' => 'any',
'fields' => 'ids',
- 'tax_query' => array(
+ 'tax_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
'relation' => 'AND',
[
'taxonomy' => 'etn_speaker_category',
@@ -310,7 +300,7 @@
'post_status' => 'any',
'fields' => 'ids',
- 'tax_query' => array(
+ 'tax_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query
'relation' => 'AND',
[
'taxonomy' => 'etn_speaker_category',
@@ -360,7 +350,7 @@
$term_id = is_array( $term ) ? $term['term_id'] : '';
$args = array(
'role__in' => array('etn-speaker', 'etn-organizer'),
- 'meta_key' => 'etn_speaker_group',
+ 'meta_key' => 'etn_speaker_group', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key
'meta_compare' => 'NOT EXISTS'
);
@@ -475,21 +465,21 @@
* @return string
*/
public function proxy_image() {
- $action = isset( $_GET['action'] ) ? $_GET['action'] : '';
-
+ $action = isset( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Proxy image endpoint; action param is a hardcoded string comparison, not persisted.
+
if ( $action !== 'proxy_image' ) {
return;
}
ob_start();
- if ( $_SERVER['REQUEST_METHOD'] === 'OPTIONS' ) {
+ if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 'OPTIONS' ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- REQUEST_METHOD is a trusted server variable, only compared against a literal string.
http_response_code(200);
ob_end_flush();
exit;
}
- $imageUrl = isset( $_GET['url'] ) ? $_GET['url'] : null;
+ $imageUrl = isset( $_GET['url'] ) ? esc_url_raw( wp_unslash( $_GET['url'] ) ) : null; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Proxy endpoint; URL is immediately validated by is_valid_image_url() below.
// Validate and sanitize the URL
if ( ! $this->is_valid_image_url( $imageUrl ) ) {
@@ -537,12 +527,12 @@
header("Content-Type: $mimeType");
- $tempStream = fopen('php://temp', 'r+');
- fwrite( $tempStream, $imageContent );
+ $tempStream = fopen('php://temp', 'r+'); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen -- php://temp stream, WP_Filesystem cannot handle in-memory streams.
+ fwrite( $tempStream, $imageContent ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite
rewind( $tempStream );
fpassthru( $tempStream );
- fclose( $tempStream );
+ fclose( $tempStream ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
} else {
http_response_code(404);
}
@@ -600,8 +590,8 @@
* @return void
*/
public function render_template_preview() {
- $action = ! empty( $_GET['action'] ) ? $_GET['action'] : '';
- $template_id = ! empty( $_GET['template_id'] ) ? intval( $_GET['template_id'] ) : 0;
+ $action = ! empty( $_GET['action'] ) ? sanitize_text_field( wp_unslash( $_GET['action'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Template preview action; value is compared to a literal string only.
+ $template_id = ! empty( $_GET['template_id'] ) ? absint( $_GET['template_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Template preview; ID is cast to integer before use.
if ( 'etn-preview-template' !== $action ) {
return;
@@ -623,13 +613,13 @@
* @return void
*/
public function render_ics_download() {
- $action = ! empty( $_GET['etn_action'] ) ? sanitize_text_field( wp_unslash( $_GET['etn_action'] ) ) : '';
+ $action = ! empty( $_GET['etn_action'] ) ? sanitize_text_field( wp_unslash( $_GET['etn_action'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( 'download_ics' !== $action ) {
return;
}
- $event_id = ! empty( $_GET['event_id'] ) ? absint( $_GET['event_id'] ) : 0;
+ $event_id = ! empty( $_GET['event_id'] ) ? absint( $_GET['event_id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$event = $event_id ? get_post( $event_id ) : null;
// Security: only serve published Eventin event posts.
@@ -850,7 +840,7 @@
}
// Parse URL to get components
- $parsedUrl = parse_url( $cleanUrl );
+ $parsedUrl = wp_parse_url( $cleanUrl );
if ( ! $parsedUrl || ! isset( $parsedUrl['scheme'] ) || ! isset( $parsedUrl['host'] ) ) {
return false;
}
--- a/wp-event-solution/core/Attendee/Api/AttendeeController.php
+++ b/wp-event-solution/core/Attendee/Api/AttendeeController.php
@@ -218,7 +218,7 @@
if ( ! empty( $meta_query ) ) {
$meta_query['relation'] = 'AND';
- $args['meta_query'] = $meta_query;
+ $args['meta_query'] = $meta_query; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
}
if ( $search && ! is_numeric( $search ) ) {
@@ -278,7 +278,7 @@
),
);
- $args['meta_query'] = $meta_query;
+ $args['meta_query'] = $meta_query; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
}
$attendees = [];
@@ -610,7 +610,8 @@
);
}
- $message = sprintf( __( '%d Attendee are deleted of %d', 'eventin' ), $count, count( $ids ) );
+ // translators: %1$d is the number of attendees deleted, %2$d is the total number of attendees selected.
+ $message = sprintf( __( '%1$d Attendee are deleted of %2$d', 'eventin' ), $count, count( $ids ) );
return rest_ensure_response( $message );
}
@@ -829,7 +830,7 @@
'customer_lname' => '',
'customer_email' => ! empty( $data['etn_email'] ) ? $data['etn_email'] : '',
'event_id' => ! empty( $data['etn_event_id'] ) ? $data['etn_event_id'] : '',
- 'date_time' => date('Y-m-d h:i A'),
+ 'date_time' => gmdate('Y-m-d h:i A'),
'customer_id' => $customer_id,
'total_price' => $total_price,
'status' => 'success' === $data['etn_status'] ? 'completed' : 'failed',
@@ -1142,4 +1143,4 @@
return rest_ensure_response( $data );
}
-}
No newline at end of file
+}
--- a/wp-event-solution/core/Attendee/AttendeeExporter.php
+++ b/wp-event-solution/core/Attendee/AttendeeExporter.php
@@ -133,9 +133,9 @@
$data[$key] = $extra_field_value;
break;
- case 'date':
+ case 'date':
$date_format = get_option( 'date_format' );
- $date = date( $date_format, strtotime( $extra_field_value ) );
+ $date = gmdate( $date_format, strtotime( $extra_field_value ) );
if ( ! $extra_field_value ) {
$date = '';
--- a/wp-event-solution/core/Attendee/Hooks.php
+++ b/wp-event-solution/core/Attendee/Hooks.php
@@ -22,7 +22,7 @@
add_action( 'woocommerce_account_purchased-events_endpoint', [ $this, 'purchased_events_content' ] );
// woo thank you page contains key in url so don't show attendee info here. this is for user purchased events
- if ( !isset( $_GET['key'] ) ) {
+ if ( !isset( $_GET['key'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only check for WooCommerce order key param; no data is modified.
add_action( 'woocommerce_order_details_after_order_table', [ $this, 'after_order_table_show_attendee_information' ], 9, 1 );
}
}
@@ -133,7 +133,7 @@
'post_type' => 'etn-attendee',
'post_status' => 'publish',
'posts_per_page' => -1,
- 'meta_query' => [
+ 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
'relation' => 'OR',
[
'key' => 'eventin_order_id',
--- a/wp-event-solution/core/Attendee/RsvpExporter.php
+++ b/wp-event-solution/core/Attendee/RsvpExporter.php
@@ -177,9 +177,9 @@
$data[$key] = $extra_field_value;
break;
- case 'date':
+ case 'date':
$date_format = get_option( 'date_format' );
- $date = date( $date_format, strtotime( $extra_field_value ) );
+ $date = gmdate( $date_format, strtotime( $extra_field_value ) );
if ( ! $extra_field_value ) {
$date = '';
--- a/wp-event-solution/core/Attendee/TicketIdGenerator.php
+++ b/wp-event-solution/core/Attendee/TicketIdGenerator.php
@@ -43,7 +43,7 @@
// Generate a random string of the desired length
for ( $i = 0; $i < $length; $i++ ) {
- $random_string .= $characters[ rand( 0, $characters_length - 1 ) ];
+ $random_string .= $characters[ wp_rand( 0, $characters_length - 1 ) ];
}
return $random_string;
@@ -62,7 +62,7 @@
'post_status' => 'any',
'posts_per_page' => -1,
'fields' => 'ids',
- 'meta_query' => [
+ 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
[
'key' => 'etn_unique_ticket_id',
'value' => $ticket,
--- a/wp-event-solution/core/Attendee/TicketTemplate.php
+++ b/wp-event-solution/core/Attendee/TicketTemplate.php
@@ -63,7 +63,7 @@
* Download PDF from email and admin dashboard
*/
public function generate_ticket_pdf() {
- if ( isset( $_GET['etn_action'] ) && sanitize_text_field( $_GET['etn_action'] ) === 'download_ticket' ) {
+ if ( isset( $_GET['etn_action'] ) && sanitize_text_field( wp_unslash( $_GET['etn_action'] ) ) === 'download_ticket' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- ticket PDF download link; etn_info_edit_token acts as a secret access token.
$get_arr = filter_input_array( INPUT_GET, FILTER_SANITIZE_FULL_SPECIAL_CHARS );
@@ -143,14 +143,14 @@
$event = new Event_Model( $event_id );
- $start_date = date( $date_format, strtotime( $event->etn_start_date ) );
- $end_date = date( $date_format, strtotime( $event->etn_end_date ) );
+ $start_date = gmdate( $date_format, strtotime( $event->etn_start_date ) );
+ $end_date = gmdate( $date_format, strtotime( $event->etn_end_date ) );
$start_date_time = $event->etn_start_date . ' ' . $event->etn_start_time;
$end_date_time = $event->etn_end_date . ' ' . $event->etn_end_time;
- $start_time = date( $time_format, strtotime( $start_date_time ) );
- $end_time = date( $time_format, strtotime( $end_date_time ) );
+ $start_time = gmdate( $time_format, strtotime( $start_date_time ) );
+ $end_time = gmdate( $time_format, strtotime( $end_date_time ) );
$date = $start_date . $date_separator . $end_date;
@@ -179,7 +179,7 @@
if ( $post && $post->post_type === 'etn-template' ) {
include_once Wpeventin::templates_dir() . "template-parts/attendee/ticket-markup-block.php";
} else {
- if(class_exists('Wpeventin_Pro') && $ticket_style === 'style-2') {
+ if(class_exists('Wpeventin_Pro') && 'style-2' === $ticket_style) {
include_once Wpeventin_Pro::templates_dir() . "attendee/ticket-markup-".esc_html($ticket_style).".php";
}else {
$ticket_style = $ticket_style == 'style-2'?'style-1':$ticket_style;
@@ -212,4 +212,4 @@
return false;
}
-}
No newline at end of file
+}
--- a/wp-event-solution/core/Attendee/attendee-model.php
+++ b/wp-event-solution/core/Attendee/attendee-model.php
@@ -78,7 +78,7 @@
'post_type' => 'etn-attendee',
'post_status' => $post_status,
'posts_per_page' => $limit,
- 'meta_query' => [
+ 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
[
'key' => $key,
'value' => $value,
@@ -155,7 +155,7 @@
* @return string
*/
public function get_extra_fields_content() {
- $fields = '<ul class="etn-attendee-extra-data" style="list-style: none; padding-left: 0; margin-left: 0;">';
+ $fields = '<ul class="etn-attendee-extra-data" style="list-style: none; list-style-type: none; padding-left: 0; margin-left: 0;">';
$extra_fields = $this->get_extra_fields();
if ( $extra_fields ) {
@@ -170,6 +170,43 @@
return $fields;
}
/**
+ * Get a single extra field value by key
+ *
+ * @param string $field_key The field key (without prefix)
+ *
+ * @return string
+ */
+ public function get_single_extra_field( $field_key ) {
+ $extra_fields = $this->get_extra_fields();
+
+ if ( ! isset( $extra_fields[ $field_key ] ) ) {
+ return '';
+ }
+
+ $value = $extra_fields[ $field_key ];
+
+ return is_array( $value ) ? implode( ', ', $value ) : $value;
+ }
+
+ /**
+ * Get extra fields as a single comma-separated inline string
+ *
+ * @return string
+ */
+ public function get_extra_fields_inline() {
+ $extra_fields = $this->get_extra_fields();
+ $parts = [];
+
+ foreach ( $extra_fields as $key => $field ) {
+ $label = ucwords( str_replace( '_', ' ', $key ) );
+ $value = is_array( $field ) ? implode( ', ', $field ) : $field;
+ $parts[] = $label . ': ' . $value;
+ }
+
+ return implode( ', ', $parts );
+ }
+
+ /**
* Get attendde data
*
* @return array
@@ -200,8 +237,8 @@
'post_type' => 'etn-attendee',
'post_status' => 'any',
'posts_per_page' => -1,
- 'meta_query' => [
- [
+ 'meta_query' => [ // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
+ [
'key' => "eventin_order_id",
'value' => $eventin_order_id,
'compare' => '=',
--- a/wp-event-solution/core/Attendee/info-update.php
+++ b/wp-event-solution/core/Attendee/info-update.php
@@ -16,7 +16,7 @@
}
public function attendee_info_update_process() {
- if ( isset( $_GET['etn_action'] ) && sanitize_text_field( $_GET['etn_action'] ) === 'edit_information' ) {
+ if ( isset( $_GET['etn_action'] ) && sanitize_text_field( wp_unslash( $_GET['etn_action'] ) ) === 'edit_information' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- attendee info edit link; action value is compared to a literal string only.
$get_arr = filter_input_array( INPUT_GET, FILTER_SANITIZE_FULL_SPECIAL_CHARS );
$attendee_id = ! empty( $get_arr['attendee_id'] ) ? intval( $get_arr['attendee_id'] ) : 0;
@@ -52,7 +52,7 @@
public function update_attendee_details() {
- if ( isset( $_POST["etn_attendee_details_update_action"] ) && $_POST["etn_attendee_details_update_action"] == "etn_attendee_details_update_action" ) {
+ if ( isset( $_POST["etn_attendee_details_update_action"] ) && $_POST["etn_attendee_details_update_action"] == "etn_attendee_details_update_action" ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- nonce field 'attendee_personal_data' is generated via wp_nonce_field('attendee_details_nonce') in the form template and verified via wp_verify_nonce() at the top of templates/attendee/update-attendee.php before any state-changing operations.
$post_arr = filter_input_array( INPUT_POST, FILTER_SANITIZE_SPECIAL_CHARS );
// render template
--- a/wp-event-solution/core/Blocks/BlockService.php
+++ b/wp-event-solution/core/Blocks/BlockService.php
@@ -4,6 +4,7 @@
defined( 'ABSPATH' ) || exit;
+use EventinBlocksBlockTypesAttendeeExtraFields;
use EventinBlocksBlockTypesAttendeeInfo;
use EventinBlocksBlockTypesBuyTicket;
use EventinBlocksBlockTypesContainer;
@@ -95,6 +96,7 @@
TemplateHeading::class,
DiamondSeparator::class,
AttendeeInfo::class,
+ AttendeeExtraFields::class,
EventInfo::class,
TicketInfo::class,
Container::class,
--- a/wp-event-solution/core/Blocks/BlockTypes/AbstractBlock.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/AbstractBlock.php
@@ -285,6 +285,7 @@
}
$safe_css = preg_replace( '/<scriptb[^>]*>(.*?)</script>/is', '', $css );
+ $safe_css = str_replace( '</style>', '', $safe_css ); // Prevent breaking out of <style> context via CSS injection.
return $safe_css;
}
--- a/wp-event-solution/core/Blocks/BlockTypes/AttendeeExtraFields.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/AttendeeExtraFields.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace EventinBlocksBlockTypes;
+
+defined( 'ABSPATH' ) || exit;
+
+/**
+ * AttendeeExtraFields Block
+ */
+class AttendeeExtraFields extends AbstractBlock {
+ /**
+ * Block name.
+ *
+ * @var string
+ */
+ protected $block_name = 'attendee-extra-fields';
+
+ /**
+ * Block namespace
+ *
+ * @var string
+ */
+ protected $namespace = 'eventin-pro';
+
+ /**
+ * Include and render the block
+ *
+ * @param array $attributes Block attributes. Default empty array
+ * @param string $content Block content. Default empty string
+ * @param WP_Block $block Block instance
+ *
+ * @return string Rendered block type output
+ */
+ protected function render( $attributes, $content, $block ) {
+ return $content;
+ }
+}
--- a/wp-event-solution/core/Blocks/BlockTypes/BuyTicket.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/BuyTicket.php
@@ -1,60 +1,76 @@
<?php
+ namespace EventinBlocksBlockTypes;
-namespace EventinBlocksBlockTypes;
+ use EtnCoreEventEvent_Model;
+ use EventinBlocksBlockTypesAbstractBlock;
+ use Wpeventin;
-defined( 'ABSPATH' ) || exit;
-use EtnCoreEventEvent_Model;
-use EventinBlocksBlockTypesAbstractBlock;
-use Wpeventin;
-
-/**
- * Buy Event Ticket Gutenberg block
- */
-class BuyTicket extends AbstractBlock
-{
/**
- * Block name.
- *
- * @var string
+ * Buy Event Ticket Gutenberg block
*/
- protected $block_name = 'buy-ticket';
-
- /**
- * Include and render the block
- *
- * @param array $attributes Block attributes. Default empty array
- * @param string $content Block content. Default empty string
- * @param WP_Block $block Block instance
- *
- * @return string Rendered block type output
- */
- protected function render($attributes, $content, $block)
+ class BuyTicket extends AbstractBlock
{
- $style_variant = ! empty($attributes['styleVariant']) ? $attributes['styleVariant'] : 'style-1';
-
- $container_class = ! empty($attributes['containerClassName']) ? $attributes['containerClassName'] : '';
- $styles = ! empty( $attributes['styles'] ) ? $attributes['styles'] : [];
-
- if ( 'etn-template' == get_post_type( get_the_ID() ) ) {
- $template = new EventinTemplateTemplateModel( get_the_ID() );
- $event_id = $template->get_preview_event_id();
- } else {
- $event_id = get_the_ID();
- }
+ /**
+ * Block name.
+ *
+ * @var string
+ */
+ protected $block_name = 'buy-ticket';
+
+ /**
+ * Include and render the block
+ *
+ * @param array $attributes Block attributes. Default empty array
+ * @param string $content Block content. Default empty string
+ * @param WP_Block $block Block instance
+ *
+ * @return string Rendered block type output
+ */
+ protected function render($attributes, $content, $block)
+ {
+ $style_variant = ! empty($attributes['styleVariant']) ? $attributes['styleVariant'] : 'style-1';
+
+ $container_class = ! empty($attributes['containerClassName']) ? $attributes['containerClassName'] : '';
+ $styles = ! empty($attributes['styles']) ? $attributes['styles'] : [];
+ // Check if we're in editor/admin
+ if ($this->is_editor()) {
+ return '<div style="border: 2px dashed #ccc;
+ border-radius: 8px;
+ padding: 20px;
+ text-align: center;
+ background: #f8f9fa;
+ color: #666;
+ margin: 10px 0;">
+ <svg style="width: 24px; height: 24px; margin-bottom: 8px;" viewBox="0 0 24 24">
+ <path fill="currentColor" d="M13 13h-2V7h2v6zm0 4h-2v-2h2v2zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z"/>
+ </svg>
+ <p style="margin: 0; font-size: 14px; font-weight: 500;">' .
+ esc_html__("This Block (Buy Ticket) is not available for preview in Edit Mode. However, it will render correctly on the frontend for customers.", 'eventin') .
+ '</p>
+ </div>';
+ }
+
+ if ($this->is_editor()) {
+ $event_id = ! empty($attributes['eventId']) ? intval($attributes['eventId']) : 0;
+ } else if ('etn-template' == get_post_type(get_the_ID())) {
+ $template = new EventinTemplateTemplateModel(get_the_ID());
+ $event_id = $template->get_preview_event_id();
+ } else {
+ $event_id = get_the_ID();
+ }
- $event = new Event_Model($event_id);
-
- ob_start();
+ $event = new Event_Model($event_id);
+ ob_start();
?>
- <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); ?>
+ <?php echo $this->render_frontend_css($styles, esc_attr($container_class)); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php
- require_once Wpeventin::templates_dir() . 'event/parts/buy-ticket.php';
- ?>
+ require Wpeventin::templates_dir() . 'event/parts/buy-ticket.php';
+ ?>
<?php
- return ob_get_clean();
- }
-}
No newline at end of file
+ return ob_get_clean();
+ }
+ }
No newline at end of file
--- a/wp-event-solution/core/Blocks/BlockTypes/EventAddToCalender.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventAddToCalender.php
@@ -46,7 +46,7 @@
?>
- <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); ?>
+ <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS rendered by render_frontend_css(); script and style tags stripped by generate_frontend_css(). ?>
<?php
require_once Wpeventin::templates_dir() . 'event/parts/event-add-calender.php';
?>
--- a/wp-event-solution/core/Blocks/BlockTypes/EventAttendee.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventAttendee.php
@@ -37,9 +37,15 @@
*/
protected function render($attributes, $content, $block)
{
- $container_class = ! empty($attributes['containerClassName']) ? $attributes['containerClassName'] : '';
- $items_per_row = ! empty($attributes['itemsPerRow']) ? intval($attributes['itemsPerRow']) : 3;
- $styles = ! empty($attributes['styles']) ? $attributes['styles'] : [];
+ $container_class = ! empty($attributes['containerClassName']) ? $attributes['containerClassName'] : '';
+ $items_per_row = ! empty($attributes['itemsPerRow']) ? intval($attributes['itemsPerRow']) : 3;
+ $styles = ! empty($attributes['styles']) ? $attributes['styles'] : [];
+ $style_variant = ! empty($attributes['styleVariant']) ? sanitize_key($attributes['styleVariant']) : 'style-1';
+ $allowed_variants = ['style-1', 'style-2'];
+
+ if (! in_array($style_variant, $allowed_variants, true)) {
+ $style_variant = 'style-1';
+ }
if ($this->is_editor()) {
$event_id = ! empty($attributes['eventId']) ? intval($attributes['eventId']) : 0;
@@ -74,7 +80,7 @@
$frontend_css
);
}
-
+
// Ensure img always uses 100% width/height to fill container, overriding any saved styles
$avatar_img_selector = ".{$container_class} .etn-attendee-item .etn-attendee-avatar img";
$frontend_css .= "n{$avatar_img_selector} {n";
@@ -82,12 +88,14 @@
$frontend_css .= " height: 100% !important;n";
$frontend_css .= "}n";
- echo '<style>' . $frontend_css . '</style>';
+ echo '<style>' . $frontend_css . '</style>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS generated from block editor attributes; HTML escaping would break styles.
}
?>
<?php
- $items_per_row = $items_per_row; // Make available to template
- require_once Wpeventin::templates_dir() . 'event/parts/event-attendee.php';
+ $items_per_row = $items_per_row; // Make available to template
+ $style_variant = $style_variant;
+ $style_template = Wpeventin::templates_dir() . 'event/parts/styles/event-attendee/' . $style_variant . '.php';
+ require $style_template;
return ob_get_clean();
}
}
--- a/wp-event-solution/core/Blocks/BlockTypes/EventBanner.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventBanner.php
@@ -72,7 +72,7 @@
$frontend_css
);
}
- echo '<style>' . $frontend_css . '</style>';
+ echo '<style>' . $frontend_css . '</style>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS generated from block editor attributes; HTML escaping would break styles.
}
?>
<?php
--- a/wp-event-solution/core/Blocks/BlockTypes/EventCategory.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventCategory.php
@@ -46,7 +46,7 @@
ob_start();
?>
- <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); ?>
+ <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS rendered by render_frontend_css(); script and style tags stripped by generate_frontend_css(). ?>
<?php
require_once Wpeventin::templates_dir() . 'event/parts/event-category.php';
?>
--- a/wp-event-solution/core/Blocks/BlockTypes/EventCountDownTimer.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventCountDownTimer.php
@@ -75,7 +75,7 @@
ob_start();
?>
- <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); ?>
+ <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS rendered by render_frontend_css(); script and style tags stripped by generate_frontend_css(). ?>
<?php
require_once Wpeventin::templates_dir() . 'event/parts/event-count-down-timer.php';
?>
--- a/wp-event-solution/core/Blocks/BlockTypes/EventDateTime.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventDateTime.php
@@ -60,7 +60,7 @@
ob_start();
?>
- <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); ?>
+ <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS rendered by render_frontend_css(); script and style tags stripped by generate_frontend_css(). ?>
<?php
$style_template = Wpeventin::templates_dir() . 'event/parts/styles/event-datetime/' . $style_variant . '.php';
require $style_template;
--- a/wp-event-solution/core/Blocks/BlockTypes/EventDescription.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventDescription.php
@@ -58,7 +58,7 @@
ob_start();
?>
- <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); ?>
+ <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS rendered by render_frontend_css(); script and style tags stripped by generate_frontend_css(). ?>
<?php
require Wpeventin::templates_dir() . 'event/parts/event-description.php';
?>
--- a/wp-event-solution/core/Blocks/BlockTypes/EventFaq.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventFaq.php
@@ -64,7 +64,7 @@
$frontend_css
);
}
- echo '<style>' . $frontend_css . '</style>';
+ echo '<style>' . $frontend_css . '</style>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS generated from block editor attributes; HTML escaping would break styles.
}
?>
<?php
--- a/wp-event-solution/core/Blocks/BlockTypes/EventLogo.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventLogo.php
@@ -40,7 +40,7 @@
}
ob_start();
?>
- <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); ?>
+ <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS rendered by render_frontend_css(); script and style tags stripped by generate_frontend_css(). ?>
<?php
require_once Wpeventin::templates_dir() . 'event/parts/logo.php';
?>
--- a/wp-event-solution/core/Blocks/BlockTypes/EventOrganizer.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventOrganizer.php
@@ -8,63 +8,71 @@
use Wpeventin;
/**
- * Event Organizer Gutenberg block
- */
+ * Event Organizer Gutenberg block
+ */
class EventOrganizer extends AbstractBlock
{
- /**
- * Block name.
- *
- * @var string
- */
- protected $block_name = 'event-organizer';
-
- /**
- * Include and render the block
- *
- * @param array $attributes Block attributes. Default empty array
- * @param string $content Block content. Default empty string
- * @param WP_Block $block Block instance
- *
- * @return string Rendered block type output
- */
- protected function render($attributes, $content, $block)
- {
- $container_class = ! empty($attributes['containerClassName']) ? $attributes['containerClassName'] : '';
- $styles = ! empty($attributes['styles']) ? $attributes['styles'] : [];
- $style_variant = ! empty($attributes['styleVariant']) ? sanitize_key($attributes['styleVariant']) : 'style-1';
-
- $allowed_variants = ['style-1', 'style-2'];
- if (! in_array($style_variant, $allowed_variants, true)) {
- $style_variant = 'style-1';
- }
+ /**
+ * Block name.
+ *
+ * @var string
+ */
+ protected $block_name = 'event-organizer';
- if ($this->is_editor()) {
- $event_id = ! empty($attributes['eventId']) ? intval($attributes['eventId']) : 0;
+ /**
+ * Include and render the block
+ *
+ * @param array $attributes Block attributes. Default empty array
+ * @param string $content Block content. Default empty string
+ * @param WP_Block $block Block instance
+ *
+ * @return string Rendered block type output
+ */
+ protected function render($attributes, $content, $block)
+ {
+ $container_class = ! empty($attributes['containerClassName']) ? $attributes['containerClassName'] : '';
+ $styles = ! empty($attributes['styles']) ? $attributes['styles'] : [];
+ $style_variant = ! empty($attributes['styleVariant']) ? sanitize_key($attributes['styleVariant']) : 'style-1';
+
+ $allowed_variants = ['style-1', 'style-2', 'style-3'];
+ if (! in_array($style_variant, $allowed_variants, true)) {
+ $style_variant = 'style-1';
+ }
- if ($event_id == 0) {
- $template = new EventinTemplateTemplateModel(get_the_ID());
- $event_id = $template->get_preview_event_id();
- }
- } else if ('etn-template' == get_post_type(get_the_ID())) {
+ if ($this->is_editor()) {
+ $event_id = ! empty($attributes['eventId']) ? intval($attributes['eventId']) : 0;
+
+ if ($event_id == 0) {
$template = new EventinTemplateTemplateModel(get_the_ID());
$event_id = $template->get_preview_event_id();
- } else {
- $event_id = get_the_ID();
}
+ } else if ('etn-template' == get_post_type(get_the_ID())) {
+ $template = new EventinTemplateTemplateModel(get_the_ID());
+ $event_id = $template->get_preview_event_id();
+ } else {
+ $event_id = get_the_ID();
+ }
- $event = new Event_Model($event_id);
+ $event = new Event_Model($event_id);
- $event_organizers = $event->get_organizers();
+ $event_organizers = $event->get_organizers();
- ob_start();
+ ob_start();
?>
<?php
// Generate CSS with !important to override SCSS
$frontend_css = $this->generate_frontend_css($styles, $container_class);
- if (! empty($frontend_css)) {
+ if (! empty($frontend_css) && ! empty($container_class)) {
+ // Fix wrapper selector: container-class is on the same element as .etn-event-organizers
+ // Change ".container-class .etn-event-organizers" to ".container-class.etn-event-organizers"
+ $frontend_css = preg_replace(
+ '/.' . preg_quote($container_class, '/') . 's+.etn-event-organizers(.etn-organizer-style-d+)?/',
+ '.' . $container_class . '.etn-event-organizers$1',
+ $frontend_css
+ );
+
// Add !important to common properties that need to override SCSS
- $important_properties = ['width', 'height', 'font-size', 'color', 'font-weight', 'line-height', 'letter-spacing', 'margin', 'padding', 'text-align', 'font-family', 'border-width', 'border-color', 'border-style', 'border-radius', 'z-index', 'box-shadow', 'left', 'right', 'top', 'bottom', 'position'];
+ $important_properties = ['width', 'height', 'font-size', 'color', 'background-color', 'font-weight', 'line-height', 'letter-spacing', 'margin', 'padding', 'text-align', 'font-family', 'border-width', 'border-color', 'border-style', 'border-radius', 'z-index', 'box-shadow', 'left', 'right', 'top', 'bottom', 'position'];
foreach ($important_properties as $prop) {
$frontend_css = preg_replace(
"/({$prop})s*:s*([^;!]+?)(?!s*!important)s*;/im",
@@ -72,7 +80,7 @@
$frontend_css
);
}
- echo '<style>' . $frontend_css . '</style>';
+ echo '<style>' . $frontend_css . '</style>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS generated from block editor attributes; HTML escaping would break styles.
}
?>
<?php
@@ -83,4 +91,4 @@
<?php
return ob_get_clean();
}
- }
+ }
--- a/wp-event-solution/core/Blocks/BlockTypes/EventRSVP.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventRSVP.php
@@ -46,7 +46,7 @@
?>
- <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); ?>
+ <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS rendered by render_frontend_css(); script and style tags stripped by generate_frontend_css(). ?>
<?php
require_once Wpeventin::templates_dir() . 'event/parts/rsvp.php';
?>
--- a/wp-event-solution/core/Blocks/BlockTypes/EventSchedule.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventSchedule.php
@@ -8,55 +8,55 @@
use Wpeventin;
/**
- * Event Schedule Gutenberg block
- */
+ * Event Schedule Gutenberg block
+ */
class EventSchedule extends AbstractBlock
{
- /**
- * Block name.
- *
- * @var string
- */
- protected $block_name = 'event-schedule';
-
- /**
- * Include and render the block
- *
- * @param array $attributes Block attributes. Default empty array
- * @param string $content Block content. Default empty string
- * @param WP_Block $block Block instance
- *
- * @return string Rendered block type output
- */
- protected function render($attributes, $content, $block)
- {
- $container_class = ! empty($attributes['containerClassName']) ? $attributes['containerClassName'] : '';
- $styles = ! empty($attributes['styles']) ? $attributes['styles'] : [];
- $style_variant = ! empty($attributes['styleVariant']) ? sanitize_key($attributes['styleVariant']) : 'style-1';
-
- $allowed_variants = ['style-1', 'style-2', 'style-3'];
- if (! in_array($style_variant, $allowed_variants, true)) {
- $style_variant = 'style-1';
- }
+ /**
+ * Block name.
+ *
+ * @var string
+ */
+ protected $block_name = 'event-schedule';
+
+ /**
+ * Include and render the block
+ *
+ * @param array $attributes Block attributes. Default empty array
+ * @param string $content Block content. Default empty string
+ * @param WP_Block $block Block instance
+ *
+ * @return string Rendered block type output
+ */
+ protected function render($attributes, $content, $block)
+ {
+ $container_class = ! empty($attributes['containerClassName']) ? $attributes['containerClassName'] : '';
+ $styles = ! empty($attributes['styles']) ? $attributes['styles'] : [];
+ $style_variant = ! empty($attributes['styleVariant']) ? sanitize_key($attributes['styleVariant']) : 'style-1';
+
+ $allowed_variants = ['style-1', 'style-2', 'style-3', 'style-4', 'style-5'];
+ if (! in_array($style_variant, $allowed_variants, true)) {
+ $style_variant = 'style-1';
+ }
- if ($this->is_editor()) {
- $event_id = ! empty($attributes['eventId']) ? intval($attributes['eventId']) : 0;
+ if ($this->is_editor()) {
+ $event_id = ! empty($attributes['eventId']) ? intval($attributes['eventId']) : 0;
- if ($event_id == 0) {
- $template = new EventinTemplateTemplateModel(get_the_ID());
- $event_id = $template->get_preview_event_id();
- }
- } else if ('etn-template' == get_post_type(get_the_ID())) {
+ if ($event_id == 0) {
$template = new EventinTemplateTemplateModel(get_the_ID());
$event_id = $template->get_preview_event_id();
- } else {
- $event_id = get_the_ID();
}
+ } else if ('etn-template' == get_post_type(get_the_ID())) {
+ $template = new EventinTemplateTemplateModel(get_the_ID());
+ $event_id = $template->get_preview_event_id();
+ } else {
+ $event_id = get_the_ID();
+ }
- $event = new Event_Model($event_id);
- $event_location = $event->get_address();
+ $event = new Event_Model($event_id);
+ $event_location = $event->get_address();
- ob_start();
+ ob_start();
?>
<?php
// Generate CSS with !important to override SCSS
@@ -75,7 +75,7 @@
$frontend_css
);
}
- echo '<style>' . $frontend_css . '</style>';
+ echo '<style>' . $frontend_css . '</style>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS generated from block editor attributes; HTML escaping would break styles.
}
?>
<?php
--- a/wp-event-solution/core/Blocks/BlockTypes/EventSocial.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventSocial.php
@@ -51,7 +51,7 @@
ob_start();
?>
- <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); ?>
+ <?php echo $this->render_frontend_css( $styles, esc_attr( $container_class ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- CSS rendered by render_frontend_css(); script and style tags stripped by generate_frontend_css(). ?>
<?php
$style_template = Wpeventin::templates_dir() . 'event/parts/styles/event-social/' . $style_variant . '.php';
require $style_template;
--- a/wp-event-solution/core/Blocks/BlockTypes/EventSpeaker.php
+++ b/wp-event-solution/core/Blocks/BlockTypes/EventSpeaker.php
@@ -8,56 +8,56 @@
use Wpeventin;
/**
- * Event Venue Gutenberg block
- */
+ * Event Venue Gutenberg block
+ */
class EventSpeaker extends AbstractBlock
{
- /**
- * Block name.
- *
- * @var string
- */
-