24 Commits

Author SHA1 Message Date
894109ae6c bump version
Some checks failed
Release Plugin Zip / release (push) Has been cancelled
2026-03-31 21:53:37 -05:00
569d11ac1a Add SportsPress schedule exporter 2026-03-31 21:51:20 -05:00
e019bf2061 Add configurable printable venue labels 2026-03-29 09:32:41 -05:00
d2ff863ca5 Add printable calendars feature 2026-03-27 16:22:44 -05:00
785f617134 Fix Games admin filter links 2026-03-27 16:02:56 -05:00
910cc8905e bump version 2026-03-26 21:33:12 -05:00
723b90be52 Improve SportsPress event admin filter controls and team/result ordering
Some checks failed
Release Plugin Zip / release (push) Has been cancelled
2026-03-26 20:11:45 -05:00
e3d9c677c1 Consolidate team ordering and add explicit away-first settings 2026-03-26 20:11:45 -05:00
344a00cf82 bump version
Some checks failed
Release Plugin Zip / release (push) Has been cancelled
2026-03-24 19:27:23 -05:00
8f741f8f00 Add CSV feed 2026-03-24 19:26:25 -05:00
e4a596b479 ignore data folder 2026-03-24 19:19:59 -05:00
5f0622c052 version v0.1.3
All checks were successful
Release Plugin Zip / release (push) Successful in 4s
2026-02-17 15:33:24 -06:00
e1b3abbfb0 add officials to quick edit menu 2026-02-17 15:32:39 -06:00
2623fbf7f2 Merge branch 'github-main'
All checks were successful
Release Plugin Zip / release (push) Successful in 4s
2026-02-17 15:24:08 -06:00
0696d821b5 version 0.1.2 2026-02-17 15:23:48 -06:00
cb05d53522 add week filter 2026-02-17 15:22:48 -06:00
e0af498a3f add github actions 2026-02-17 15:22:12 -06:00
00f7b7979e add week filter
All checks were successful
Release Plugin Zip / release (push) Successful in 3s
2026-02-17 15:16:40 -06:00
9fbce23828 add github actions 2026-02-17 15:16:37 -06:00
d62b1a746b typo 2025-06-06 12:24:36 -05:00
f59273d788 rename readme as markdwon, update manifest 2025-06-06 12:22:33 -05:00
377cdbffb0 update readme and version 2025-06-06 12:19:40 -05:00
d3f4951fd8 Merge branch 'open-graph-tags' 2025-06-06 12:10:42 -05:00
d2ddf227fd Improve Open Graph metadata for sports events
- Added `asc_generate_sp_event_title()` to format event titles using team names.
- Added `asc_generate_short_date()` for consistent date/time representation.
- Refined title/description to reflect event status (postponed, cancelled, etc.) and venue.
- Handled special outcomes like Technical Forfeit or Forfeit in title.
2025-06-06 12:09:30 -05:00
20 changed files with 6749 additions and 140 deletions

37
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: Release Plugin Zip
on:
push:
tags:
- "v*"
permissions:
contents: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build plugin zip
id: build
run: |
set -euo pipefail
PLUGIN_SLUG="${GITHUB_REPOSITORY##*/}"
TAG="${GITHUB_REF_NAME}"
ZIP_NAME="${PLUGIN_SLUG}-${TAG}.zip"
mkdir -p dist
git archive --format=zip --prefix="${PLUGIN_SLUG}/" -o "dist/${ZIP_NAME}" HEAD
echo "zip_path=dist/${ZIP_NAME}" >> "$GITHUB_OUTPUT"
echo "zip_name=${ZIP_NAME}" >> "$GITHUB_OUTPUT"
- name: Create or update release and upload zip
uses: softprops/action-gh-release@v2
with:
files: ${{ steps.build.outputs.zip_path }}
fail_on_unmatched_files: true

1
.gitignore vendored
View File

@@ -7,3 +7,4 @@ node_modules/
*.sql
*.tar.gz
*.zip
data

503
assets/print-calendar.css Normal file
View File

@@ -0,0 +1,503 @@
@import url("https://fonts.googleapis.com/css2?family=Nunito+Sans:opsz,wdth,wght@6..12,75..125,600..900&family=Open+Sans:wght@400..800&display=swap");
:root {
--pc-font-body: "Open Sans", Arial, sans-serif;
--pc-font-display: "Nunito Sans", "Open Sans", Arial, sans-serif;
--pc-page-padding: 0.45in;
--pc-gap: 8px;
--pc-border: #d5dde6;
--pc-preview-bg: #d9dce3;
--pc-team-logo-size: clamp(40px, 5vw, 56px);
--pc-brand-logo-height: clamp(40px, 5vw, 56px);
--pc-brand-logo-max-width: 34%;
--pc-muted-day-bg: rgba(243, 245, 248, 0.72);
--pc-empty-day-bg: rgba(233, 237, 242, 0.72);
--pc-event-logo-height: clamp(28px, 100%, 74px);
--pc-qr-size: 50px;
--pc-qr-offset: calc(var(--pc-qr-size) + var(--pc-gap));
}
body {
margin: 0;
padding: 20px;
font-family: var(--pc-font-body);
color: #111;
background: #fff;
}
.print-shell {
margin: 0;
width: calc(100% / var(--sheet-scale));
background: #fff;
transform-origin: top left;
transform: scale(var(--sheet-scale));
}
.print-page {
padding: var(--pc-page-padding);
}
@media screen {
body.print-preview {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: flex-start;
padding: 24px;
background: var(--pc-preview-bg);
}
body.print-preview .print-shell {
box-shadow: 0 10px 30px rgba(17, 24, 39, 0.2);
}
body.print-preview .print-shell.letter {
width: 8.5in;
min-height: 11in;
}
body.print-preview .print-shell.ledger {
width: 11in;
min-height: 17in;
}
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
margin: 0 0 12px;
padding-bottom: 8px;
border-bottom: 2px solid var(--team-accent, #b61f0f);
}
.header-brand {
display: flex;
align-items: center;
gap: 10px;
min-width: 0;
}
.team-logo,
.league-logo {
display: inline-flex;
align-items: center;
justify-content: center;
flex: 0 0 auto;
}
.team-logo {
width: var(--pc-team-logo-size);
height: var(--pc-team-logo-size);
}
.team-logo img,
.team-logo-img {
width: 100%;
height: 100%;
display: block;
object-fit: contain;
}
.league-logo {
height: var(--pc-brand-logo-height);
max-width: var(--pc-brand-logo-max-width);
}
.league-logo a,
.league-logo .custom-logo-link,
.league-logo .wp-block-site-logo__link {
height: 100%;
display: inline-flex;
align-items: center;
justify-content: center;
}
.league-logo img,
.league-logo-img,
.league-logo .custom-logo,
.league-logo .wp-block-site-logo__image {
width: auto;
height: 100%;
max-width: 100%;
display: block;
object-fit: contain;
}
.header-copy {
min-width: 0;
}
.title {
margin: 0;
font-family: var(--pc-font-display);
font-size: 28px;
font-weight: 800;
font-variation-settings: "wdth" 92, "wght" 800;
line-height: 1.1;
color: var(--team-ink, #111);
}
.meta {
margin: 0;
font-size: 13px;
color: var(--team-muted-ink, #333);
}
.legend {
display: flex;
flex-wrap: wrap;
gap: var(--pc-gap);
margin: 0;
}
.legend-item {
display: inline-flex;
align-items: center;
font-family: var(--pc-font-display);
font-variation-settings: "wdth" 70, "wght" 700;
background: #fff;
}
.sheet-grid {
display: grid;
grid-template-columns: repeat(var(--month-columns), minmax(0, 1fr));
gap: var(--pc-gap);
align-items: start;
}
.sheet-grid > .month:nth-child(3):last-child {
grid-column: 1 / -1;
width: calc((100% - var(--pc-gap)) / 2);
max-width: calc((100% - var(--pc-gap)) / 2);
justify-self: center;
}
.month {
margin: 0;
break-inside: avoid;
page-break-inside: avoid;
}
.month-title {
margin: 0;
padding: 2px;
font-family: var(--pc-font-display);
font-size: calc(20px * var(--month-font-scale));
font-weight: 800;
font-variation-settings: "wdth" 80, "wght" 800;
line-height: 1.1;
letter-spacing: 0.01em;
text-align: center;
text-transform: uppercase;
background: var(--team-primary);
color: var(--team-on-primary);
}
.dow,
.grid {
display: grid;
grid-template-columns: repeat(7, minmax(0, 1fr));
}
.dow span {
display: block;
padding: 2px 1px;
font-size: calc(10px * var(--month-font-scale));
font-weight: 700;
text-align: center;
text-transform: uppercase;
border-bottom: 1px solid var(--pc-border);
background: var(--team-link-color);
color: var(--team-on-link-color);
}
.day {
--corner-badge-size: calc(15px * var(--month-font-scale));
--corner-badge-offset: 0px;
position: relative;
overflow: hidden;
aspect-ratio: var(--day-aspect);
background: #fff;
}
.day.muted {
background: var(--pc-muted-day-bg);
color: #9aa5b1;
}
.day.no-events {
background: var(--pc-empty-day-bg);
}
.day-num {
position: absolute;
top: var(--corner-badge-offset);
left: var(--corner-badge-offset);
z-index: 4;
width: var(--corner-badge-size);
height: var(--corner-badge-size);
display: flex;
align-items: center;
justify-content: center;
font-family: var(--pc-font-display);
font-size: calc(12px * var(--month-font-scale));
font-weight: 800;
font-variation-settings: "wdth" 86, "wght" 800;
line-height: 1;
}
.day.has-events .day-num {
color: var(--day-num-color, #fff);
}
.events-stack {
height: 100%;
display: grid;
grid-template-rows: repeat(var(--event-count), minmax(0, 1fr));
}
.event {
--event-top-band: calc(var(--corner-badge-size, 11px) + var(--corner-badge-offset, 2px));
--event-bottom-band: 26px;
--event-logo-height: var(--pc-event-logo-height);
position: relative;
background: var(--event-bg, var(--team-primary, #1b76d1));
color: var(--event-fg, #fff);
}
.event.h {
--event-bg: var(--team-primary, #1b76d1);
}
.event.a {
--event-bg: var(--team-link-color, var(--team-secondary, #8b3f1f));
}
.event-center {
position: absolute;
top: var(--event-top-band);
left: 0;
right: 0;
bottom: var(--event-bottom-band);
z-index: 1;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
width: 100%;
font-size: calc(10px * var(--month-font-scale));
font-weight: 700;
line-height: 1;
text-align: center;
}
.event-center img {
width: auto;
height: var(--event-logo-height);
max-width: 100%;
max-height: 100%;
display: block;
object-fit: contain;
object-position: center;
}
.event-name {
width: 100%;
max-width: 100%;
max-height: 100%;
overflow: hidden;
text-overflow: clip;
white-space: normal;
word-break: normal;
overflow-wrap: normal;
hyphens: none;
line-height: 1.05;
font-weight: 700;
opacity: 0.85;
}
.event.no-logo .event-name {
font-family: var(--pc-font-display);
font-weight: 700;
font-variation-settings: "wdth" 30, "wght" 700;
letter-spacing: -0.01em;
text-transform: uppercase;
}
.ha-flag {
position: absolute;
top: var(--corner-badge-offset, 2px);
right: var(--corner-badge-offset, 2px);
z-index: 3;
width: var(--corner-badge-size, 11px);
height: var(--corner-badge-size, 11px);
display: flex;
align-items: center;
justify-content: center;
font-family: var(--pc-font-display);
font-size: calc(10px * var(--month-font-scale));
font-weight: 900;
font-variation-settings: "wdth" 84, "wght" 900;
line-height: 1;
letter-spacing: -0.01em;
background: #111;
color: #fff;
}
.event.a .ha-flag {
background: #fff;
color: #111;
}
.event-meta {
position: absolute;
left: 0;
right: 0;
bottom: 2px;
z-index: 3;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
gap: 1px;
padding: 0 2px;
overflow: hidden;
}
.event-time {
order: 1;
max-width: 100%;
font-size: calc(12px * var(--month-font-scale));
font-weight: 800;
line-height: 1;
text-transform: uppercase;
text-align: center;
color: currentColor;
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
opacity: 0.95;
}
.event-venue {
order: 2;
max-width: 100%;
font-size: calc(8px * var(--month-font-scale));
font-weight: 700;
line-height: 1;
text-align: center;
text-transform: uppercase;
white-space: nowrap;
overflow: hidden;
text-overflow: clip;
opacity: 0.88;
}
.empty {
padding: 16px;
border: 2px dashed #c8d2de;
background: #f8fafc;
}
.footer-meta {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: var(--pc-gap);
margin-top: 10px;
padding-top: 8px;
border-top: 1px solid var(--pc-border);
}
.legend-bottom {
--month-width: calc((100% - ((var(--month-columns) - 1) * var(--pc-gap))) / var(--month-columns));
flex: 0 0 var(--month-width);
width: var(--month-width);
max-width: var(--month-width);
align-content: flex-start;
justify-content: center;
gap: 6px;
}
.legend-bottom .legend-item {
padding: 3px 6px;
font-size: 10px;
text-align: center;
}
.footer-qr {
position: relative;
flex: 0 0 auto;
display: flex;
align-items: flex-end;
justify-content: flex-end;
gap: var(--pc-gap);
min-height: var(--pc-qr-size);
padding-right: var(--pc-qr-offset);
}
.footer-qr-copy {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 2px;
text-align: right;
}
.footer-qr-label {
font-size: 9px;
font-weight: 700;
letter-spacing: 0.02em;
text-transform: uppercase;
color: var(--team-muted-ink, #333);
}
.footer-qr-link {
font-size: 10px;
font-weight: 700;
text-decoration: none;
color: var(--team-ink, #111);
}
.footer-qr-image {
position: absolute;
right: 0;
bottom: 0;
width: var(--pc-qr-size);
height: var(--pc-qr-size);
display: block;
border: 1px solid var(--pc-border);
background: #fff;
}
@media print {
body,
body.print-preview {
padding: 0;
display: block;
background: #fff;
}
.print-shell,
body.print-preview .print-shell,
body.print-preview .print-shell.letter,
body.print-preview .print-shell.ledger {
width: auto;
min-height: auto;
box-shadow: none;
}
.print-page {
padding: 0;
}
.header {
margin-bottom: 8px;
}
.title {
font-size: calc(26px * var(--month-font-scale));
}
}

View File

@@ -0,0 +1,27 @@
( function ( blocks, blockEditor, element, i18n ) {
var el = element.createElement;
var useBlockProps = blockEditor.useBlockProps;
var __ = i18n.__;
blocks.registerBlockType( 'tse/schedule-exporter', {
edit: function () {
var blockProps = useBlockProps( {
className: 'tse-schedule-exporter-block-placeholder',
} );
return el(
'div',
blockProps,
el( 'strong', null, __( 'Schedule Exporter', 'tonys-sportspress-enhancements' ) ),
el(
'p',
null,
__( 'This block renders the public schedule exporter on the frontend.', 'tonys-sportspress-enhancements' )
)
);
},
save: function () {
return null;
},
} );
} )( window.wp.blocks, window.wp.blockEditor, window.wp.element, window.wp.i18n );

View File

@@ -8,6 +8,55 @@ Author: Your Name
add_action('wp_head', 'custom_open_graph_tags_with_sportspress_integration');
function asc_generate_sp_event_title( $post ) {
// See https://github.com/ThemeBoy/SportsPress/blob/770fa8c6654d7d6648791e877709c2428677635b/includes/admin/post-types/class-sp-admin-cpt-event.php#L99C40-L99C55
if ( is_numeric( $post ) ) {
$post = get_post( $post );
}
if ( ! $post || $post->post_type !== 'sp_event' ) {
return get_the_title();
}
$teams = get_post_meta( $post->ID, 'sp_team', false );
$teams = array_filter( $teams );
$team_names = array();
foreach ( $teams as $team ) {
while ( is_array( $team ) ) {
$team = array_shift( array_filter( $team ) );
}
if ( $team > 0 ) {
$team_names[] = sp_team_short_name( $team );
}
}
$team_names = array_unique( $team_names );
if ( get_option( 'sportspress_event_reverse_teams', 'no' ) === 'yes' ) {
$team_names = array_reverse( $team_names );
}
$delimiter = ' ' . get_option( 'sportspress_event_teams_delimiter', 'vs' ) . ' ';
return implode( $delimiter, $team_names );
}
function asc_generate_short_date( $post, $withTime = true ) {
$formatted_date = get_the_date('D n/j/y', $post);
if (!$withTime){
return $formatted_date;
}
if ( get_the_date('i', $post) == "00") {
$formatted_time = get_the_date('gA', $post);
} else {
$formatted_time = get_the_date('g:iA', $post);
}
return $formatted_date . " " . $formatted_time ;
}
function custom_open_graph_tags_with_sportspress_integration() {
if (is_single()) {
global $post;
@@ -18,16 +67,22 @@ function custom_open_graph_tags_with_sportspress_integration() {
// Fetch details using SP_Event methods
$publish_date = get_the_date('F j, Y', $post);
$venue_terms = get_the_terms($post->ID, 'sp_venue');
$venue_name = $venue_terms ? $venue_terms[0]->name : 'No Venue Specified';
$venue_name = $venue_terms ? $venue_terms[0]->name : 'Venue TBD';
$results = $event->results(); // Using SP_Event method
$title = get_the_title() . " " . "(" . $publish_date . ")";
$title = asc_generate_sp_event_title($post);
$sp_status = get_post_meta( $post->ID, 'sp_status', true );
$status = $event->status(); // Using SP_Event method
$publish_date_and_time = get_the_date('F j, Y g:i A', $post);
$description = "{$publish_date_and_time} at {$venue_name}.";
if ( 'postponed' == $sp_status ) {
$description = "POSTPONED" . " - " . $description;
$title = "POSTPONED" . " - " . $title;
if ( 'postponed' == $sp_status || 'cancelled' == $sp_status || 'tbd' == $sp_status) {
$description = strtoupper($sp_status) . " " . $description;
$title = strtoupper($sp_status) . "" . $title . "" . asc_generate_short_date($post) . "" . $venue_name;
}
if ( 'future' == $status ) {
$description = $description;
$title = $title . "" . asc_generate_short_date($post) . "" . $venue_name;
}
if ( 'results' == $status ) { // checks if there is a final score
@@ -76,6 +131,7 @@ function custom_open_graph_tags_with_sportspress_integration() {
unset( $result['outcome'] );
$team_name = sp_team_short_name( $team_id );
$team_abbreviation = sp_team_abbreviation( $team_id );
$outcome_abbreviation = get_post_meta( $the_outcome->ID, 'sp_abbreviation', true );
if ( ! $outcome_abbreviation ) {
@@ -87,15 +143,37 @@ function custom_open_graph_tags_with_sportspress_integration() {
"outcome" => $the_outcome->post_title,
"outcome_abbreviation" => $outcome_abbreviation,
"team_name" => $team_name,
"team_abbreviation" => $team_abbreviation
]
);
$i++;
endforeach;
$publish_date = get_the_date('F j, Y', $post);
$title = "{$teams_result_array[0]['team_name']} {$teams_result_array[0]['result']['r']}-{$teams_result_array[1]['result']['r']} {$teams_result_array[1]['team_name']} ({$publish_date})";
$description .= " " . "{$teams_result_array[0]['team_name']} ({$teams_result_array[0]['outcome']}), {$teams_result_array[1]['team_name']} ({$teams_result_array[1]['outcome']}).";;
$publish_date = asc_generate_short_date($post, false);
$special_result_suffix_abbreviation = '';
$special_result_suffix= '';
foreach ( $teams_result_array as $team ) {
$outcome_abbreviation = strtoupper( $team['outcome_abbreviation'] ); // Normalize case
if ( $outcome_abbreviation === 'TF-W' ) {
$special_result_suffix_abbreviation = 'TF-W';
$special_result_suffix = 'Technical Forfeit Win';
break;
} elseif ( $outcome_abbreviation === 'TF-L' ) {
$special_result_suffix_abbreviation = 'TF';
$special_result_suffix = 'Technical Forfeit';
break;
} elseif ( $outcome_abbreviation === 'F-W' || $outcome_abbreviation === 'F-L' ) {
$special_result_suffix_abbreviation = 'Forfeit';
$special_result_suffix = 'Forfeit';
break;
}
}
$title = "{$teams_result_array[0]['team_name']} {$teams_result_array[0]['result']['r']}-{$teams_result_array[1]['result']['r']} {$teams_result_array[1]['team_name']}{$publish_date}" . ($special_result_suffix ? "({$special_result_suffix_abbreviation})" : "");
$description .= " " . "{$teams_result_array[0]['team_name']} ({$teams_result_array[0]['outcome']}), {$teams_result_array[1]['team_name']} ({$teams_result_array[1]['outcome']})." ;
}
$description .= " " . $post->post_content;
$image = get_site_url() . "/head-to-head?post={$post->ID}";
echo '<meta property="og:type" content="article" />' . "\n";

View File

@@ -0,0 +1,418 @@
<?php
/**
* Admin week filter for SportsPress events.
*
* Adds a week selector in wp-admin for `sp_event` and filters events by
* Monday-start week (Monday 00:00:00 through Sunday 23:59:59).
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Screen-option defaults for event list filters.
*
* @return array<string, bool>
*/
function tony_sportspress_event_filter_defaults() {
return array(
'month' => true,
'week' => true,
'team' => true,
'venue' => true,
'league' => true,
'season' => true,
'match_day' => true,
);
}
/**
* Build user meta key for an event filter screen option.
*
* @param string $key Filter key.
* @return string
*/
function tony_sportspress_event_filter_meta_key( $key ) {
return 'tony_sp_event_filter_' . $key;
}
/**
* Check whether a filter is enabled for the current user.
*
* @param string $key Filter key.
* @return bool
*/
function tony_sportspress_event_filter_enabled( $key ) {
$defaults = tony_sportspress_event_filter_defaults();
if ( ! array_key_exists( $key, $defaults ) ) {
return true;
}
$user_id = get_current_user_id();
if ( ! $user_id ) {
return (bool) $defaults[ $key ];
}
$stored = get_user_meta( $user_id, tony_sportspress_event_filter_meta_key( $key ), true );
if ( '' === $stored ) {
return (bool) $defaults[ $key ];
}
return '1' === (string) $stored;
}
/**
* Persist event filter Screen Options via AJAX.
*/
function tony_sportspress_save_event_filter_screen_options_ajax() {
if ( ! current_user_can( 'edit_posts' ) ) {
wp_send_json_error();
}
check_ajax_referer( 'tony_sp_event_filters', 'nonce' );
$defaults = tony_sportspress_event_filter_defaults();
$filters = isset( $_POST['filters'] ) && is_array( $_POST['filters'] ) ? $_POST['filters'] : array();
$user_id = get_current_user_id();
foreach ( $defaults as $key => $_enabled ) {
$value = isset( $filters[ $key ] ) ? sanitize_text_field( wp_unslash( $filters[ $key ] ) ) : '0';
update_user_meta( $user_id, tony_sportspress_event_filter_meta_key( $key ), '1' === $value ? '1' : '0' );
}
wp_send_json_success();
}
add_action( 'wp_ajax_tony_sp_event_filter_prefs_save', 'tony_sportspress_save_event_filter_screen_options_ajax' );
/**
* Add filter visibility toggles to Screen Options on event list admin page.
*
* @param string $settings Existing settings HTML.
* @param WP_Screen $screen Current screen.
* @return string
*/
function tony_sportspress_event_filter_screen_options_markup( $settings, $screen ) {
if ( ! $screen || 'edit-sp_event' !== $screen->id ) {
return $settings;
}
$labels = array(
'month' => __( 'Month/Year', 'tonys-sportspress-enhancements' ),
'week' => __( 'Week', 'tonys-sportspress-enhancements' ),
'team' => __( 'Team', 'tonys-sportspress-enhancements' ),
'venue' => __( 'Venue', 'tonys-sportspress-enhancements' ),
'league' => __( 'League', 'tonys-sportspress-enhancements' ),
'season' => __( 'Season', 'tonys-sportspress-enhancements' ),
'match_day' => __( 'Match Day', 'tonys-sportspress-enhancements' ),
);
$settings .= '<fieldset class="metabox-prefs">';
$settings .= '<legend>' . esc_html__( 'Event Filters', 'tonys-sportspress-enhancements' ) . '</legend>';
foreach ( $labels as $key => $label ) {
$meta_key = tony_sportspress_event_filter_meta_key( $key );
$checked = tony_sportspress_event_filter_enabled( $key ) ? ' checked="checked"' : '';
$settings .= '<label for="' . esc_attr( $meta_key ) . '">';
$settings .= '<input type="checkbox" id="' . esc_attr( $meta_key ) . '" name="' . esc_attr( $meta_key ) . '" value="1"' . $checked . ' />';
$settings .= esc_html( $label );
$settings .= '</label>';
}
$settings .= '</fieldset>';
return $settings;
}
add_filter( 'screen_settings', 'tony_sportspress_event_filter_screen_options_markup', 10, 2 );
/**
* Parse an ISO week input (e.g. 2026-W07) from the request.
*
* @return array{year:int,week:int}|null
*/
function tony_sportspress_parse_admin_week_filter() {
if ( empty( $_GET['sp_week_filter'] ) ) {
return null;
}
$raw = sanitize_text_field( wp_unslash( $_GET['sp_week_filter'] ) );
if ( ! preg_match( '/^(\d{4})-W(0[1-9]|[1-4][0-9]|5[0-3])$/', $raw, $matches ) ) {
return null;
}
$year = (int) $matches[1];
$week = (int) $matches[2];
return array(
'year' => $year,
'week' => $week,
);
}
/**
* Render week filter control in event admin list.
*
* @param string $post_type Current post type.
*/
function tony_sportspress_render_admin_week_filter( $post_type ) {
if ( 'sp_event' !== $post_type ) {
return;
}
if ( ! tony_sportspress_event_filter_enabled( 'week' ) ) {
return;
}
$value = '';
if ( ! empty( $_GET['sp_week_filter'] ) ) {
$value = sanitize_text_field( wp_unslash( $_GET['sp_week_filter'] ) );
}
$summary_text = __( 'Select a week', 'tonys-sportspress-enhancements' );
$parsed = tony_sportspress_parse_admin_week_filter();
if ( is_array( $parsed ) ) {
$timezone = wp_timezone();
$monday = ( new DateTimeImmutable( 'now', $timezone ) )->setISODate( $parsed['year'], $parsed['week'], 1 )->setTime( 0, 0, 0 );
$sunday = $monday->modify( '+6 days' )->setTime( 23, 59, 59 );
/* translators: 1: Monday label/date, 2: Sunday label/date. */
$summary_text = sprintf(
__( '%1$s to %2$s', 'tonys-sportspress-enhancements' ),
wp_date( 'D M j, Y', $monday->getTimestamp(), $timezone ),
wp_date( 'D M j, Y', $sunday->getTimestamp(), $timezone )
);
}
?>
<label for="sp_week_filter" class="screen-reader-text"><?php esc_html_e( 'Filter by week', 'tonys-sportspress-enhancements' ); ?></label>
<input
type="week"
id="sp_week_filter"
name="sp_week_filter"
class="sp-week-filter-field"
value="<?php echo esc_attr( $value ); ?>"
title="<?php esc_attr_e( 'Week (Monday start)', 'tonys-sportspress-enhancements' ); ?>"
/>
<span id="sp-week-filter-summary" class="sp-week-filter-summary"><?php echo esc_html( $summary_text ); ?></span>
<?php
}
add_action( 'restrict_manage_posts', 'tony_sportspress_render_admin_week_filter' );
/**
* Add responsive admin styles so filters stay visible on narrow widths.
*/
function tony_sportspress_admin_week_filter_styles() {
$screen = get_current_screen();
if ( ! $screen || 'edit-sp_event' !== $screen->id ) {
return;
}
$hide = array(
'month' => ! tony_sportspress_event_filter_enabled( 'month' ),
'team' => ! tony_sportspress_event_filter_enabled( 'team' ),
'venue' => ! tony_sportspress_event_filter_enabled( 'venue' ),
'league' => ! tony_sportspress_event_filter_enabled( 'league' ),
'season' => ! tony_sportspress_event_filter_enabled( 'season' ),
'match_day' => ! tony_sportspress_event_filter_enabled( 'match_day' ),
'week' => ! tony_sportspress_event_filter_enabled( 'week' ),
);
?>
<style>
<?php if ( $hide['month'] ) : ?>
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="m"] { display: none !important; }
<?php endif; ?>
<?php if ( $hide['team'] ) : ?>
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="team"],
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="team"] + .chosen-container,
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="team"] + .select2 { display: none !important; }
<?php endif; ?>
<?php if ( $hide['venue'] ) : ?>
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="sp_venue"],
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="sp_venue"] + .chosen-container,
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="sp_venue"] + .select2 { display: none !important; }
<?php endif; ?>
<?php if ( $hide['league'] ) : ?>
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="sp_league"],
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="sp_league"] + .chosen-container,
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="sp_league"] + .select2 { display: none !important; }
<?php endif; ?>
<?php if ( $hide['season'] ) : ?>
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="sp_season"],
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="sp_season"] + .chosen-container,
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) select[name="sp_season"] + .select2 { display: none !important; }
<?php endif; ?>
<?php if ( $hide['match_day'] ) : ?>
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) input[name="match_day"] { display: none !important; }
<?php endif; ?>
<?php if ( $hide['week'] ) : ?>
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) #sp_week_filter,
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) #sp-week-filter-summary { display: none !important; }
<?php endif; ?>
@media (max-width: 1200px) {
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) {
display: flex;
flex-wrap: wrap;
gap: 6px;
align-items: center;
}
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) > * {
float: none;
margin-right: 0;
}
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) .sp-week-filter-field {
min-width: 145px;
}
.post-type-sp_event .tablenav.top .alignleft.actions:not(.bulkactions) .sp-week-filter-summary {
display: block;
width: 100%;
margin-top: 2px;
color: #50575e;
font-size: 12px;
line-height: 1.4;
}
}
</style>
<?php
}
add_action( 'admin_head-edit.php', 'tony_sportspress_admin_week_filter_styles' );
/**
* Update week summary text when week input changes.
*/
function tony_sportspress_admin_week_filter_script() {
$screen = get_current_screen();
if ( ! $screen || 'edit-sp_event' !== $screen->id ) {
return;
}
?>
<script>
(function() {
const filterCheckboxes = Array.from(
document.querySelectorAll('#screen-options-wrap input[type="checkbox"][id^="tony_sp_event_filter_"]')
);
function saveFilterPrefs() {
if (!filterCheckboxes.length || typeof ajaxurl === 'undefined') {
return;
}
const body = new URLSearchParams();
body.append('action', 'tony_sp_event_filter_prefs_save');
body.append('nonce', <?php echo wp_json_encode( wp_create_nonce( 'tony_sp_event_filters' ) ); ?>);
filterCheckboxes.forEach(function(checkbox) {
const key = checkbox.id.replace('tony_sp_event_filter_', '');
body.append('filters[' + key + ']', checkbox.checked ? '1' : '0');
});
fetch(ajaxurl, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
},
body: body.toString(),
keepalive: true
}).catch(function() {});
}
filterCheckboxes.forEach(function(checkbox) {
checkbox.addEventListener('change', saveFilterPrefs);
});
const monthSelect = document.querySelector('select[name="m"]');
if (monthSelect) {
const allDates = monthSelect.querySelector('option[value="0"]');
if (allDates) {
allDates.textContent = <?php echo wp_json_encode( __( 'Month/Year', 'tonys-sportspress-enhancements' ) ); ?>;
}
}
const input = document.getElementById('sp_week_filter');
const summary = document.getElementById('sp-week-filter-summary');
if (!input || !summary) {
return;
}
function updateSummary() {
const raw = (input.value || '').trim();
const match = raw.match(/^(\d{4})-W(\d{2})$/);
if (!match) {
summary.textContent = 'Select a week';
return;
}
const year = parseInt(match[1], 10);
const week = parseInt(match[2], 10);
const jan4 = new Date(Date.UTC(year, 0, 4));
const jan4Day = jan4.getUTCDay() || 7;
const mondayWeek1 = new Date(jan4);
mondayWeek1.setUTCDate(jan4.getUTCDate() - jan4Day + 1);
const monday = new Date(mondayWeek1);
monday.setUTCDate(mondayWeek1.getUTCDate() + (week - 1) * 7);
const sunday = new Date(monday);
sunday.setUTCDate(monday.getUTCDate() + 6);
const fmt = new Intl.DateTimeFormat(undefined, {
weekday: 'short',
month: 'short',
day: 'numeric',
year: 'numeric',
timeZone: 'UTC'
});
summary.textContent = fmt.format(monday) + ' to ' + fmt.format(sunday);
}
input.addEventListener('change', updateSummary);
updateSummary();
})();
</script>
<?php
}
add_action( 'admin_footer-edit.php', 'tony_sportspress_admin_week_filter_script' );
/**
* Apply Monday-start week date query to event admin list.
*
* @param WP_Query $query Main query.
*/
function tony_sportspress_apply_admin_week_filter( $query ) {
if ( ! is_admin() || ! $query->is_main_query() ) {
return;
}
$post_type = $query->get( 'post_type' );
if ( 'sp_event' !== $post_type ) {
return;
}
$parsed = tony_sportspress_parse_admin_week_filter();
if ( null === $parsed ) {
return;
}
$timezone = wp_timezone();
$monday = ( new DateTimeImmutable( 'now', $timezone ) )->setISODate( $parsed['year'], $parsed['week'], 1 )->setTime( 0, 0, 0 );
$sunday = $monday->modify( '+6 days' )->setTime( 23, 59, 59 );
$date_query = $query->get( 'date_query' );
if ( ! is_array( $date_query ) ) {
$date_query = array();
}
$date_query[] = array(
'after' => array(
'year' => (int) $monday->format( 'Y' ),
'month' => (int) $monday->format( 'n' ),
'day' => (int) $monday->format( 'j' ),
),
'before' => array(
'year' => (int) $sunday->format( 'Y' ),
'month' => (int) $sunday->format( 'n' ),
'day' => (int) $sunday->format( 'j' ),
),
'inclusive' => true,
);
$query->set( 'date_query', $date_query );
}
add_action( 'pre_get_posts', 'tony_sportspress_apply_admin_week_filter' );

1592
includes/sp-event-csv.php Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -75,15 +75,27 @@ function custom_event_rewrite_flush() {
register_activation_hook(__FILE__, 'custom_event_rewrite_flush');
register_deactivation_hook(__FILE__, 'flush_rewrite_rules');
// Modify the query to handle custom permalinks and include future posts
function custom_event_parse_request($query) {
$post_type = sp_array_value( $query->query, 'post_type', null );
if (isset($query->query_vars['post_type']) && $query->query_vars['post_type'] === 'sp_event') {
if (isset($query->query_vars['p'])) {
$query->set('post_type', 'sp_event');
$query->set('p', $query->query_vars['p']);
$query->set('post_status', array('publish', 'future'));
}
}
// Modify the front-end single event query to allow scheduled events to resolve.
function custom_event_parse_request( $query ) {
if ( ! $query instanceof WP_Query ) {
return;
}
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ( 'sp_event' !== $query->get( 'post_type' ) ) {
return;
}
$post_id = absint( $query->get( 'p' ) );
if ( $post_id <= 0 ) {
return;
}
$query->set( 'post_type', 'sp_event' );
$query->set( 'p', $post_id );
$query->set( 'post_status', array( 'publish', 'future' ) );
}
add_action('pre_get_posts', 'custom_event_parse_request');

View File

@@ -0,0 +1,234 @@
<?php
/**
* Quick Edit officials support for SportsPress events.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Print hidden officials data on each event row for quick edit prefill.
*
* @param string $column Column key.
* @param int $post_id Post ID.
*/
function tony_sportspress_event_quick_edit_officials_row_data( $column, $post_id ) {
if ( 'sp_team' !== $column ) {
return;
}
$officials = get_post_meta( $post_id, 'sp_officials', true );
if ( ! is_array( $officials ) ) {
$officials = array();
}
$serialized = wp_json_encode( $officials );
if ( ! is_string( $serialized ) ) {
$serialized = '{}';
}
echo '<span class="hidden tony-event-officials-data" data-officials="' . esc_attr( $serialized ) . '"></span>';
}
add_action( 'manage_sp_event_posts_custom_column', 'tony_sportspress_event_quick_edit_officials_row_data', 20, 2 );
/**
* Render quick edit UI for officials.
*
* @param string $column_name Column key.
* @param string $post_type Post type key.
*/
function tony_sportspress_event_quick_edit_officials_field( $column_name, $post_type ) {
if ( 'sp_event' !== $post_type || 'sp_team' !== $column_name ) {
return;
}
static $printed = false;
if ( $printed ) {
return;
}
$printed = true;
wp_nonce_field( 'tony_sp_event_officials_quick_edit', 'tony_sp_event_officials_quick_edit_nonce' );
$duties = get_terms(
array(
'taxonomy' => 'sp_duty',
'hide_empty' => false,
'orderby' => 'meta_value_num',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'sp_order',
'compare' => 'NOT EXISTS',
),
array(
'key' => 'sp_order',
'compare' => 'EXISTS',
),
),
)
);
if ( ! is_array( $duties ) || empty( $duties ) ) {
return;
}
$officials = get_posts(
array(
'post_type' => 'sp_official',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
)
);
if ( ! is_array( $officials ) || empty( $officials ) ) {
return;
}
?>
<fieldset class="inline-edit-col-right tony-sp-event-officials-wrap">
<div class="inline-edit-col">
<span class="title inline-edit-categories-label"><?php esc_html_e( 'Officials', 'tonys-sportspress-enhancements' ); ?></span>
<?php foreach ( $duties as $duty ) : ?>
<div class="tony-sp-duty-group">
<span class="title inline-edit-categories-label"><?php echo esc_html( $duty->name ); ?></span>
<input type="hidden" name="tony_sp_officials[<?php echo esc_attr( $duty->term_id ); ?>][]" value="0">
<ul class="cat-checklist">
<?php foreach ( $officials as $official ) : ?>
<li>
<label class="selectit">
<input
value="<?php echo esc_attr( $official->ID ); ?>"
type="checkbox"
name="tony_sp_officials[<?php echo esc_attr( $duty->term_id ); ?>][]"
class="tony-sp-official-checkbox"
data-duty-id="<?php echo esc_attr( $duty->term_id ); ?>"
>
<?php echo esc_html( $official->post_title ); ?>
</label>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endforeach; ?>
</div>
</fieldset>
<?php
}
add_action( 'quick_edit_custom_box', 'tony_sportspress_event_quick_edit_officials_field', 10, 2 );
/**
* Save quick edit officials data.
*
* @param int $post_id Post ID.
*/
function tony_sportspress_event_quick_edit_officials_save( $post_id ) {
if ( empty( $_POST ) ) {
return;
}
if ( wp_is_post_revision( $post_id ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) ) {
return;
}
if ( 'sp_event' !== get_post_type( $post_id ) ) {
return;
}
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
$nonce = isset( $_POST['tony_sp_event_officials_quick_edit_nonce'] )
? sanitize_text_field( wp_unslash( $_POST['tony_sp_event_officials_quick_edit_nonce'] ) )
: '';
if ( '' === $nonce || ! wp_verify_nonce( $nonce, 'tony_sp_event_officials_quick_edit' ) ) {
return;
}
$raw_officials = isset( $_POST['tony_sp_officials'] ) ? wp_unslash( $_POST['tony_sp_officials'] ) : array();
if ( ! is_array( $raw_officials ) ) {
$raw_officials = array();
}
$clean_officials = array();
foreach ( $raw_officials as $duty_id => $official_ids ) {
$duty_id = absint( $duty_id );
if ( $duty_id <= 0 || ! is_array( $official_ids ) ) {
continue;
}
$official_ids = array_map( 'absint', $official_ids );
$official_ids = array_filter( $official_ids );
$official_ids = array_values( array_unique( $official_ids ) );
if ( ! empty( $official_ids ) ) {
$clean_officials[ $duty_id ] = $official_ids;
}
}
update_post_meta( $post_id, 'sp_officials', $clean_officials );
}
add_action( 'save_post', 'tony_sportspress_event_quick_edit_officials_save' );
/**
* Prefill quick edit checkboxes with existing officials.
*/
function tony_sportspress_event_quick_edit_officials_script() {
$screen = get_current_screen();
if ( ! $screen || 'edit-sp_event' !== $screen->id ) {
return;
}
?>
<script>
(function($) {
if (typeof inlineEditPost === 'undefined' || !inlineEditPost.edit) {
return;
}
var wpInlineEdit = inlineEditPost.edit;
inlineEditPost.edit = function(id) {
wpInlineEdit.apply(this, arguments);
var postId = 0;
if (typeof id === 'object') {
postId = parseInt(this.getId(id), 10);
}
if (!postId) {
return;
}
var editRow = $('#edit-' + postId);
var postRow = $('#post-' + postId);
var payload = postRow.find('.tony-event-officials-data').attr('data-officials');
var selected = {};
try {
selected = payload ? JSON.parse(payload) : {};
} catch (e) {
selected = {};
}
editRow.find('.tony-sp-official-checkbox').prop('checked', false);
Object.keys(selected).forEach(function(dutyId) {
var ids = selected[dutyId];
if (!Array.isArray(ids)) {
return;
}
ids.forEach(function(officialId) {
editRow
.find('.tony-sp-official-checkbox[data-duty-id="' + dutyId + '"][value="' + String(officialId) + '"]')
.prop('checked', true);
});
});
};
})(jQuery);
</script>
<?php
}
add_action( 'admin_footer-edit.php', 'tony_sportspress_event_quick_edit_officials_script' );

View File

@@ -0,0 +1,275 @@
<?php
/**
* Unified team-ordering behavior for SportsPress event admin and frontend lists.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Check whether SportsPress reverse teams option is enabled.
*
* @return bool
*/
function tony_sportspress_reverse_teams_enabled() {
return get_option( 'sportspress_event_reverse_teams', 'no' ) === 'yes';
}
/**
* Add Away | Home option to Event List title format setting.
*
* @param array $options Event list settings options.
* @return array
*/
function tony_sportspress_event_list_add_away_home_option( $options ) {
if ( ! is_array( $options ) ) {
return $options;
}
foreach ( $options as &$option ) {
if ( ! is_array( $option ) || ! isset( $option['id'] ) || 'sportspress_event_list_title_format' !== $option['id'] ) {
continue;
}
if ( ! isset( $option['options'] ) || ! is_array( $option['options'] ) ) {
continue;
}
if ( ! array_key_exists( 'awayhome', $option['options'] ) ) {
$option['options']['awayhome'] = sprintf( '%s | %s', esc_attr__( 'Away', 'sportspress' ), esc_attr__( 'Home', 'sportspress' ) );
}
}
unset( $option );
return $options;
}
add_filter( 'sportspress_event_list_options', 'tony_sportspress_event_list_add_away_home_option' );
/**
* Clarify wording of SportsPress Teams reverse-order option.
*
* @param array $options Team options.
* @return array
*/
function tony_sportspress_relabel_reverse_teams_option( $options ) {
if ( ! is_array( $options ) ) {
return $options;
}
foreach ( $options as &$option ) {
if ( ! is_array( $option ) || ! isset( $option['id'] ) || 'sportspress_event_reverse_teams' !== $option['id'] ) {
continue;
}
$option['desc'] = esc_attr__( 'Show away team first', 'tonys-sportspress-enhancements' );
}
unset( $option );
return $options;
}
add_filter( 'sportspress_event_logo_options', 'tony_sportspress_relabel_reverse_teams_option' );
/**
* Add Event Results team order option.
*
* @param array $options Event Results options.
* @return array
*/
function tony_sportspress_add_event_results_order_option( $options ) {
if ( ! is_array( $options ) ) {
return $options;
}
$options[] = array(
'title' => esc_attr__( 'Row order', 'tonys-sportspress-enhancements' ),
'id' => 'tony_sportspress_event_results_row_order',
'default' => 'home_away',
'type' => 'radio',
'options' => array(
'home_away' => sprintf( '%s | %s', esc_attr__( 'Home', 'sportspress' ), esc_attr__( 'Away', 'sportspress' ) ),
'away_home' => sprintf( '%s | %s', esc_attr__( 'Away', 'sportspress' ), esc_attr__( 'Home', 'sportspress' ) ),
),
);
return $options;
}
add_filter( 'sportspress_result_options', 'tony_sportspress_add_event_results_order_option' );
/**
* Override SportsPress event templates with plugin versions.
*
* @param string $template Located template path.
* @param string $template_name Template filename.
* @param string $template_path Template base path.
* @return string
*/
function tony_sportspress_locate_event_list_template( $template, $template_name, $template_path ) {
$supported = array(
'event-list.php',
'event-results.php',
);
if ( ! in_array( $template_name, $supported, true ) ) {
return $template;
}
$override = dirname( __DIR__ ) . '/templates/' . $template_name;
if ( file_exists( $override ) ) {
return $override;
}
return $template;
}
add_filter( 'sportspress_locate_template', 'tony_sportspress_locate_event_list_template', 10, 3 );
/**
* Add admin styles for explicit Home/Away labels on event edit screens.
*/
function tony_sportspress_event_team_order_admin_styles() {
$screen = get_current_screen();
if ( ! $screen || 'sp_event' !== $screen->post_type ) {
return;
}
?>
<style>
#sp_teamdiv .sp-instance {
padding-top: 8px;
border-top: 1px solid #dcdcde;
}
#sp_teamdiv .sp-instance:first-child {
padding-top: 0;
border-top: 0;
}
#sp_teamdiv .tony-sp-home-away-label {
margin: 0 0 8px;
font-size: 12px;
letter-spacing: 0.02em;
text-transform: uppercase;
color: #50575e;
}
</style>
<?php
}
add_action( 'admin_head-post.php', 'tony_sportspress_event_team_order_admin_styles' );
add_action( 'admin_head-post-new.php', 'tony_sportspress_event_team_order_admin_styles' );
/**
* Add explicit Home/Away labels and reverse visual order in event edit teams metabox.
*/
function tony_sportspress_event_team_order_admin_script() {
$screen = get_current_screen();
if ( ! $screen || 'sp_event' !== $screen->post_type ) {
return;
}
$slot_labels = array(
__( 'Home Team', 'tonys-sportspress-enhancements' ),
__( 'Away Team', 'tonys-sportspress-enhancements' ),
);
$show_away_first = tony_sportspress_reverse_teams_enabled();
?>
<script>
(function($) {
function applyHomeAwayLabels() {
var labels = <?php echo wp_json_encode( $slot_labels ); ?>;
var showAwayFirst = <?php echo $show_away_first ? 'true' : 'false'; ?>;
var $instances = $('#sp_teamdiv .sp-instance');
if (!$instances.length) {
return;
}
var $container = $instances.first().parent();
$instances.css('order', '');
if (showAwayFirst && $instances.length > 1) {
$container.css({
display: 'flex',
flexDirection: 'column'
});
$instances.each(function(index) {
$(this).css('order', index + 1);
});
$instances.eq(0).css('order', 2);
$instances.eq(1).css('order', 1);
}
$instances.each(function(index) {
var label = labels[index] || ('Team ' + (index + 1));
var $instance = $(this);
if (!$instance.children('.tony-sp-home-away-label').length) {
$instance.prepend('<p class="tony-sp-home-away-label"><strong>' + label + '</strong></p>');
} else {
$instance.children('.tony-sp-home-away-label').find('strong').text(label);
}
$instance.find('select[name="sp_team[]"]').first().attr('aria-label', label);
});
}
$(applyHomeAwayLabels);
$(document).on('sp-init-chosen sp-init', applyHomeAwayLabels);
})(jQuery);
</script>
<?php
}
add_action( 'admin_footer-post.php', 'tony_sportspress_event_team_order_admin_script' );
add_action( 'admin_footer-post-new.php', 'tony_sportspress_event_team_order_admin_script' );
/**
* Normalize event-list results array to match event team order.
*
* @param array $main_results Team results array.
* @param int $event_id Event ID.
* @return array
*/
function tony_sportspress_event_list_score_order( $main_results, $event_id ) {
if ( ! is_array( $main_results ) || empty( $main_results ) ) {
return $main_results;
}
$teams = (array) get_post_meta( $event_id, 'sp_team', false );
$teams = array_values( array_filter( array_map( 'absint', $teams ) ) );
if ( empty( $teams ) ) {
return $main_results;
}
$ordered = array();
foreach ( $teams as $index => $team_id ) {
if ( array_key_exists( $team_id, $main_results ) ) {
$ordered[ $team_id ] = $main_results[ $team_id ];
continue;
}
// SportsPress main_results() can be positional (0,1,...) in team order.
if ( array_key_exists( $index, $main_results ) ) {
$ordered[ $team_id ] = $main_results[ $index ];
}
}
if ( empty( $ordered ) ) {
return $main_results;
}
foreach ( $main_results as $team_id => $result ) {
if ( array_key_exists( $team_id, $ordered ) ) {
continue;
}
// Skip positional keys that have already been remapped to team IDs.
if ( is_int( $team_id ) || ctype_digit( (string) $team_id ) ) {
$position = (int) $team_id;
if ( array_key_exists( $position, $teams ) ) {
continue;
}
}
$ordered[ $team_id ] = $result;
}
return $ordered;
}
add_filter( 'sportspress_event_list_main_results', 'tony_sportspress_event_list_score_order', 999, 2 );

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,879 @@
<?php
/**
* SportsPress schedule exporter admin page.
*
* @package Tonys_Sportspress_Enhancements
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Register the schedule exporter admin page.
*
* @return void
*/
function tse_sp_schedule_exporter_add_admin_page() {
add_submenu_page(
'sportspress',
__( 'Schedule Exporter', 'tonys-sportspress-enhancements' ),
__( 'Schedule Exporter', 'tonys-sportspress-enhancements' ),
'manage_sportspress',
'tse-schedule-exporter',
'tse_sp_schedule_exporter_render_admin_page'
);
}
add_action( 'admin_menu', 'tse_sp_schedule_exporter_add_admin_page' );
add_shortcode( 'tse_schedule_exporter', 'tse_sp_schedule_exporter_render_shortcode' );
add_action( 'init', 'tse_sp_schedule_exporter_register_block' );
/**
* Handle schedule export downloads.
*
* @return void
*/
function tse_sp_schedule_exporter_handle_download() {
if ( is_user_logged_in() && ! current_user_can( 'manage_sportspress' ) ) {
wp_die( esc_html__( 'You do not have permission to export schedules.', 'tonys-sportspress-enhancements' ), '', array( 'response' => 403 ) );
}
check_admin_referer( 'tse_schedule_export' );
$team_id = isset( $_GET['team_id'] ) ? absint( wp_unslash( $_GET['team_id'] ) ) : 0;
$season_id = isset( $_GET['season_id'] ) ? absint( wp_unslash( $_GET['season_id'] ) ) : 0;
$league_id = isset( $_GET['league_id'] ) ? absint( wp_unslash( $_GET['league_id'] ) ) : 0;
$format = isset( $_GET['format'] ) ? sanitize_key( wp_unslash( $_GET['format'] ) ) : '';
if ( $team_id <= 0 || 'sp_team' !== get_post_type( $team_id ) ) {
wp_die( esc_html__( 'Choose a valid team before exporting.', 'tonys-sportspress-enhancements' ), '', array( 'response' => 400 ) );
}
if ( ! in_array( $format, array( 'matchup', 'team' ), true ) ) {
wp_die( esc_html__( 'Choose a valid export format.', 'tonys-sportspress-enhancements' ), '', array( 'response' => 400 ) );
}
$events = tse_sp_schedule_exporter_get_events( $team_id, $season_id, $league_id );
$team = get_post( $team_id );
if ( ! $team instanceof WP_Post ) {
wp_die( esc_html__( 'The selected team could not be loaded.', 'tonys-sportspress-enhancements' ), '', array( 'response' => 404 ) );
}
$filename = sanitize_title( $team->post_name ? $team->post_name : $team->post_title );
if ( '' === $filename ) {
$filename = 'schedule';
}
if ( $season_id > 0 ) {
$season = get_term( $season_id, 'sp_season' );
if ( $season && ! is_wp_error( $season ) && ! empty( $season->slug ) ) {
$filename .= '-' . sanitize_title( $season->slug );
}
}
$filename .= '-' . $format . '.csv';
header( 'Content-Type: text/csv; charset=utf-8' );
header( 'Content-Disposition: attachment; filename=' . $filename );
$output = fopen( 'php://output', 'w' );
if ( false === $output ) {
wp_die( esc_html__( 'Unable to start the CSV export.', 'tonys-sportspress-enhancements' ), '', array( 'response' => 500 ) );
}
fwrite( $output, "\xEF\xBB\xBF" );
if ( 'matchup' === $format ) {
fputcsv(
$output,
array(
'Date',
'Time',
'Away Team',
'Home Team',
'Field Name',
)
);
foreach ( $events as $event ) {
fputcsv(
$output,
array(
$event['date'],
$event['time'],
$event['away_team'],
$event['home_team'],
$event['venue_name'],
)
);
}
} else {
fputcsv(
$output,
array(
'Extra Label',
'Date',
'Time',
'Opponent',
'Home/Away',
'Venue',
)
);
foreach ( $events as $event ) {
fputcsv(
$output,
array(
$event['label'],
$event['date'],
$event['time'],
$event['opponent_name'],
$event['location_flag'],
$event['venue_name'],
)
);
}
}
fclose( $output );
exit;
}
add_action( 'admin_post_tse_schedule_export', 'tse_sp_schedule_exporter_handle_download' );
add_action( 'admin_post_nopriv_tse_schedule_export', 'tse_sp_schedule_exporter_handle_download' );
/**
* Register the schedule exporter block.
*
* @return void
*/
function tse_sp_schedule_exporter_register_block() {
if ( ! function_exists( 'register_block_type' ) ) {
return;
}
wp_register_script(
'tse-schedule-exporter-block',
TONY_SPORTSPRESS_ENHANCEMENTS_URL . 'assets/schedule-exporter-block.js',
array( 'wp-blocks', 'wp-block-editor', 'wp-element', 'wp-i18n' ),
TONY_SPORTSPRESS_ENHANCEMENTS_VERSION,
true
);
register_block_type(
'tse/schedule-exporter',
array(
'api_version' => 3,
'title' => __( 'Schedule Exporter', 'tonys-sportspress-enhancements' ),
'description' => __( 'Shows the public schedule exporter with CSV and printable PDF options.', 'tonys-sportspress-enhancements' ),
'category' => 'widgets',
'icon' => 'calendar-alt',
'editor_script' => 'tse-schedule-exporter-block',
'render_callback' => 'tse_sp_schedule_exporter_render_block',
'supports' => array(
'html' => false,
),
)
);
}
/**
* Render the schedule exporter page.
*
* @return void
*/
function tse_sp_schedule_exporter_render_admin_page() {
if ( ! current_user_can( 'manage_sportspress' ) ) {
return;
}
$leagues = tse_sp_schedule_exporter_get_leagues();
$league_id = tse_sp_schedule_exporter_resolve_league_id( $leagues );
$seasons = tse_sp_schedule_exporter_get_seasons();
$season_id = tse_sp_schedule_exporter_resolve_season_id( $seasons );
$teams = tse_sp_schedule_exporter_get_teams( $league_id, $season_id );
$team_id = tse_sp_schedule_exporter_resolve_team_id( $teams );
$paper = tse_sp_schedule_exporter_resolve_paper_size();
echo '<div class="wrap">';
echo '<h1>' . esc_html__( 'Schedule Exporter', 'tonys-sportspress-enhancements' ) . '</h1>';
echo '<p>' . esc_html__( 'Choose a team and season, then export the schedule as CSV or open the printable schedule in a PDF-ready print view.', 'tonys-sportspress-enhancements' ) . '</p>';
echo '<form method="get" action="' . esc_url( admin_url( 'admin.php' ) ) . '" class="tse-schedule-exporter-form" style="max-width:960px;margin:20px 0 28px;">';
echo '<input type="hidden" name="page" value="tse-schedule-exporter" />';
echo '<table class="form-table" role="presentation"><tbody>';
echo '<tr>';
echo '<th scope="row"><label for="tse-schedule-exporter-league">' . esc_html__( 'League', 'tonys-sportspress-enhancements' ) . '</label></th>';
echo '<td><select id="tse-schedule-exporter-league" name="league_id" data-auto-submit="1">';
foreach ( $leagues as $league ) {
printf(
'<option value="%1$s" %2$s>%3$s</option>',
esc_attr( (string) $league->term_id ),
selected( $league_id, (int) $league->term_id, false ),
esc_html( $league->name )
);
}
echo '</select></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="tse-schedule-exporter-season">' . esc_html__( 'Season', 'tonys-sportspress-enhancements' ) . '</label></th>';
echo '<td><select id="tse-schedule-exporter-season" name="season_id" data-auto-submit="1">';
echo '<option value="0">' . esc_html__( 'Current / All matching events', 'tonys-sportspress-enhancements' ) . '</option>';
foreach ( $seasons as $season ) {
printf(
'<option value="%1$s" %2$s>%3$s</option>',
esc_attr( (string) $season->term_id ),
selected( $season_id, (int) $season->term_id, false ),
esc_html( $season->name )
);
}
echo '</select></td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="tse-schedule-exporter-paper">' . esc_html__( 'Paper Size', 'tonys-sportspress-enhancements' ) . '</label></th>';
echo '<td><select id="tse-schedule-exporter-paper" name="paper">';
foreach ( tse_sp_schedule_exporter_get_paper_sizes() as $paper_value => $paper_label ) {
printf(
'<option value="%1$s" %2$s>%3$s</option>',
esc_attr( $paper_value ),
selected( $paper, $paper_value, false ),
esc_html( $paper_label )
);
}
echo '</select>';
echo '<p class="description">' . esc_html__( 'The PDF option opens the existing printable schedule and triggers the browser print dialog so you can save it as a PDF.', 'tonys-sportspress-enhancements' ) . '</p>';
echo '</td>';
echo '</tr>';
echo '<tr>';
echo '<th scope="row"><label for="tse-schedule-exporter-team">' . esc_html__( 'Team', 'tonys-sportspress-enhancements' ) . '</label></th>';
echo '<td><select id="tse-schedule-exporter-team" name="team_id">';
foreach ( $teams as $team ) {
printf(
'<option value="%1$s" %2$s>%3$s</option>',
esc_attr( (string) $team->ID ),
selected( $team_id, (int) $team->ID, false ),
esc_html( $team->post_title )
);
}
echo '</select>';
echo '<p class="description">' . esc_html__( 'Teams are filtered by the selected league and season.', 'tonys-sportspress-enhancements' ) . '</p>';
echo '</td>';
echo '</tr>';
echo '</tbody></table>';
echo '</form>';
if ( empty( $teams ) ) {
echo '<div class="notice notice-warning inline"><p>' . esc_html__( 'No SportsPress teams match the selected league and season.', 'tonys-sportspress-enhancements' ) . '</p></div>';
echo '</div>';
return;
}
echo '<div style="max-width:960px;padding:20px 24px;border:1px solid #dcdcde;background:#fff;">';
echo '<h2 style="margin-top:0;">' . esc_html__( 'Exports', 'tonys-sportspress-enhancements' ) . '</h2>';
echo '<table class="widefat striped" style="max-width:100%;margin-top:16px;"><tbody>';
foreach ( array(
array(
'format' => 'matchup',
'label' => __( 'Download Matchup CSV', 'tonys-sportspress-enhancements' ),
'description' => __( 'Date, time, away team, home team, and field name.', 'tonys-sportspress-enhancements' ),
),
array(
'format' => 'team',
'label' => __( 'Download Team CSV', 'tonys-sportspress-enhancements' ),
'description' => __( 'TeamSnap-compatible layout with game label, opponent, home/away flag, and venue.', 'tonys-sportspress-enhancements' ),
),
) as $export_option ) {
$url = wp_nonce_url(
add_query_arg(
array(
'action' => 'tse_schedule_export',
'league_id' => $league_id,
'team_id' => $team_id,
'season_id' => $season_id,
'format' => $export_option['format'],
),
admin_url( 'admin-post.php' )
),
'tse_schedule_export'
);
echo '<tr>';
echo '<td style="width:240px;"><a class="button button-primary tse-export-link" data-format="' . esc_attr( $export_option['format'] ) . '" href="' . esc_url( $url ) . '">' . esc_html( $export_option['label'] ) . '</a></td>';
echo '<td>' . esc_html( $export_option['description'] ) . '</td>';
echo '</tr>';
}
$pdf_url = tse_sp_schedule_exporter_get_pdf_url( $team_id, $season_id, $paper, $league_id );
echo '<tr>';
echo '<td style="width:240px;"><a class="button tse-pdf-link" href="' . esc_url( $pdf_url ) . '" target="_blank" rel="noopener noreferrer">' . esc_html__( 'Open Printable PDF View', 'tonys-sportspress-enhancements' ) . '</a></td>';
echo '<td>' . esc_html__( 'Opens the printable schedule and launches the browser print dialog so you can save a PDF.', 'tonys-sportspress-enhancements' ) . '</td>';
echo '</tr>';
echo '</tbody></table>';
tse_sp_schedule_exporter_render_link_sync_script( true );
echo '</div>';
echo '</div>';
}
/**
* Render the public shortcode.
*
* @return string
*/
function tse_sp_schedule_exporter_render_shortcode() {
$leagues = tse_sp_schedule_exporter_get_leagues();
$league_id = tse_sp_schedule_exporter_resolve_league_id( $leagues );
$seasons = tse_sp_schedule_exporter_get_seasons();
$season_id = tse_sp_schedule_exporter_resolve_season_id( $seasons );
$teams = tse_sp_schedule_exporter_get_teams( $league_id, $season_id );
$team_id = tse_sp_schedule_exporter_resolve_team_id( $teams );
$paper = tse_sp_schedule_exporter_resolve_paper_size();
if ( empty( $teams ) ) {
return '<p>' . esc_html__( 'No SportsPress teams match the selected league and season.', 'tonys-sportspress-enhancements' ) . '</p>';
}
ob_start();
?>
<div class="tse-schedule-exporter" style="max-width:960px;margin:0 auto;padding:24px;border:1px solid #d7d7db;background:#fff;">
<h2 style="margin-top:0;"><?php esc_html_e( 'Schedule Exporter', 'tonys-sportspress-enhancements' ); ?></h2>
<p><?php esc_html_e( 'Export schedules as CSV or open the printable version and save it as a PDF.', 'tonys-sportspress-enhancements' ); ?></p>
<form method="get" action="<?php echo esc_url( get_permalink() ); ?>" class="tse-schedule-exporter-form" style="display:grid;gap:16px;margin:24px 0;">
<div>
<label for="tse-public-league"><strong><?php esc_html_e( 'League', 'tonys-sportspress-enhancements' ); ?></strong></label><br />
<select id="tse-public-league" name="league_id" data-auto-submit="1">
<?php foreach ( $leagues as $league ) : ?>
<option value="<?php echo esc_attr( (string) $league->term_id ); ?>" <?php selected( $league_id, (int) $league->term_id ); ?>>
<?php echo esc_html( $league->name ); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="tse-public-season"><strong><?php esc_html_e( 'Season', 'tonys-sportspress-enhancements' ); ?></strong></label><br />
<select id="tse-public-season" name="season_id" data-auto-submit="1">
<option value="0"><?php esc_html_e( 'Current / All matching events', 'tonys-sportspress-enhancements' ); ?></option>
<?php foreach ( $seasons as $season ) : ?>
<option value="<?php echo esc_attr( (string) $season->term_id ); ?>" <?php selected( $season_id, (int) $season->term_id ); ?>>
<?php echo esc_html( $season->name ); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="tse-public-paper"><strong><?php esc_html_e( 'Paper Size', 'tonys-sportspress-enhancements' ); ?></strong></label><br />
<select id="tse-public-paper" name="paper">
<?php foreach ( tse_sp_schedule_exporter_get_paper_sizes() as $paper_value => $paper_label ) : ?>
<option value="<?php echo esc_attr( $paper_value ); ?>" <?php selected( $paper, $paper_value ); ?>>
<?php echo esc_html( $paper_label ); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div>
<label for="tse-public-team"><strong><?php esc_html_e( 'Team', 'tonys-sportspress-enhancements' ); ?></strong></label><br />
<select id="tse-public-team" name="team_id">
<?php foreach ( $teams as $team ) : ?>
<option value="<?php echo esc_attr( (string) $team->ID ); ?>" <?php selected( $team_id, (int) $team->ID ); ?>>
<?php echo esc_html( $team->post_title ); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</form>
<table style="width:100%;border-collapse:collapse;margin-top:16px;">
<tbody>
<tr>
<td style="width:240px;padding:10px 12px;border:1px solid #d7d7db;">
<a class="button button-primary tse-export-link" data-format="matchup" href="<?php echo esc_url( tse_sp_schedule_exporter_get_export_url( $team_id, $season_id, 'matchup', $league_id ) ); ?>"><?php esc_html_e( 'Download Matchup CSV', 'tonys-sportspress-enhancements' ); ?></a>
</td>
<td style="padding:10px 12px;border:1px solid #d7d7db;"><?php esc_html_e( 'Date, time, away team, home team, and field name.', 'tonys-sportspress-enhancements' ); ?></td>
</tr>
<tr>
<td style="width:240px;padding:10px 12px;border:1px solid #d7d7db;">
<a class="button button-primary tse-export-link" data-format="team" href="<?php echo esc_url( tse_sp_schedule_exporter_get_export_url( $team_id, $season_id, 'team', $league_id ) ); ?>"><?php esc_html_e( 'Download Team CSV', 'tonys-sportspress-enhancements' ); ?></a>
</td>
<td style="padding:10px 12px;border:1px solid #d7d7db;"><?php esc_html_e( 'TeamSnap-compatible layout with game label, opponent, home/away flag, and venue.', 'tonys-sportspress-enhancements' ); ?></td>
</tr>
<tr>
<td style="width:240px;padding:10px 12px;border:1px solid #d7d7db;">
<a class="button tse-pdf-link" href="<?php echo esc_url( tse_sp_schedule_exporter_get_pdf_url( $team_id, $season_id, $paper, $league_id ) ); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Open Printable PDF View', 'tonys-sportspress-enhancements' ); ?></a>
</td>
<td style="padding:10px 12px;border:1px solid #d7d7db;"><?php esc_html_e( 'Opens the printable schedule and starts the print dialog so visitors can save a PDF.', 'tonys-sportspress-enhancements' ); ?></td>
</tr>
</tbody>
</table>
</div>
<?php
$output = (string) ob_get_clean();
return $output . tse_sp_schedule_exporter_render_link_sync_script();
}
/**
* Render the schedule exporter block.
*
* @return string
*/
function tse_sp_schedule_exporter_render_block() {
if ( is_admin() || ( function_exists( 'wp_is_json_request' ) && wp_is_json_request() ) ) {
return '<div class="tse-schedule-exporter-block-placeholder"><strong>' . esc_html__( 'Schedule Exporter', 'tonys-sportspress-enhancements' ) . '</strong><p>' . esc_html__( 'The schedule exporter renders on the frontend.', 'tonys-sportspress-enhancements' ) . '</p></div>';
}
return tse_sp_schedule_exporter_render_shortcode();
}
/**
* Get teams for the exporter.
*
* @return WP_Post[]
*/
function tse_sp_schedule_exporter_get_leagues() {
$leagues = get_terms(
array(
'taxonomy' => 'sp_league',
'hide_empty' => false,
'orderby' => 'name',
'order' => 'ASC',
)
);
if ( is_wp_error( $leagues ) || ! is_array( $leagues ) ) {
return array();
}
return $leagues;
}
/**
* Get seasons for the exporter.
*
* @return WP_Term[]
*/
function tse_sp_schedule_exporter_get_seasons() {
$seasons = get_terms(
array(
'taxonomy' => 'sp_season',
'hide_empty' => false,
'orderby' => 'name',
'order' => 'ASC',
)
);
if ( is_wp_error( $seasons ) || ! is_array( $seasons ) ) {
return array();
}
return $seasons;
}
/**
* Get teams for the exporter.
*
* @param int $league_id League ID.
* @param int $season_id Season ID.
* @return WP_Post[]
*/
function tse_sp_schedule_exporter_get_teams( $league_id = 0, $season_id = 0 ) {
$tax_query = array();
if ( $league_id > 0 ) {
$tax_query[] = array(
'taxonomy' => 'sp_league',
'field' => 'term_id',
'terms' => array( $league_id ),
);
}
if ( $season_id > 0 ) {
$tax_query[] = array(
'taxonomy' => 'sp_season',
'field' => 'term_id',
'terms' => array( $season_id ),
);
}
$args = array(
'post_type' => 'sp_team',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'title',
'order' => 'ASC',
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'cache_results' => false,
);
if ( ! empty( $tax_query ) ) {
if ( count( $tax_query ) > 1 ) {
$tax_query['relation'] = 'AND';
}
$args['tax_query'] = $tax_query;
}
$teams = get_posts( $args );
return is_array( $teams ) ? $teams : array();
}
/**
* Resolve selected team ID.
*
* @param WP_Post[] $teams Team posts.
* @return int
*/
function tse_sp_schedule_exporter_resolve_team_id( $teams ) {
$requested = isset( $_GET['team_id'] ) ? absint( wp_unslash( $_GET['team_id'] ) ) : 0;
if ( $requested > 0 && 'sp_team' === get_post_type( $requested ) ) {
foreach ( $teams as $team ) {
if ( $team instanceof WP_Post && (int) $team->ID === $requested ) {
return $requested;
}
}
}
if ( isset( $teams[0] ) && $teams[0] instanceof WP_Post ) {
return (int) $teams[0]->ID;
}
return 0;
}
/**
* Resolve selected league ID.
*
* @param WP_Term[] $leagues League terms.
* @return int
*/
function tse_sp_schedule_exporter_resolve_league_id( $leagues ) {
$requested = isset( $_GET['league_id'] ) ? absint( wp_unslash( $_GET['league_id'] ) ) : 0;
if ( $requested > 0 ) {
return $requested;
}
foreach ( $leagues as $league ) {
if ( ! $league instanceof WP_Term ) {
continue;
}
$slug = isset( $league->slug ) ? strtolower( (string) $league->slug ) : '';
$name = isset( $league->name ) ? strtolower( trim( (string) $league->name ) ) : '';
if ( 'cmba' === $slug || 'cmba' === $name ) {
return (int) $league->term_id;
}
}
if ( isset( $leagues[0] ) && $leagues[0] instanceof WP_Term ) {
return (int) $leagues[0]->term_id;
}
return 0;
}
/**
* Resolve selected season ID.
*
* @param WP_Term[] $seasons Season terms.
* @return int
*/
function tse_sp_schedule_exporter_resolve_season_id( $seasons ) {
$requested = isset( $_GET['season_id'] ) ? absint( wp_unslash( $_GET['season_id'] ) ) : 0;
if ( $requested > 0 ) {
return $requested;
}
$current = absint( (string) get_option( 'sportspress_season', '0' ) );
if ( $current > 0 ) {
return $current;
}
if ( isset( $seasons[0] ) && is_object( $seasons[0] ) && isset( $seasons[0]->term_id ) ) {
return (int) $seasons[0]->term_id;
}
return 0;
}
/**
* Get supported paper sizes.
*
* @return array
*/
function tse_sp_schedule_exporter_get_paper_sizes() {
return array(
'letter' => __( 'Letter', 'tonys-sportspress-enhancements' ),
'ledger' => __( '11x17 / Ledger', 'tonys-sportspress-enhancements' ),
);
}
/**
* Resolve selected paper size.
*
* @return string
*/
function tse_sp_schedule_exporter_resolve_paper_size() {
$paper = isset( $_GET['paper'] ) ? sanitize_key( wp_unslash( $_GET['paper'] ) ) : 'letter';
return array_key_exists( $paper, tse_sp_schedule_exporter_get_paper_sizes() ) ? $paper : 'letter';
}
/**
* Collect team schedule events for export.
*
* @param int $team_id Team ID.
* @param int $season_id Optional season ID.
* @param int $league_id Optional league ID.
* @return array
*/
function tse_sp_schedule_exporter_get_events( $team_id, $season_id = 0, $league_id = 0 ) {
$team_id = absint( $team_id );
if ( $team_id <= 0 || 'sp_team' !== get_post_type( $team_id ) ) {
return array();
}
$args = array(
'post_type' => 'sp_event',
'post_status' => array( 'publish', 'future' ),
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'ASC',
'no_found_rows' => true,
'meta_query' => array(
array(
'key' => 'sp_team',
'value' => array( (string) $team_id ),
'compare' => 'IN',
),
),
);
$tax_query = array();
if ( $season_id > 0 ) {
$tax_query[] = array(
'taxonomy' => 'sp_season',
'field' => 'term_id',
'terms' => array( $season_id ),
);
}
if ( $league_id > 0 ) {
$tax_query[] = array(
'taxonomy' => 'sp_league',
'field' => 'term_id',
'terms' => array( $league_id ),
);
}
if ( ! empty( $tax_query ) ) {
if ( count( $tax_query ) > 1 ) {
$tax_query['relation'] = 'AND';
}
$args['tax_query'] = $tax_query;
}
$query = new WP_Query( $args );
$events = array();
$team_name = get_the_title( $team_id );
foreach ( $query->posts as $event ) {
$event_id = $event instanceof WP_Post ? (int) $event->ID : 0;
if ( $event_id <= 0 ) {
continue;
}
$teams = array_values( array_unique( array_map( 'intval', get_post_meta( $event_id, 'sp_team', false ) ) ) );
if ( ! in_array( $team_id, $teams, true ) ) {
continue;
}
$home_id = isset( $teams[0] ) ? (int) $teams[0] : 0;
$away_id = isset( $teams[1] ) ? (int) $teams[1] : 0;
$location_flag = $home_id === $team_id ? 'Home' : 'Away';
$opponent_id = $home_id === $team_id ? $away_id : $home_id;
$venue = tse_sp_schedule_exporter_get_primary_venue( $event_id );
$events[] = array(
'label' => '',
'event_id' => $event_id,
'date' => get_post_time( 'm/d/Y', false, $event_id, true ),
'time' => strtoupper( (string) ( function_exists( 'sp_get_time' ) ? sp_get_time( $event_id ) : get_post_time( get_option( 'time_format' ), false, $event_id, true ) ) ),
'team_name' => is_string( $team_name ) ? $team_name : '',
'opponent_name' => $opponent_id > 0 ? get_the_title( $opponent_id ) : __( 'TBD', 'tonys-sportspress-enhancements' ),
'location_flag' => $location_flag,
'home_team' => $home_id > 0 ? get_the_title( $home_id ) : '',
'away_team' => $away_id > 0 ? get_the_title( $away_id ) : '',
'venue_name' => isset( $venue['name'] ) ? $venue['name'] : '',
'venue_abbreviation' => isset( $venue['abbreviation'] ) ? $venue['abbreviation'] : '',
'venue_short_name' => isset( $venue['short_name'] ) ? $venue['short_name'] : '',
);
}
foreach ( $events as $index => $event ) {
$events[ $index ]['label'] = sprintf( 'G#%02d', $index + 1 );
}
wp_reset_postdata();
return $events;
}
/**
* Get the primary venue details for an event.
*
* @param int $event_id Event ID.
* @return array
*/
function tse_sp_schedule_exporter_get_primary_venue( $event_id ) {
$venues = get_the_terms( $event_id, 'sp_venue' );
if ( ! is_array( $venues ) || ! isset( $venues[0] ) || ! $venues[0] instanceof WP_Term ) {
return array(
'name' => '',
'abbreviation' => '',
'short_name' => '',
);
}
$venue = $venues[0];
return array(
'name' => isset( $venue->name ) ? (string) $venue->name : '',
'abbreviation' => trim( (string) get_term_meta( $venue->term_id, 'tse_abbreviation', true ) ),
'short_name' => trim( (string) get_term_meta( $venue->term_id, 'tse_short_name', true ) ),
);
}
/**
* Build an export download URL.
*
* @param int $team_id Team ID.
* @param int $season_id Season ID.
* @param string $format Export format.
* @param int $league_id League ID.
* @return string
*/
function tse_sp_schedule_exporter_get_export_url( $team_id, $season_id, $format, $league_id = 0 ) {
return wp_nonce_url(
add_query_arg(
array(
'action' => 'tse_schedule_export',
'league_id' => absint( $league_id ),
'team_id' => absint( $team_id ),
'season_id' => absint( $season_id ),
'format' => sanitize_key( $format ),
),
admin_url( 'admin-post.php' )
),
'tse_schedule_export'
);
}
/**
* Build the printable PDF URL.
*
* @param int $team_id Team ID.
* @param int $season_id Season ID.
* @param string $paper Paper size.
* @param int $league_id League ID.
* @return string
*/
function tse_sp_schedule_exporter_get_pdf_url( $team_id, $season_id, $paper, $league_id = 0 ) {
return add_query_arg(
array(
Tony_Sportspress_Printable_Calendars::QUERY_FLAG => '1',
'sp_team' => (string) absint( $team_id ),
'sp_season' => $season_id > 0 ? (string) absint( $season_id ) : '',
'sp_league' => $league_id > 0 ? (string) absint( $league_id ) : '',
'paper' => $paper,
'autoprint' => '1',
),
home_url( '/' )
);
}
/**
* Render a small script that keeps export links in sync with current selections.
*
* @param bool $echo Whether to echo immediately.
* @return string
*/
function tse_sp_schedule_exporter_render_link_sync_script( $echo = false ) {
$script = <<<HTML
<script>
(function(){
function syncLinks(scope){
var form = scope.querySelector('.tse-schedule-exporter-form');
if (!form) {
return;
}
var league = form.querySelector('[name="league_id"]');
var season = form.querySelector('[name="season_id"]');
var team = form.querySelector('[name="team_id"]');
var paper = form.querySelector('[name="paper"]');
scope.querySelectorAll('.tse-export-link').forEach(function(link){
var url = new URL(link.href, window.location.origin);
if (league) url.searchParams.set('league_id', league.value || '0');
if (season) url.searchParams.set('season_id', season.value || '0');
if (team) url.searchParams.set('team_id', team.value || '0');
if (link.dataset.format) url.searchParams.set('format', link.dataset.format);
link.href = url.toString();
});
scope.querySelectorAll('.tse-pdf-link').forEach(function(link){
var url = new URL(link.href, window.location.origin);
if (league) url.searchParams.set('sp_league', league.value || '0');
if (season) url.searchParams.set('sp_season', season.value || '0');
if (team) url.searchParams.set('sp_team', team.value || '0');
if (paper) url.searchParams.set('paper', paper.value || 'letter');
link.href = url.toString();
});
}
document.querySelectorAll('.tse-schedule-exporter, .wrap').forEach(function(scope){
if (!scope.querySelector('.tse-schedule-exporter-form')) {
return;
}
syncLinks(scope);
scope.querySelectorAll('.tse-schedule-exporter-form select').forEach(function(select){
select.addEventListener('change', function(){
if (select.dataset.autoSubmit === '1') {
select.form.submit();
return;
}
syncLinks(scope);
});
});
});
})();
</script>
HTML;
if ( $echo ) {
echo $script; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
return '';
}
return $script;
}

116
includes/sp-venue-meta.php Normal file
View File

@@ -0,0 +1,116 @@
<?php
/**
* Venue term metadata support.
*
* Adds short name and abbreviation fields to SportsPress venues.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Register venue term meta.
*/
function tony_sportspress_register_venue_term_meta() {
register_term_meta(
'sp_venue',
'tse_short_name',
array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'show_in_rest' => true,
'auth_callback' => static function() {
return current_user_can( 'manage_categories' );
},
)
);
register_term_meta(
'sp_venue',
'tse_abbreviation',
array(
'type' => 'string',
'single' => true,
'sanitize_callback' => 'sanitize_text_field',
'show_in_rest' => true,
'auth_callback' => static function() {
return current_user_can( 'manage_categories' );
},
)
);
}
add_action( 'init', 'tony_sportspress_register_venue_term_meta' );
/**
* Render add-form fields for venue metadata.
*/
function tony_sportspress_add_venue_meta_fields() {
?>
<div class="form-field term-short-name-wrap">
<label for="tse_short_name"><?php esc_html_e( 'Short Name', 'tonys-sportspress-enhancements' ); ?></label>
<input name="tse_short_name" id="tse_short_name" type="text" value="" maxlength="100" />
<p><?php esc_html_e( 'Optional shorter label for this field or venue.', 'tonys-sportspress-enhancements' ); ?></p>
</div>
<div class="form-field term-abbreviation-wrap">
<label for="tse_abbreviation"><?php esc_html_e( 'Abbreviation', 'tonys-sportspress-enhancements' ); ?></label>
<input name="tse_abbreviation" id="tse_abbreviation" type="text" value="" maxlength="20" />
<p><?php esc_html_e( 'Optional abbreviation such as CC East or Field 1.', 'tonys-sportspress-enhancements' ); ?></p>
</div>
<?php
}
add_action( 'sp_venue_add_form_fields', 'tony_sportspress_add_venue_meta_fields' );
/**
* Render edit-form fields for venue metadata.
*
* @param WP_Term $term Venue term.
*/
function tony_sportspress_edit_venue_meta_fields( $term ) {
$short_name = get_term_meta( $term->term_id, 'tse_short_name', true );
$abbreviation = get_term_meta( $term->term_id, 'tse_abbreviation', true );
?>
<tr class="form-field term-short-name-wrap">
<th scope="row">
<label for="tse_short_name"><?php esc_html_e( 'Short Name', 'tonys-sportspress-enhancements' ); ?></label>
</th>
<td>
<input name="tse_short_name" id="tse_short_name" type="text" value="<?php echo esc_attr( $short_name ); ?>" maxlength="100" />
<p class="description"><?php esc_html_e( 'Optional shorter label for this field or venue.', 'tonys-sportspress-enhancements' ); ?></p>
</td>
</tr>
<tr class="form-field term-abbreviation-wrap">
<th scope="row">
<label for="tse_abbreviation"><?php esc_html_e( 'Abbreviation', 'tonys-sportspress-enhancements' ); ?></label>
</th>
<td>
<input name="tse_abbreviation" id="tse_abbreviation" type="text" value="<?php echo esc_attr( $abbreviation ); ?>" maxlength="20" />
<p class="description"><?php esc_html_e( 'Optional abbreviation such as CC East or Field 1.', 'tonys-sportspress-enhancements' ); ?></p>
</td>
</tr>
<?php
}
add_action( 'sp_venue_edit_form_fields', 'tony_sportspress_edit_venue_meta_fields' );
/**
* Save venue metadata fields.
*
* @param int $term_id Venue term ID.
*/
function tony_sportspress_save_venue_meta_fields( $term_id ) {
if ( ! current_user_can( 'manage_categories' ) ) {
return;
}
$short_name = isset( $_POST['tse_short_name'] ) ? sanitize_text_field( wp_unslash( $_POST['tse_short_name'] ) ) : '';
$short_name = is_string( $short_name ) ? trim( $short_name ) : '';
$abbreviation = isset( $_POST['tse_abbreviation'] ) ? sanitize_text_field( wp_unslash( $_POST['tse_abbreviation'] ) ) : '';
$abbreviation = is_string( $abbreviation ) ? trim( $abbreviation ) : '';
update_term_meta( $term_id, 'tse_short_name', $short_name );
update_term_meta( $term_id, 'tse_abbreviation', $abbreviation );
}
add_action( 'created_sp_venue', 'tony_sportspress_save_venue_meta_fields' );
add_action( 'edited_sp_venue', 'tony_sportspress_save_venue_meta_fields' );

View File

@@ -1,7 +1,7 @@
{
"name": "tonys-sportspress-enhancements",
"version": "0.1.0",
"version": "0.1.5",
"main": "Gruntfile.js",
"author": "YOUR NAME HERE",
"scripts" : {

39
readme.md Normal file
View File

@@ -0,0 +1,39 @@
# Tony's SportsPress Enhancements
Suite of enhancements for the SportsPress plugin, including custom event permalinks, Open Graph tags, and automatic featured image generation for events.
## Description
Tony's SportsPress Enhancements is a collection of add-ons for the [SportsPress](https://wordpress.org/plugins/sportspress/) plugin. It provides:
- **Custom event permalinks** for `sp_event` post types, including season and team slugs.
- **Open Graph meta tags** for events, with dynamic titles, descriptions, and images.
- **Automatic featured image generation** for events, combining team colors and logos into a shareable image.
- **Printable team schedules** with season-aware venue colors and a print-friendly calendar layout.
## Features
- Custom rewrite rules and permalinks for SportsPress events.
- Open Graph integration for better social sharing.
- Dynamic, cached event images based on team data.
- Printable schedule pages linked from team profiles.
- Compatible with WordPress 4.5+ and PHP 5.6+.
## Installation
1. Upload the plugin files to the `/wp-content/plugins/tonys-sportspress-enhancements/` directory, or install via the WordPress plugin repository.
2. Activate the plugin through the 'Plugins' menu in WordPress.
3. Make sure the [SportsPress](https://wordpress.org/plugins/sportspress/) plugin is installed and activated.
## Frequently Asked Questions
**Q: Does this plugin require SportsPress?**
A: Yes, it extends the functionality of the SportsPress plugin.
**Q: How are event images generated?**
A: When an event is viewed or shared, a featured image is generated using the primary colors and logos of the participating teams.
---
*This plugin is not affiliated with or endorsed by ThemeBoy or the official SportsPress plugin.*

View File

@@ -1,115 +0,0 @@
=== Tonys Sportspress Enhancements ===
Contributors: (this should be a list of wordpress.org userid's)
Donate link: https://example.com/
Tags: comments, spam
Requires at least: 4.5
Tested up to: 6.5.3
Requires PHP: 5.6
Stable tag: 0.1.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Here is a short description of the plugin. This should be no more than 150 characters. No markup here.
== Description ==
This is the long description. No limit, and you can use Markdown (as well as in the following sections).
For backwards compatibility, if this section is missing, the full length of the short description will be used, and
Markdown parsed.
A few notes about the sections above:
* "Contributors" is a comma separated list of wp.org/wp-plugins.org usernames
* "Tags" is a comma separated list of tags that apply to the plugin
* "Requires at least" is the lowest version that the plugin will work on
* "Tested up to" is the highest version that you've *successfully used to test the plugin*. Note that it might work on
higher versions... this is just the highest one you've verified.
* Stable tag should indicate the Subversion "tag" of the latest stable version, or "trunk," if you use `/trunk/` for
stable.
Note that the `readme.txt` of the stable tag is the one that is considered the defining one for the plugin, so
if the `/trunk/readme.txt` file says that the stable tag is `4.3`, then it is `/tags/4.3/readme.txt` that'll be used
for displaying information about the plugin. In this situation, the only thing considered from the trunk `readme.txt`
is the stable tag pointer. Thus, if you develop in trunk, you can update the trunk `readme.txt` to reflect changes in
your in-development version, without having that information incorrectly disclosed about the current stable version
that lacks those changes -- as long as the trunk's `readme.txt` points to the correct stable tag.
If no stable tag is provided, it is assumed that trunk is stable, but you should specify "trunk" if that's where
you put the stable version, in order to eliminate any doubt.
== Installation ==
This section describes how to install the plugin and get it working.
e.g.
1. Upload `plugin-name.php` to the `/wp-content/plugins/` directory
1. Activate the plugin through the 'Plugins' menu in WordPress
1. Place `<?php do_action('plugin_name_hook'); ?>` in your templates
== Frequently Asked Questions ==
= A question that someone might have =
An answer to that question.
= What about foo bar? =
Answer to foo bar dilemma.
== Screenshots ==
1. This screen shot description corresponds to screenshot-1.(png|jpg|jpeg|gif). Note that the screenshot is taken from
the /assets directory or the directory that contains the stable readme.txt (tags or trunk). Screenshots in the /assets
directory take precedence. For example, `/assets/screenshot-1.png` would win over `/tags/4.3/screenshot-1.png`
(or jpg, jpeg, gif).
2. This is the second screen shot
== Changelog ==
= 1.0 =
* A change since the previous version.
* Another change.
= 0.5 =
* List versions from most recent at top to oldest at bottom.
== Upgrade Notice ==
= 1.0 =
Upgrade notices describe the reason a user should upgrade. No more than 300 characters.
= 0.5 =
This version fixes a security related bug. Upgrade immediately.
== Arbitrary section ==
You may provide arbitrary sections, in the same format as the ones above. This may be of use for extremely complicated
plugins where more information needs to be conveyed that doesn't fit into the categories of "description" or
"installation." Arbitrary sections will be shown below the built-in sections outlined above.
== A brief Markdown Example ==
Ordered list:
1. Some feature
1. Another feature
1. Something else about the plugin
Unordered list:
* something
* something else
* third thing
Here's a link to [WordPress](https://wordpress.org/ "Your favorite software") and one to [Markdown's Syntax Documentation][markdown syntax].
Titles are optional, naturally.
[markdown syntax]: https://daringfireball.net/projects/markdown/syntax
"Markdown is what the parser uses to process much of the readme file"
Markdown uses email style notation for blockquotes and I've been told:
> Asterisks for *emphasis*. Double it up for **strong**.
`<?php code(); // goes in backticks ?>`

576
templates/event-list.php Normal file
View File

@@ -0,0 +1,576 @@
<?php
/**
* Event List
*
* @author ThemeBoy
* @package SportsPress/Templates
* @version 2.7.23
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
$defaults = array(
'id' => null,
'title' => false,
'status' => 'default',
'format' => 'default',
'date' => 'default',
'date_from' => 'default',
'date_to' => 'default',
'date_past' => 'default',
'date_future' => 'default',
'date_relative' => 'default',
'day' => 'default',
'league' => null,
'season' => null,
'venue' => null,
'team' => null,
'teams_past' => null,
'date_before' => null,
'player' => null,
'number' => -1,
'show_team_logo' => get_option( 'sportspress_event_list_show_logos', 'no' ) == 'yes' ? true : false,
'link_events' => get_option( 'sportspress_link_events', 'yes' ) == 'yes' ? true : false,
'link_teams' => get_option( 'sportspress_link_teams', 'no' ) == 'yes' ? true : false,
'link_venues' => get_option( 'sportspress_link_venues', 'yes' ) == 'yes' ? true : false,
'responsive' => get_option( 'sportspress_enable_responsive_tables', 'no' ) == 'yes' ? true : false,
'sortable' => get_option( 'sportspress_enable_sortable_tables', 'yes' ) == 'yes' ? true : false,
'scrollable' => get_option( 'sportspress_enable_scrollable_tables', 'yes' ) == 'yes' ? true : false,
'paginated' => get_option( 'sportspress_event_list_paginated', 'yes' ) == 'yes' ? true : false,
'rows' => get_option( 'sportspress_event_list_rows', 10 ),
'order' => 'default',
'columns' => null,
'show_all_events_link' => false,
'show_title' => get_option( 'sportspress_event_list_show_title', 'yes' ) == 'yes' ? true : false,
'title_format' => get_option( 'sportspress_event_list_title_format', 'title' ),
'time_format' => get_option( 'sportspress_event_list_time_format', 'combined' ),
);
extract( $defaults, EXTR_SKIP );
$calendar = new SP_Calendar( $id );
if ( $status != 'default' ) {
$calendar->status = $status;
}
if ( $format != 'default' ) {
$calendar->event_format = $format;
}
if ( $date != 'default' ) {
$calendar->date = $date;
}
if ( $date_from != 'default' ) {
$calendar->from = $date_from;
}
if ( $date_to != 'default' ) {
$calendar->to = $date_to;
}
if ( $date_past != 'default' ) {
$calendar->past = $date_past;
}
if ( $date_future != 'default' ) {
$calendar->future = $date_future;
}
if ( $date_relative != 'default' ) {
$calendar->relative = $date_relative;
}
if ( $league ) {
$calendar->league = $league;
}
if ( $season ) {
$calendar->season = $season;
}
if ( $venue ) {
$calendar->venue = $venue;
}
if ( $team ) {
$calendar->team = $team;
}
if ( $teams_past ) {
$calendar->teams_past = $teams_past;
}
if ( $date_before ) {
$calendar->date_before = $date_before;
}
if ( $player ) {
$calendar->player = $player;
}
if ( $order != 'default' ) {
$calendar->order = $order;
}
if ( $day != 'default' ) {
$calendar->day = $day;
}
$data = $calendar->data();
$usecolumns = $calendar->columns;
if ( isset( $columns ) ) :
if ( is_array( $columns ) ) {
$usecolumns = $columns;
} else {
$usecolumns = explode( ',', $columns );
}
endif;
$title_format_raw = $title_format;
$is_awayhome_format = 'awayhome' === $title_format_raw;
if ( $is_awayhome_format ) {
$title_format = 'homeaway';
}
$home_label = $is_awayhome_format ? esc_attr__( 'Away', 'sportspress' ) : esc_attr__( 'Home', 'sportspress' );
$away_label = $is_awayhome_format ? esc_attr__( 'Home', 'sportspress' ) : esc_attr__( 'Away', 'sportspress' );
if ( $show_title && false === $title && $id ) :
$caption = $calendar->caption;
if ( $caption ) {
$title = $caption;
} else {
$title = get_the_title( $id );
}
endif;
$labels = array();
// Create a unique identifier based on the current time in microseconds
$identifier = uniqid( 'eventlist_' );
?>
<div class="sp-template sp-template-event-list">
<?php if ( $title ) { ?>
<h4 class="sp-table-caption"><?php echo wp_kses_post( $title ); ?></h4>
<?php } ?>
<div class="sp-table-wrapper">
<table class="sp-event-list sp-event-list-format-<?php echo esc_attr( $title_format ); ?> sp-data-table
<?php
if ( $paginated ) {
?>
sp-paginated-table
<?php
} if ( $sortable ) {
?>
sp-sortable-table
<?php
} if ( $responsive ) {
echo ' sp-responsive-table ' . esc_attr( $identifier ); } if ( $scrollable ) {
?>
sp-scrollable-table <?php } ?>" data-sp-rows="<?php echo esc_attr( $rows ); ?>">
<thead>
<tr>
<?php
echo '<th class="data-date">' . esc_attr__( 'Date', 'sportspress' ) . '</th>';
switch ( $title_format ) {
case 'homeaway':
if ( sp_column_active( $usecolumns, 'event' ) ) {
echo '<th class="data-home">' . esc_html( $home_label ) . '</th>';
}
if ( 'combined' == $time_format && sp_column_active( $usecolumns, 'time' ) ) {
echo '<th class="data-time">' . esc_attr__( 'Time/Results', 'sportspress' ) . '</th>';
$labels[] = esc_attr__( 'Time/Results', 'sportspress' );
} elseif ( in_array( $time_format, array( 'separate', 'results' ) ) && sp_column_active( $usecolumns, 'results' ) ) {
echo '<th class="data-results">' . esc_attr__( 'Results', 'sportspress' ) . '</th>';
}
if ( sp_column_active( $usecolumns, 'event' ) ) {
echo '<th class="data-away">' . esc_html( $away_label ) . '</th>';
}
if ( in_array( $time_format, array( 'separate', 'time' ) ) && sp_column_active( $usecolumns, 'time' ) ) {
echo '<th class="data-time">' . esc_attr__( 'Time', 'sportspress' ) . '</th>';
}
break;
default:
if ( sp_column_active( $usecolumns, 'event' ) ) {
if ( $title_format == 'teams' ) {
echo '<th class="data-teams">' . esc_attr__( 'Teams', 'sportspress' ) . '</th>';
} else {
echo '<th class="data-event">' . esc_attr__( 'Event', 'sportspress' ) . '</th>';
}
}
switch ( $time_format ) {
case 'separate':
if ( sp_column_active( $usecolumns, 'time' ) ) {
echo '<th class="data-time">' . esc_attr__( 'Time', 'sportspress' ) . '</th>';
}
if ( sp_column_active( $usecolumns, 'results' ) ) {
echo '<th class="data-results">' . esc_attr__( 'Results', 'sportspress' ) . '</th>';
}
break;
case 'time':
if ( sp_column_active( $usecolumns, 'time' ) ) {
echo '<th class="data-time">' . esc_attr__( 'Time', 'sportspress' ) . '</th>';
}
break;
case 'results':
if ( sp_column_active( $usecolumns, 'results' ) ) {
echo '<th class="data-results">' . esc_attr__( 'Results', 'sportspress' ) . '</th>';
}
break;
default:
if ( sp_column_active( $usecolumns, 'time' ) ) {
echo '<th class="data-time">' . esc_attr__( 'Time/Results', 'sportspress' ) . '</th>';
}
}
}
if ( sp_column_active( $usecolumns, 'league' ) ) {
echo '<th class="data-league">' . esc_attr__( 'League', 'sportspress' ) . '</th>';
}
if ( sp_column_active( $usecolumns, 'season' ) ) {
echo '<th class="data-season">' . esc_attr__( 'Season', 'sportspress' ) . '</th>';
}
if ( sp_column_active( $usecolumns, 'venue' ) ) {
echo '<th class="data-venue">' . esc_attr__( 'Venue', 'sportspress' ) . '</th>';
} else {
echo '<th style="display:none;" class="data-venue">' . esc_attr__( 'Venue', 'sportspress' ) . '</th>';
}
if ( sp_column_active( $usecolumns, 'article' ) ) {
echo '<th class="data-article">' . esc_attr__( 'Article', 'sportspress' ) . '</th>';
}
if ( sp_column_active( $usecolumns, 'day' ) ) {
echo '<th class="data-day">' . esc_attr__( 'Match Day', 'sportspress' ) . '</th>';
}
do_action( 'sportspress_event_list_head_row', $usecolumns );
?>
</tr>
</thead>
<tbody>
<?php
$i = 0;
if ( is_numeric( $number ) && $number > 0 ) {
$limit = $number;
}
foreach ( $data as $event ) :
if ( isset( $limit ) && $i >= $limit ) {
continue;
}
$teams = get_post_meta( $event->ID, 'sp_team' );
$video = get_post_meta( $event->ID, 'sp_video', true );
$status = get_post_meta( $event->ID, 'sp_status', true );
$main_results = apply_filters( 'sportspress_event_list_main_results', sp_get_main_results( $event ), $event->ID );
$reverse_results = $is_awayhome_format;
$reverse_teams = false;
if ( 'homeaway' === $title_format ) {
$reverse_teams = $is_awayhome_format;
} elseif ( 'teams' === $title_format ) {
$reverse_teams = get_option( 'sportspress_event_reverse_teams', 'no' ) === 'yes' ? true : false;
}
if ( $reverse_results ) {
$main_results = array_reverse( $main_results, true );
}
$teams_output = '';
$team_class = '';
$teams_array = array();
$team_logos = array();
if ( $teams ) :
foreach ( $teams as $t => $team ) :
$name = sp_team_short_name( $team );
if ( $name ) :
$name = '<meta itemprop="name" content="' . $name . '">' . $name;
if ( $show_team_logo ) :
if ( has_post_thumbnail( $team ) ) :
$logo = '<span class="team-logo">' . sp_get_logo( $team, 'mini', array( 'itemprop' => 'url' ) ) . '</span>';
$team_logos[] = $logo;
$team_class .= ' has-logo';
if ( $t ) :
$name = $logo . ' ' . $name;
else :
$name .= ' ' . $logo;
endif;
endif;
endif;
if ( $link_teams ) :
$team_output = '<a href="' . get_post_permalink( $team ) . '" itemprop="url">' . $name . '</a>';
else :
$team_output = $name;
endif;
$team_result = sp_array_value( $main_results, $team, null );
if ( $team_result != null ) :
if ( $usecolumns != null && ! in_array( 'time', $usecolumns ) ) :
$team_output .= ' (' . $team_result . ')';
endif;
endif;
$teams_array[] = $team_output;
$teams_output .= $team_output . '<br>';
endif;
endforeach;
else :
$teams_output .= '&mdash;';
endif;
echo '<tr class="sp-row sp-post' . ( $i % 2 == 0 ? ' alternate' : '' ) . ' sp-row-no-' . esc_attr( $i ) . '" itemscope itemtype="http://schema.org/SportsEvent">';
$date_html = '<date>' . get_post_time( 'Y-m-d H:i:s', false, $event ) . '</date>' . apply_filters( 'sportspress_event_date', get_post_time( get_option( 'date_format' ), false, $event, true ), $event->ID );
if ( $link_events ) {
$date_html = '<a href="' . get_post_permalink( $event->ID, false, true ) . '" itemprop="url">' . $date_html . '</a>';
}
echo '<td class="data-date" itemprop="startDate" content="' . esc_attr( mysql2date( 'Y-m-d\TH:i:sP', $event->post_date ) ) . '" data-label="' . esc_attr__( 'Date', 'sportspress' ) . '">' . wp_kses( $date_html, array( 'a' => array( 'href' => array(), 'itemprop' => array() ), 'date' => array() ) ) . '</td>';
// Check if the reverse_teams option is selected and alter the teams order
if ( $reverse_teams ) {
$teams_array = array_reverse( $teams_array, true );
}
switch ( $title_format ) {
case 'homeaway':
if ( sp_column_active( $usecolumns, 'event' ) ) {
$team = array_shift( $teams_array );
echo '<td class="data-home' . esc_attr( $team_class ) . '" itemprop="competitor" itemscope itemtype="http://schema.org/SportsTeam" data-label="' . esc_attr( $home_label ) . '">' . wp_kses_post( $team ) . '</td>';
}
if ( 'combined' == $time_format && sp_column_active( $usecolumns, 'time' ) ) {
echo '<td class="data-time ' . esc_attr( $status ) . '" data-label="' . esc_attr__( 'Time/Results', 'sportspress' ) . '">';
if ( $link_events ) {
echo '<a href="' . esc_url( get_post_permalink( $event->ID, false, true ) ) . '" itemprop="url">';
}
if ( ! empty( $main_results ) ) :
echo wp_kses_post( implode( ' - ', $main_results ) );
else :
echo '<date>&nbsp;' . wp_kses_post( get_post_time( 'H:i:s', false, $event ) ) . '</date>' . wp_kses_post( apply_filters( 'sportspress_event_time', sp_get_time( $event ), $event->ID ) );
endif;
if ( $link_events ) {
echo '</a>';
}
echo '</td>';
} elseif ( in_array( $time_format, array( 'separate', 'results' ) ) && sp_column_active( $usecolumns, 'results' ) ) {
echo '<td class="data-results" data-label="' . esc_attr__( 'Results', 'sportspress' ) . '">';
if ( $link_events ) {
echo '<a href="' . esc_url( get_post_permalink( $event->ID, false, true ) ) . '" itemprop="url">';
}
if ( ! empty( $main_results ) ) :
echo wp_kses_post( implode( ' - ', $main_results ) );
else :
echo '-';
endif;
if ( $link_events ) {
echo '</a>';
}
echo '</td>';
}
if ( sp_column_active( $usecolumns, 'event' ) ) {
$team = array_shift( $teams_array );
echo '<td class="data-away' . esc_attr( $team_class ) . '" itemprop="competitor" itemscope itemtype="http://schema.org/SportsTeam" data-label="' . esc_attr( $away_label ) . '">' . wp_kses_post( $team ) . '</td>';
}
if ( in_array( $time_format, array( 'separate', 'time' ) ) && sp_column_active( $usecolumns, 'time' ) ) {
echo '<td class="data-time ' . esc_attr( $status ) . '" data-label="' . esc_attr__( 'Time', 'sportspress' ) . '">';
if ( $link_events ) {
echo '<a href="' . esc_url( get_post_permalink( $event->ID, false, true ) ) . '" itemprop="url">';
}
echo '<date>&nbsp;' . wp_kses_post( get_post_time( 'H:i:s', false, $event ) ) . '</date>' . wp_kses_post( apply_filters( 'sportspress_event_time', sp_get_time( $event ), $event->ID ) );
if ( $link_events ) {
echo '</a>';
}
echo '</td>';
}
break;
default:
if ( sp_column_active( $usecolumns, 'event' ) ) {
if ( $title_format == 'teams' ) {
echo '<td class="data-event data-teams" data-label="' . esc_attr__( 'Teams', 'sportspress' ) . '">' . wp_kses_post( $teams_output ) . '</td>';
} else {
$title_html = implode( ' ', $team_logos ) . ' ' . $event->post_title;
if ( $link_events ) {
$title_html = '<a href="' . get_post_permalink( $event->ID, false, true ) . '" itemprop="url name">' . $title_html . '</a>';
}
echo '<td class="data-event" data-label="' . esc_attr__( 'Event', 'sportspress' ) . '">' . wp_kses_post( $title_html ) . '</td>';
}
}
switch ( $time_format ) {
case 'separate':
if ( sp_column_active( $usecolumns, 'time' ) ) {
echo '<td class="data-time ' . esc_attr( $status ) . '" data-label="' . esc_attr__( 'Time', 'sportspress' ) . '">';
if ( $link_events ) {
echo '<a href="' . esc_url( get_post_permalink( $event->ID, false, true ) ) . '" itemprop="url">';
}
echo '<date>&nbsp;' . wp_kses_post( get_post_time( 'H:i:s', false, $event ) ) . '</date>' . wp_kses_post( apply_filters( 'sportspress_event_time', sp_get_time( $event ), $event->ID ) );
if ( $link_events ) {
echo '</a>';
}
echo '</td>';
}
if ( sp_column_active( $usecolumns, 'results' ) ) {
echo '<td class="data-results" data-label="' . esc_attr__( 'Results', 'sportspress' ) . '">';
if ( $link_events ) {
echo '<a href="' . esc_url( get_post_permalink( $event->ID, false, true ) ) . '" itemprop="url">';
}
if ( ! empty( $main_results ) ) :
echo wp_kses_post( implode( ' - ', $main_results ) );
else :
echo '-';
endif;
if ( $link_events ) {
echo '</a>';
}
echo '</td>';
}
break;
case 'time':
if ( sp_column_active( $usecolumns, 'time' ) ) {
echo '<td class="data-time ' . esc_attr( $status ) . '" data-label="' . esc_attr__( 'Time', 'sportspress' ) . '">';
if ( $link_events ) {
echo '<a href="' . esc_url( get_post_permalink( $event->ID, false, true ) ) . '" itemprop="url">';
}
echo '<date>&nbsp;' . wp_kses_post( get_post_time( 'H:i:s', false, $event ) ) . '</date>' . wp_kses_post( apply_filters( 'sportspress_event_time', sp_get_time( $event ), $event->ID ) );
if ( $link_events ) {
echo '</a>';
}
echo '</td>';
}
break;
case 'results':
if ( sp_column_active( $usecolumns, 'results' ) ) {
echo '<td class="data-results" data-label="' . esc_attr__( 'Results', 'sportspress' ) . '">';
if ( $link_events ) {
echo '<a href="' . esc_url( get_post_permalink( $event->ID, false, true ) ) . '" itemprop="url">';
}
if ( ! empty( $main_results ) ) :
echo wp_kses_post( implode( ' - ', $main_results ) );
else :
echo '-';
endif;
if ( $link_events ) {
echo '</a>';
}
echo '</td>';
}
break;
default:
if ( sp_column_active( $usecolumns, 'time' ) ) {
echo '<td class="data-time ' . esc_attr( $status ) . '" data-label="' . esc_attr__( 'Time/Results', 'sportspress' ) . '">';
if ( $link_events ) {
echo '<a href="' . esc_url( get_post_permalink( $event->ID, false, true ) ) . '" itemprop="url">';
}
if ( ! empty( $main_results ) ) :
echo wp_kses_post( implode( ' - ', $main_results ) );
else :
echo '<date>&nbsp;' . wp_kses_post( get_post_time( 'H:i:s', false, $event ) ) . '</date>' . wp_kses_post( apply_filters( 'sportspress_event_time', sp_get_time( $event ), $event->ID ) );
endif;
if ( $link_events ) {
echo '</a>';
}
echo '</td>';
}
}
}
if ( sp_column_active( $usecolumns, 'league' ) ) :
echo '<td class="data-league" data-label="' . esc_attr__( 'League', 'sportspress' ) . '">';
$leagues = get_the_terms( $event->ID, 'sp_league' );
if ( $leagues ) :
echo wp_kses_post( implode( ', ', wp_list_pluck( $leagues, 'name' ) ) );
endif;
echo '</td>';
endif;
if ( sp_column_active( $usecolumns, 'season' ) ) :
echo '<td class="data-season" data-label="' . esc_attr__( 'Season', 'sportspress' ) . '">';
$seasons = get_the_terms( $event->ID, 'sp_season' );
if ( $seasons ) :
echo wp_kses_post( implode( ', ', wp_list_pluck( $seasons, 'name' ) ) );
endif;
echo '</td>';
endif;
if ( sp_column_active( $usecolumns, 'venue' ) ) :
echo '<td class="data-venue" data-label="' . esc_attr__( 'Venue', 'sportspress' ) . '" itemprop="location" itemscope itemtype="http://schema.org/Place">';
echo '<div itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">';
if ( $link_venues ) :
the_terms( $event->ID, 'sp_venue' );
else :
$venues = get_the_terms( $event->ID, 'sp_venue' );
if ( $venues ) :
echo wp_kses_post( implode( ', ', wp_list_pluck( $venues, 'name' ) ) );
endif;
endif;
echo '</div>';
echo '</td>';
else :
echo '<td style="display:none;" class="data-venue" data-label="' . esc_attr__( 'Venue', 'sportspress' ) . '" itemprop="location" itemscope itemtype="http://schema.org/Place">';
echo '<div itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">';
esc_attr_e( 'N/A', 'sportspress' );
echo '</div>';
echo '</td>';
endif;
if ( sp_column_active( $usecolumns, 'article' ) ) :
echo '<td class="data-article" data-label="' . esc_attr__( 'Article', 'sportspress' ) . '">';
if ( $link_events ) {
echo '<a href="' . esc_url( get_post_permalink( $event->ID, false, true ) ) . '" itemprop="url">';
}
if ( $video ) :
echo '<div class="dashicons dashicons-video-alt"></div>';
elseif ( has_post_thumbnail( $event->ID ) ) :
echo '<div class="dashicons dashicons-camera"></div>';
endif;
if ( $event->post_content !== null ) :
if ( $event->post_status == 'publish' ) :
esc_attr_e( 'Recap', 'sportspress' );
else :
esc_attr_e( 'Preview', 'sportspress' );
endif;
endif;
if ( $link_events ) {
echo '</a>';
}
echo '</td>';
endif;
if ( sp_column_active( $usecolumns, 'day' ) ) :
echo '<td class="data-day" data-label="' . esc_attr__( 'Match Day', 'sportspress' ) . '">';
$day = get_post_meta( $event->ID, 'sp_day', true );
if ( '' == $day ) {
echo '-';
} else {
echo wp_kses_post( $day );
}
echo '</td>';
endif;
do_action( 'sportspress_event_list_row', $event, $usecolumns );
echo '</tr>';
$i++;
endforeach;
?>
</tbody>
</table>
</div>
<?php
// If responsive tables are enabled then load the inline css code
if ( $responsive ) {
// sportspress_responsive_tables_css( $identifier );
}
if ( $id && $show_all_events_link ) {
echo '<div class="sp-calendar-link sp-view-all-link"><a href="' . esc_url( get_permalink( $id ) ) . '">' . esc_attr__( 'View all events', 'sportspress' ) . '</a></div>';
}
?>
</div>

166
templates/event-results.php Normal file
View File

@@ -0,0 +1,166 @@
<?php
/**
* Event Results
*
* @author ThemeBoy
* @package SportsPress/Templates
* @version 2.7.1
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
if ( get_option( 'sportspress_event_show_results', 'yes' ) === 'no' ) {
return;
}
if ( ! isset( $id ) ) {
$id = get_the_ID();
}
$event = new SP_Event( $id );
$status = $event->status();
if ( 'results' != $status ) {
return;
}
if ( ! isset( $caption ) ) {
$caption = esc_attr__( 'Results', 'sportspress' );
}
// Get event result data
$data = $event->results();
// The first row should be column labels
$labels = $data[0];
// Remove the first row to leave us with the actual data
unset( $data[0] );
$data = array_filter( $data );
if ( empty( $data ) ) {
return false;
}
$scrollable = get_option( 'sportspress_enable_scrollable_tables', 'yes' ) == 'yes' ? true : false;
$link_teams = get_option( 'sportspress_link_teams', 'no' ) == 'yes' ? true : false;
$show_outcomes = array_key_exists( 'outcome', $labels );
// Initialize
$output = '';
$table_rows = '';
$i = 0;
// Event Results row order is controlled in SportsPress > Settings > Events > Event Results.
$row_order = get_option( 'tony_sportspress_event_results_row_order', '' );
if ( '' === $row_order ) {
// Backward compatibility with the legacy checkbox option.
$legacy_away_first = get_option( 'tony_sportspress_event_results_away_first', 'no' ) === 'yes';
$row_order = $legacy_away_first ? 'away_home' : 'home_away';
}
$teams = array_values( array_filter( array_map( 'absint', (array) get_post_meta( $id, 'sp_team', false ) ) ) );
if ( 'away_home' === $row_order ) {
$teams = array_reverse( $teams );
}
if ( ! empty( $teams ) ) {
$ordered = array();
foreach ( $teams as $index => $team_id ) {
if ( array_key_exists( $team_id, $data ) ) {
$ordered[ $team_id ] = $data[ $team_id ];
continue;
}
// SportsPress can store positional rows in team order (0,1,...) depending on context.
if ( array_key_exists( $index, $data ) ) {
$ordered[ $team_id ] = $data[ $index ];
}
}
foreach ( $data as $team_id => $result ) {
if ( ! array_key_exists( $team_id, $ordered ) ) {
$ordered[ $team_id ] = $result;
}
}
if ( ! empty( $ordered ) ) {
$data = $ordered;
}
}
foreach ( $data as $team_id => $result ) :
if ( $show_outcomes ) :
$outcomes = array();
$result_outcome = sp_array_value( $result, 'outcome' );
if ( ! is_array( $result_outcome ) ) :
$outcomes = array( '&mdash;' );
else :
foreach ( $result_outcome as $outcome ) :
$the_outcome = get_page_by_path( $outcome, OBJECT, 'sp_outcome' );
if ( is_object( $the_outcome ) ) :
$outcomes[] = $the_outcome->post_title;
endif;
endforeach;
endif;
endif;
unset( $result['outcome'] );
$table_rows .= '<tr class="' . ( $i % 2 == 0 ? 'odd' : 'even' ) . '">';
$team_name = sp_team_short_name( $team_id );
if ( $link_teams && sp_post_exists( $team_id ) ) :
$team_name = '<a href="' . get_post_permalink( $team_id ) . '">' . $team_name . '</a>';
endif;
$table_rows .= '<td class="data-name">' . $team_name . '</td>';
foreach ( $labels as $key => $label ) :
if ( in_array( $key, array( 'name', 'outcome' ) ) ) {
continue;
}
if ( array_key_exists( $key, $result ) && $result[ $key ] != '' ) :
$value = $result[ $key ];
else :
$value = apply_filters( 'sportspress_event_empty_result_string', '&mdash;' );
endif;
$table_rows .= '<td class="data-' . $key . '">' . $value . '</td>';
endforeach;
if ( $show_outcomes ) :
$table_rows .= '<td class="data-outcome">' . implode( ', ', $outcomes ) . '</td>';
endif;
$table_rows .= '</tr>';
$i++;
endforeach;
if ( empty( $table_rows ) ) :
return false;
else :
$output .= '<h4 class="sp-table-caption">' . $caption . '</h4>';
$output .= '<div class="sp-table-wrapper">' .
'<table class="sp-event-results sp-data-table' . ( $scrollable ? ' sp-scrollable-table' : '' ) . '"><thead>' .
'<th class="data-name">' . esc_attr__( 'Team', 'sportspress' ) . '</th>';
foreach ( $labels as $key => $label ) :
$output .= '<th class="data-' . $key . '">' . $label . '</th>';
endforeach;
$output .= '</tr>' . '</thead>' . '<tbody>';
$output .= $table_rows;
$output .= '</tbody>' . '</table>' . '</div>';
endif;
?>
<div class="sp-template sp-template-event-results">
<?php echo wp_kses_post( $output ); ?>
</div>

View File

@@ -0,0 +1,81 @@
<?php
/**
* Tests for custom event permalink query behavior.
*
* @package Tonys_Sportspress_Enhancements
*/
/**
* Event permalink query tests.
*/
class Test_SP_Event_Permalink extends WP_UnitTestCase {
/**
* Preserve global main query references for each test.
*
* @var WP_Query
*/
private $original_wp_query;
/**
* Preserve global main query references for each test.
*
* @var WP_Query
*/
private $original_wp_the_query;
/**
* Set up test case state.
*/
public function set_up(): void {
parent::set_up();
$this->original_wp_query = $GLOBALS['wp_query'];
$this->original_wp_the_query = $GLOBALS['wp_the_query'];
set_current_screen( 'front' );
}
/**
* Restore global query references.
*/
public function tear_down(): void {
$GLOBALS['wp_query'] = $this->original_wp_query;
$GLOBALS['wp_the_query'] = $this->original_wp_the_query;
set_current_screen( 'front' );
parent::tear_down();
}
/**
* The admin event list query should not be altered by permalink handling.
*/
public function test_admin_event_queries_are_not_modified() {
set_current_screen( 'edit-sp_event' );
$query = new WP_Query();
$query->set( 'post_type', 'sp_event' );
$query->set( 'p', 123 );
$query->set( 'post_status', 'future' );
custom_event_parse_request( $query );
$this->assertSame( 'future', $query->get( 'post_status' ) );
$this->assertSame( 123, $query->get( 'p' ) );
}
/**
* Front-end single event requests should include future posts.
*/
public function test_frontend_single_event_queries_include_future_posts() {
$query = new WP_Query();
$query->set( 'post_type', 'sp_event' );
$query->set( 'p', 456 );
$GLOBALS['wp_query'] = $query;
$GLOBALS['wp_the_query'] = $query;
custom_event_parse_request( $query );
$this->assertSame( 'sp_event', $query->get( 'post_type' ) );
$this->assertSame( 456, $query->get( 'p' ) );
$this->assertSame( array( 'publish', 'future' ), $query->get( 'post_status' ) );
}
}

View File

@@ -1,19 +1,41 @@
<?php
/**
* Plugin Name: Tonys SportsPress Enhancements
* Plugin URI: PLUGIN SITE HERE
* Plugin URI: https://github.com/anthonyscorrea/tonys-sportspress-enhancements
* Description: Suite of SportsPress Enhancements
* Author: YOUR NAME HERE
* Author URI: YOUR SITE HERE
* Author: Tony Correa
* Author URI: https://github.com/anthonyscorrea/
* Text Domain: tonys-sportspress-enhancements
* Domain Path: /languages
* Version: 0.1.0
* Version: 0.1.6
*
* @package Tonys_Sportspress_Enhancements
*/
if ( ! defined( 'TONY_SPORTSPRESS_ENHANCEMENTS_VERSION' ) ) {
define( 'TONY_SPORTSPRESS_ENHANCEMENTS_VERSION', '0.1.6' );
}
if ( ! defined( 'TONY_SPORTSPRESS_ENHANCEMENTS_FILE' ) ) {
define( 'TONY_SPORTSPRESS_ENHANCEMENTS_FILE', __FILE__ );
}
if ( ! defined( 'TONY_SPORTSPRESS_ENHANCEMENTS_DIR' ) ) {
define( 'TONY_SPORTSPRESS_ENHANCEMENTS_DIR', plugin_dir_path( __FILE__ ) );
}
if ( ! defined( 'TONY_SPORTSPRESS_ENHANCEMENTS_URL' ) ) {
define( 'TONY_SPORTSPRESS_ENHANCEMENTS_URL', plugin_dir_url( __FILE__ ) );
}
// Include other files here
require_once plugin_dir_path(__FILE__) . 'includes/open-graph-tags.php';
require_once plugin_dir_path(__FILE__) . 'includes/featured-image-generator.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-event-permalink.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-event-permalink.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-event-csv.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-event-admin-week-filter.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-event-quick-edit-officials.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-event-team-ordering.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-printable-calendars.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-schedule-exporter.php';
require_once plugin_dir_path(__FILE__) . 'includes/sp-venue-meta.php';