speakers-for-the-events-cal.../README.md
Laurence Horrocks-Barlow fef0766e67 v1.0.1 — security hardening, TEC integration fixes, and documentation
Security:
- Validate CSV upload MIME type server-side via finfo
- Deliver import notices via per-user transient (prevents GET-param spoofing)
- Sanitise translatable success string with wp_kses to block HTML injection
- Switch sanitize_url to esc_url_raw; wp_kses_post to sanitize_textarea_field for plain-text bio

Bug fixes:
- Guard preg_replace null return in normalise_name() to prevent TypeError on PHP 8
- Replace generic save_post hook with save_post_tec_speaker / save_post_tribe_events
  so saves no longer need a manual revision check and cannot interact with TEC's own
  save_post handler at priority 15

TEC integration:
- Check for tribe-select2 / tribe-select2-css handles first (TEC ships SelectWoo,
  not vanilla Select2); CDN was previously always loaded unnecessarily
- Type-specific save hooks make event/speaker save paths explicit and independent

Improvements:
- Add register_activation_hook to flush rewrite rules on activation
- Wrap instantiation in plugins_loaded so TEC is guaranteed loaded first
- Show admin notice and skip TEC-specific hooks when TEC is inactive
- Cap event picker query at PICKER_LIMIT = 200 (was unbounded -1)
- Register front-end CSS via wp_add_inline_style on wp_enqueue_scripts
- absint() on speaker IDs in option value attributes

Documentation:
- Write full README.md (was blank)
- Add CHANGELOG.md with detailed 1.0.0 and 1.0.1 entries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 08:32:33 +01:00

98 lines
3.5 KiB
Markdown

# Speakers for The Events Calendar
A WordPress plugin that adds a Speaker custom post type to [The Events Calendar](https://theeventscalendar.com/), letting you create speaker profiles, attach them to events, display them on event pages, and bulk-import them from CSV.
## Requirements
| Requirement | Version |
|---|---|
| WordPress | 6.0+ |
| PHP | 8.0+ |
| The Events Calendar | Any current release |
## Features
- **Speaker CPT** — a dedicated `tec_speaker` post type with title, bio (editor), excerpt, featured image, website URL, and email fields.
- **Event speaker picker** — a searchable multi-select on every event edit screen, powered by SelectWoo (TEC's bundled library) with an automatic CDN fallback.
- **Front-end display** — speakers are rendered in a responsive card grid beneath the event meta block on single event pages.
- **`[tec_speakers]` shortcode** — display a filterable speaker archive anywhere on the site.
- **CSV bulk importer** — import speakers from a spreadsheet; duplicate names are skipped automatically.
## Installation
1. Upload the `speakers-for-the-events-calendar` folder to `/wp-content/plugins/`.
2. Activate through **Plugins → Installed Plugins**.
3. The Events Calendar must be installed and active; the plugin shows an admin notice if it is not.
## Usage
### Adding speakers
Go to **Speakers → Add New**. Fill in the title (speaker name), the bio in the editor, and optionally a website URL and email in the **Speaker Details** sidebar panel. Set a featured image for the speaker photo.
### Attaching speakers to an event
Open any event in the editor. A **Speakers** meta box appears in the main column. Type to search and click names to select; click again to deselect.
### Displaying speakers
Speakers are automatically displayed beneath the event meta block on single event pages — no configuration needed.
To display a speaker directory on any page or post, use the shortcode:
```
[tec_speakers]
[tec_speakers limit="20"]
[tec_speakers search="Jane"]
```
| Attribute | Default | Description |
|---|---|---|
| `limit` | `50` | Maximum number of speakers to display |
| `search` | _(empty)_ | Filter speakers by name or content |
### CSV import
Go to **Speakers → Import CSV**. The CSV must have a header row with these columns (order matters):
```
name, bio, email, website, image
```
| Column | Required | Notes |
|---|---|---|
| `name` | Yes | Speaker's full name |
| `bio` | No | Plain-text biography |
| `email` | No | Stored as private meta, not displayed publicly |
| `website` | No | Full URL including `https://` |
| `image` | No | Ignored — add photos via Featured Image after import |
Speakers whose name (ignoring common honorifics and extra whitespace) matches an existing speaker are skipped. No existing records are overwritten.
## Hooks
### Actions
| Hook | Description |
|---|---|
| `tribe_events_single_event_after_the_meta` | Where speakers are injected on single event pages |
### Filters
None currently. Open an issue if you need to customise output or query arguments.
## Data
| Meta key | Post type | Description |
|---|---|---|
| `_tec_event_speakers` | `tribe_events` | Array of `tec_speaker` post IDs attached to the event |
| `_tec_speaker_website` | `tec_speaker` | Speaker website URL |
| `_tec_speaker_email` | `tec_speaker` | Speaker contact email (private) |
## Changelog
See [CHANGELOG.md](CHANGELOG.md).
## License
GPLv2 or later. See [https://www.gnu.org/licenses/gpl-2.0.html](https://www.gnu.org/licenses/gpl-2.0.html).