Skip to content

Commit 64ce1c2

Browse files
feat(event-submission): URL-based artist tour import — auto-create artist-scoped pipeline (#322)
Implements the DME side of extrachill-events#320. Adds a moderation queue (`artist_url_submissions` under $wpdb->base_prefix), four abilities, four REST routes, and an admin moderation screen. Abilities (`inc/Abilities/ArtistUrlImportAbilities.php`): - `data-machine-events/preview-artist-url` — non-destructive probe via UniversalWebScraper. Returns detected format, event count, preview list, and a suggested artist (term ID if a similar_text fuzzy match clears 85%, name otherwise). Logged-in users only. - `data-machine-events/submit-artist-url` — re-probes server-side (never trusts client detection) and inserts a row in `pending_review` (or `scraping_failed`). Logged-in users only. - `data-machine-events/approve-artist-url-submission` — admin only. Resolves the artist term (existing id, new name + wp_insert_term, or the submission's suggested term). Creates pipeline+flow via `datamachine/create-pipeline` + `datamachine/create-flow` mirroring the CityAbilities pattern, with universal_web_scraper handler. Triggers an immediate first run via `datamachine/run-flow`. - `data-machine-events/reject-artist-url-submission` — admin only. Marks the row rejected with an optional reason. SelectionMode alignment: the upsert step pins `taxonomy_artist_selection = (string) $artist_term_id` (PRE_SELECTED) and uses `SelectionMode::AI_DECIDES` constants by class reference for venue/location/festival, `SelectionMode::SKIP` for promoter, category, post_tag — no bare strings (#320 requirement). Dedupe: SHA-256 over a normalized URL (lowercased scheme/host, fragment stripped, trailing slash trimmed except root, default ports removed). UNIQUE KEY on url_hash; duplicate preview/submit returns `url_already_tracked`. REST: `POST /wp-json/datamachine/v1/artist-url/{preview,submit, {id}/approve,{id}/reject}`. Preview and submit reject direct-browser navigations (no XHR / JSON Accept header → 404), in the spirit of Admin moderation UI (`inc/Admin/ArtistUrlSubmissionsAdmin.php`): adds "Artist URL Imports" under Events. Tabs filter by status (pending review, approved, rejected, failed scrapes), inline forms for approve (artist term id OR new name + schedule) and reject (reason). Forms post to admin-post.php with nonces and delegate to the abilities. Tests (`tests/Unit/ArtistUrlSubmissionsTableTest.php`, `tests/Unit/ArtistUrlImportAbilitiesTest.php`): URL normalization, url_hash dedupe, table CRUD, preview/submit rejection paths, `artist_required` error from approve when no artist input is provided, reject sets status + reason. Approve's pipeline-creation integration is covered by curl verification against a live install (matrix in the PR body) — recreating Data Machine core abilities in isolated unit tests would be fake coverage. The extrachill-events side (form change consuming preview + submit abilities) ships separately once this merges. Co-authored-by: homeboy-ci[bot] <266378653+homeboy-ci[bot]@users.noreply.github.com>
1 parent cbd7571 commit 64ce1c2

8 files changed

Lines changed: 2547 additions & 0 deletions

data-machine-events.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ function data_machine_events_sanitize_query_params( $value ) {
6262
require_once DATA_MACHINE_EVENTS_PLUGIN_DIR . 'inc/Core/event-dates-sync.php';
6363
require_once DATA_MACHINE_EVENTS_PLUGIN_DIR . 'inc/Core/EventDatesTable.php';
6464

65+
// Artist URL Submissions table (moderation queue for the #320 import flow).
66+
require_once DATA_MACHINE_EVENTS_PLUGIN_DIR . 'inc/Core/ArtistUrlSubmissionsTable.php';
67+
add_action( 'plugins_loaded', array( \DataMachineEvents\Core\ArtistUrlSubmissionsTable::class, 'maybe_install' ), 20 );
68+
6569
// Global alias — event-dates-sync.php is namespaced so this makes the public API accessible globally.
6670
if ( ! function_exists( 'datamachine_get_event_dates' ) ) {
6771
/**
@@ -234,6 +238,11 @@ public function init() {
234238
if ( class_exists( 'DataMachineEvents\\Admin\\Settings_Page' ) ) {
235239
new \DataMachineEvents\Admin\Settings_Page();
236240
}
241+
242+
// Artist URL Submissions moderation queue (extrachill-events#320).
243+
if ( class_exists( 'DataMachineEvents\\Admin\\ArtistUrlSubmissionsAdmin' ) ) {
244+
new \DataMachineEvents\Admin\ArtistUrlSubmissionsAdmin();
245+
}
237246
}
238247

239248
add_action( 'init', array( $this, 'init_data_machine_integration' ), 25 );
@@ -484,6 +493,11 @@ function ( array $templates ): array {
484493
new \DataMachineEvents\Abilities\MergedBillDecideAbilities();
485494
}
486495

496+
if ( file_exists( DATA_MACHINE_EVENTS_PLUGIN_DIR . 'inc/Abilities/ArtistUrlImportAbilities.php' ) ) {
497+
require_once DATA_MACHINE_EVENTS_PLUGIN_DIR . 'inc/Abilities/ArtistUrlImportAbilities.php';
498+
new \DataMachineEvents\Abilities\ArtistUrlImportAbilities();
499+
}
500+
487501
// Chat tools for the merged-bill agent decision step (issue #256).
488502
if ( class_exists( 'DataMachineEvents\\Api\\Chat\\Tools\\MergedBillInspect' ) ) {
489503
new \DataMachineEvents\Api\Chat\Tools\MergedBillInspect();
@@ -606,6 +620,7 @@ public function enqueue_admin_assets( $hook ) {
606620

607621
public function activate() {
608622
\DataMachineEvents\Core\EventDatesTable::create_table();
623+
\DataMachineEvents\Core\ArtistUrlSubmissionsTable::create_table();
609624
$this->register_post_types();
610625
$this->register_taxonomies();
611626
flush_rewrite_rules();

0 commit comments

Comments
 (0)