initial commit.

This commit is contained in:
Chris 2025-08-02 22:21:45 +01:00
commit 195a208b5a
7 changed files with 245 additions and 0 deletions

6
html/live-score.html Normal file
View File

@ -0,0 +1,6 @@
<div id="live-score-container">
<h3>Live Match Score</h3>
<div id="live-score-content">
<em>Loading live score...</em>
</div>
</div>

View File

@ -0,0 +1,18 @@
<div id="score-controls">
<h4>Rugby Score Controls</h4>
<label>Minute: <input type="number" id="score-minute" value="0" min="0"></label><br>
<label>Team:
<select id="score-team">
<option value="home">Home</option>
<option value="away">Away</option>
</select>
</label><br>
<button class="score-btn" data-type="start">Start Match</button>
<button class="score-btn" data-type="half_time">Half Time</button>
<button class="score-btn" data-type="full_time">Full Time</button>
<button class="score-btn" data-type="try">Try</button>
<button class="score-btn" data-type="conversion">Conversion</button>
<button class="score-btn" data-type="penalty_kick">Penalty Kick</button>
<button class="score-btn" data-type="yellow_card">Yellow Card</button>
<button class="score-btn" data-type="red_card">Red Card</button>
</div>

4
html/scoreboard.html Normal file
View File

@ -0,0 +1,4 @@
<div id="live-scoreboard">
<h3>Scoreboard Timeline</h3>
<ul id="scoreboard-list"></ul>
</div>

23
js/live-score.js Normal file
View File

@ -0,0 +1,23 @@
jQuery(document).ready(function ($) {
fetch(LiveScoreAjax.templatesUrl + 'live-score.html')
.then(r => r.text())
.then(html => {
const container = $(html).appendTo('[data-live-score-shortcode]');
function fetchLiveScore() {
$.get(LiveScoreAjax.ajaxUrl, { action: 'get_live_score' }, function (res) {
if (res.success) {
const score = res.data.score;
$('#live-score-content').html(`
<strong>${res.data.event_title}</strong><br>
<span>Home: ${score.home} | Away: ${score.away}</span>
`);
} else {
$('#live-score-content').html('<em>No live event at the moment.</em>');
}
});
}
fetchLiveScore();
setInterval(fetchLiveScore, 10000); // Poll every 10 seconds
});
});

35
js/scoreboard-controls.js Normal file
View File

@ -0,0 +1,35 @@
jQuery(document).ready(function ($) {
if (!scoreboardData.canEdit) return;
fetch(scoreboardData.templatesUrl + 'scoreboard-controls.html')
.then(r => r.text())
.then(html => {
const panel = $(html).appendTo('.entry-content');
panel.on('click', '.score-btn', function () {
const type = $(this).data('type');
const minute = parseInt($('#score-minute').val(), 10);
const team = $('#score-team').val();
const newEvent = { type, minute, team };
let timelineData = [];
try {
timelineData = JSON.parse(scoreboardData.timeline);
if (!Array.isArray(timelineData)) timelineData = [];
} catch (e) { }
timelineData.push(newEvent);
$.post(scoreboardData.ajaxUrl, {
action: 'update_scoreboard',
event_id: scoreboardData.eventId,
timeline: JSON.stringify(timelineData)
}, function (res) {
if (res.success) {
alert('Event added!');
location.reload(); // optionally trigger re-render instead
}
});
});
});
});

14
js/scoreboard.js Normal file
View File

@ -0,0 +1,14 @@
jQuery(document).ready(function ($) {
fetch(scoreboardData.templatesUrl + 'scoreboard.html')
.then(r => r.text())
.then(html => {
const container = $(html).appendTo('.entry-content');
const data = JSON.parse(scoreboardData.timeline);
const list = container.find('#scoreboard-list');
data.forEach(ev => {
const item = $(`<li>${ev.minute}' - ${ev.team || 'N/A'} - ${ev.type}</li>`);
list.append(item);
});
});
});

145
scoreboard.php Normal file
View File

@ -0,0 +1,145 @@
<?php
/**
* Plugin Name: Sportspress Scoreboard Extension
* Description: Adds a live scoreboard with edit controls for users with permission.
* Version: 1.0
*/
add_action('init', function() {
add_role('score_editor', 'Score Editor', ['sportspress_can_control_score' => true]);
});
register_activation_hook(__FILE__, function() {
$role = get_role('administrator');
if ($role) {
$role->add_cap('sportspress_can_control_score');
}
});
register_deactivation_hook(__FILE__, function() {
$role = get_role('administrator');
if ($role) {
$role->remove_cap('sportspress_can_control_score');
}
});
// Add meta box for scoreboard timeline
add_action('add_meta_boxes', function() {
add_meta_box('scoreboard_timeline', 'Scoreboard Timeline', 'render_scoreboard_meta_box', 'sp_event');
});
function render_scoreboard_meta_box($post) {
$json = get_post_meta($post->ID, '_scoreboard_timeline', true);
$json = $json ? esc_textarea($json) : '{}';
echo '<textarea style="width:100%;height:200px;" name="scoreboard_timeline_json">' . $json . '</textarea>';
}
// Save scoreboard meta
add_action('save_post_sp_event', function($post_id) {
if (isset($_POST['scoreboard_timeline_json'])) {
update_post_meta($post_id, '_scoreboard_timeline', wp_unslash($_POST['scoreboard_timeline_json']));
}
});
add_action('wp_enqueue_scripts', function() {
if (is_singular('sp_event')) {
wp_enqueue_script('scoreboard-js', plugins_url('/js/scoreboard.js', __FILE__), ['jquery'], null, true);
wp_enqueue_script('scoreboard-controls-js', plugins_url('/js/scoreboard-controls.js', __FILE__), ['jquery'], null, true);
wp_localize_script('scoreboard-js', 'scoreboardData', [
'ajaxUrl' => admin_url('admin-ajax.php'),
'eventId' => get_the_ID(),
'canEdit' => current_user_can('sportspress_can_control_score'),
'timeline' => get_post_meta(get_the_ID(), '_scoreboard_timeline', true) ?: '{}',
'templatesUrl' => plugins_url('/html/', __FILE__)
]);
}
});
// AJAX endpoint for saving scoreboard
add_action('wp_ajax_update_scoreboard', function() {
if (!current_user_can('sportspress_can_control_score')) {
wp_send_json_error('Unauthorized');
}
$event_id = intval($_POST['event_id']);
$timeline = wp_unslash($_POST['timeline']);
update_post_meta($event_id, '_scoreboard_timeline', $timeline);
wp_send_json_success();
});
add_shortcode('live_score', function($atts) {
ob_start();
?>
<div id="live-score-widget" data-refresh="1">
<strong>Loading live score...</strong>
</div>
<?php
return ob_get_clean();
});
add_action('wp_ajax_nopriv_get_live_score', 'get_live_score_callback');
add_action('wp_ajax_get_live_score', 'get_live_score_callback');
function get_live_score_callback() {
$args = [
'post_type' => 'sp_event',
'posts_per_page' => 1,
'meta_query' => [
[
'key' => 'is_live',
'value' => '1',
'compare' => '='
]
]
];
$live_event = get_posts($args);
if (!$live_event) {
wp_send_json_error('No live event');
}
$event = $live_event[0];
$timeline = get_post_meta($event->ID, '_scoreboard_timeline', true);
$timeline_data = json_decode($timeline, true);
// Simplified for display: extract latest score entry
$latest = end($timeline_data);
wp_send_json_success([
'event_id' => $event->ID,
'event_title' => get_the_title($event),
'score' => $latest ?? ['home' => 0, 'away' => 0]
]);
}
add_action('wp_enqueue_scripts', function() {
wp_enqueue_script('live-score-script', plugins_url('/js/live-score.js', __FILE__), ['jquery'], null, true);
wp_localize_script('live-score-script', 'LiveScoreAjax', [
'ajaxUrl' => admin_url('admin-ajax.php'),
]);
});
// function scoreboard_add_to_event_page($content) {
// if (get_post_type() === 'sp_event') {
// ob_start();
// render_scoreboard_timeline();
// $timeline_html = ob_get_clean();
// return $timeline_html . $content; // Prepend it
// }
// return $content;
// }
// add_filter('the_content', 'scoreboard_add_to_event_page');
// // Display scoreboard on match report
// add_action('sportspress_after_event_content', 'render_scoreboard_timeline');
// function render_scoreboard_timeline() {
// echo '<div style="background:#f0f0f0;padding:10px;margin-bottom:10px;">Scoreboard timeline loaded.</div>';
// if (current_user_can('scoreboard_can_control')) {
// echo '<div style="background:#d1ffd1;padding:10px;margin-bottom:10px;">User CAN control scoreboard.</div>';
// //include plugin_dir_path(__FILE__) . 'templates/scoreboard-controls.php';
// } else {
// echo '<div style="background:#ffe5e5;padding:10px;margin-bottom:10px;">User CANNOT control scoreboard.</div>';
// }
// //include plugin_dir_path(__FILE__) . 'templates/scoreboard-timeline.php';
// }