, which mints the Woo product on the fly (RG_Cart). */ class RG_Storefront { static function init() { add_action('init', [__CLASS__, 'rewrites']); add_filter('query_vars', function ($v) { return array_merge($v, ['rg_view', 'rg_id']); }); add_action('template_redirect', [__CLASS__, 'render']); } static function rewrites() { add_rewrite_rule('^records/?$', 'index.php?rg_view=records', 'top'); add_rewrite_rule('^release/([0-9]+)/?', 'index.php?rg_view=release&rg_id=$matches[1]', 'top'); } static function render() { $view = get_query_var('rg_view'); if (!$view) return; if ($view === 'release') { $id = (int) get_query_var('rg_id'); $data = RG_API::get('/shop/release/' . $id, [], 120); if (!$data || empty($data['release'])) { self::not_found(); return; } self::head_for_release($data); get_header(); self::release_html($data); get_footer(); exit; } // browse $q = isset($_GET['q']) ? sanitize_text_field(wp_unslash($_GET['q'])) : ''; $genre = isset($_GET['genre']) ? sanitize_text_field(wp_unslash($_GET['genre'])) : ''; $page = max(1, (int) ($_GET['page'] ?? 1)); $args = array_filter(['q' => $q, 'genre' => $genre, 'page' => $page]); $data = RG_API::get('/shop/browse', $args, 60); self::head_for_browse($q, $genre); get_header(); self::browse_html($data ?: ['items' => [], 'total' => 0, 'page' => 1, 'per' => 24], $q, $genre, $page); get_footer(); exit; } // --- : title / description / JSON-LD -------------------------------- static function head_for_browse($q, $genre) { $title = trim(($q ?: $genre) ? ($q ?: $genre) . ' — Records' : 'Records') . ' · ' . get_bloginfo('name'); add_filter('pre_get_document_title', fn() => $title); add_action('wp_head', function () { echo '' . "\n"; }); } static function head_for_release($data) { $r = $data['release']; $copies = $data['copies']; $title = trim($r['artist'] . ' – ' . $r['title']) . ' · ' . get_bloginfo('name'); add_filter('pre_get_document_title', fn() => $title); add_action('wp_head', function () use ($r, $copies) { $price = $copies ? min(array_column($copies, 'price')) : null; $desc = trim(implode(' · ', array_filter([$r['artist'], $r['format'], $r['year'], $r['label']]))); echo '' . "\n"; $ld = [ '@context' => 'https://schema.org', '@type' => 'MusicAlbum', 'name' => $r['title'], 'byArtist' => ['@type' => 'MusicGroup', 'name' => $r['artist']], ]; if (!empty($r['thumb'])) $ld['image'] = $r['thumb']; if (!empty($r['genre'])) $ld['genre'] = $r['genre']; if ($price !== null) { $ld['offers'] = [ '@type' => 'Offer', 'priceCurrency' => 'AUD', 'price' => $price, 'availability' => $copies ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock', 'url' => home_url('/release/' . $r['id']), ]; } echo '' . "\n"; }); } // --- body ----------------------------------------------------------------- static function browse_html($d, $q, $genre, $page) { $heading = $q ?: ($genre ?: 'Records'); echo '
'; echo '
'; echo '
'; echo '

' . esc_html($heading) . ' (' . (int) $d['total'] . ')

'; if (!$d['items']) { echo '

Nothing in stock matching that.

'; return; } echo '
'; foreach ($d['items'] as $it) { $url = home_url('/release/' . (int) $it['release_id']); echo ''; if (!empty($it['thumb'])) echo '' . esc_attr($it['title']) . ''; echo '
' . esc_html($it['title']) . '
'; echo '
' . esc_html($it['artist']) . '
'; echo '
$' . esc_html(number_format((float) $it['price'], 2)); if ((int) $it['copies'] > 1) echo ' · ' . (int) $it['copies'] . ' copies'; echo '
'; } echo '
'; self::pager($d, $page, $q, $genre); echo ''; } static function pager($d, $page, $q, $genre) { $pages = (int) ceil($d['total'] / max(1, $d['per'])); if ($pages <= 1) return; $link = fn($p) => esc_url(add_query_arg(array_filter(['q' => $q, 'genre' => $genre, 'page' => $p]), home_url('/records'))); echo '
'; if ($page > 1) echo '← Prev '; echo 'Page ' . $page . ' of ' . $pages . ''; if ($page < $pages) echo 'Next →'; echo '
'; } static function release_html($data) { $r = $data['release']; echo '
'; echo '

← Records

'; echo '
'; if (!empty($r['thumb'])) echo '' . esc_attr($r['title']) . ''; echo '
'; echo '

' . esc_html($r['title']) . '

'; echo '

' . esc_html($r['artist']) . '

'; foreach (['label' => 'Label', 'format' => 'Format', 'country' => 'Country', 'year' => 'Year', 'genre' => 'Genre', 'style' => 'Style'] as $k => $lbl) if (!empty($r[$k])) echo '
' . $lbl . ': ' . esc_html($r[$k]) . '
'; echo '

In stock

'; if (empty($data['copies'])) { echo '

No copies in stock right now.

'; } else { echo '
    '; foreach ($data['copies'] as $c) { $cond = trim(implode(' / ', array_filter([$c['condition'], $c['sleeve_cond'] ?? null]))); echo '
  • '; echo '$' . esc_html(number_format((float) $c['price'], 2)); if ($cond) echo ' · ' . esc_html($cond) . ''; echo ''; echo 'Add to cart'; echo '
  • '; } echo '
'; } echo '
'; if (!empty($data['tracks'])) { echo '

Tracklist

    '; foreach ($data['tracks'] as $t) { echo '
  1. ' . esc_html($t['title']); if (!empty($t['duration'])) echo ' ' . esc_html($t['duration']) . ''; echo '
  2. '; } echo '
'; } echo '
'; } static function not_found() { status_header(404); get_header(); echo '

Record not found

' . '

Browse the shop →

'; get_footer(); exit; } }