various improvements to make release 1 complete
This commit is contained in:
@@ -22,6 +22,8 @@ class Swi_Foot_Shortcodes
|
||||
add_shortcode('swi_foot_match_round', array($this, 'match_round_shortcode'));
|
||||
add_shortcode('swi_foot_standings', array($this, 'standings_shortcode'));
|
||||
add_shortcode('swi_foot_roster', array($this, 'roster_shortcode'));
|
||||
add_shortcode('swi_foot_bench', array($this, 'bench_shortcode'));
|
||||
add_shortcode('swi_foot_referees', array($this, 'referees_shortcode'));
|
||||
add_shortcode('swi_foot_events', array($this, 'events_shortcode'));
|
||||
add_shortcode('swi_foot_match_data', array($this, 'match_data_shortcode'));
|
||||
add_shortcode('swi_foot_match_home_team_logo', array($this, 'match_home_team_logo_shortcode'));
|
||||
@@ -44,6 +46,26 @@ class Swi_Foot_Shortcodes
|
||||
return $vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render error message, distinguishing between "data not available" (406) and other errors
|
||||
* @param WP_Error $error The error object
|
||||
* @return string HTML-formatted error message
|
||||
*/
|
||||
private function render_error_message($error)
|
||||
{
|
||||
if (!is_wp_error($error)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Check if this is a "data not yet available" error (HTTP 406)
|
||||
if ($error->get_error_code() === 'data_not_available') {
|
||||
return '<div class="swi-foot-data-warning">⏳ ' . __('Data not yet available', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
// For other errors, show grey "no data available" message
|
||||
return '<div class="swi-foot-data-unavailable">ℹ️ ' . __('No data available', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle internal requests for team logo images
|
||||
* URL format: /?swi_foot_team_logo=team_id&position=home|away|event
|
||||
@@ -198,7 +220,7 @@ class Swi_Foot_Shortcodes
|
||||
$match_data = $this->get_match_data($atts);
|
||||
|
||||
if (!$match_data) {
|
||||
return '<span class="swi-foot-error">' . __('Match data not available', 'swi_foot_matchdata') . '</span>';
|
||||
return '<div class="swi-foot-error">' . __('Match data not available', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
ob_start();
|
||||
@@ -388,6 +410,139 @@ class Swi_Foot_Shortcodes
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render match bench (team staff) list
|
||||
* Usage: [swi_foot_bench match_id="12345"]
|
||||
* Lists staff members (name and role) for both home and away teams
|
||||
*/
|
||||
public function bench_shortcode($atts)
|
||||
{
|
||||
$atts = shortcode_atts(array(
|
||||
'match_id' => '',
|
||||
'side' => '' // 'home' or 'away', shows both if not specified
|
||||
), $atts);
|
||||
|
||||
$match_id = $atts['match_id'];
|
||||
if (empty($match_id)) {
|
||||
return '<div class="swi-foot-error">' . __('Match ID required', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
$bench = $this->api->get_match_bench($match_id);
|
||||
|
||||
if (is_wp_error($bench)) {
|
||||
return $this->render_error_message($bench);
|
||||
}
|
||||
|
||||
if (empty($bench)) {
|
||||
return '<div class="swi-foot-notice">' . __('No bench data available', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
// Normalize side parameter
|
||||
$side = strtolower(trim($atts['side']));
|
||||
$show_side_filter = !empty($side) && in_array($side, array('home', 'away'), true);
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="swi-foot-bench-container" data-match-id="<?php echo esc_attr($match_id); ?>">
|
||||
<?php
|
||||
// Group bench players by team
|
||||
$home_staff = array_filter($bench, function($person) {
|
||||
return isset($person['isHomeTeam']) && $person['isHomeTeam'] === true;
|
||||
});
|
||||
$away_staff = array_filter($bench, function($person) {
|
||||
return isset($person['isHomeTeam']) && $person['isHomeTeam'] === false;
|
||||
});
|
||||
|
||||
// If side is specified, filter to only that side
|
||||
if ($show_side_filter) {
|
||||
if ($side === 'home') {
|
||||
$away_staff = array();
|
||||
} else {
|
||||
$home_staff = array();
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?php if (!empty($home_staff)): ?>
|
||||
<div class="bench-team bench-home">
|
||||
<?php if (!$show_side_filter): ?>
|
||||
<h3><?php echo esc_html($home_staff[array_key_first($home_staff)]['teamName'] ?? __('Home Team', 'swi_foot_matchdata')); ?></h3>
|
||||
<?php endif; ?>
|
||||
<ul class="bench-list">
|
||||
<?php foreach ($home_staff as $person): ?>
|
||||
<li class="bench-person">
|
||||
<?php echo esc_html($person['personName'] ?? ''); ?>
|
||||
<?php if (!empty($person['roleCategoryName'])): ?>
|
||||
<span class="swi-foot-role">(<?php echo esc_html($person['roleCategoryName']); ?>)</span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($away_staff)): ?>
|
||||
<div class="bench-team bench-away">
|
||||
<?php if (!$show_side_filter): ?>
|
||||
<h3><?php echo esc_html($away_staff[array_key_first($away_staff)]['teamName'] ?? __('Away Team', 'swi_foot_matchdata')); ?></h3>
|
||||
<?php endif; ?>
|
||||
<ul class="bench-list">
|
||||
<?php foreach ($away_staff as $person): ?>
|
||||
<li class="bench-person">
|
||||
<?php echo esc_html($person['personName'] ?? ''); ?>
|
||||
<?php if (!empty($person['roleCategoryName'])): ?>
|
||||
<span class="swi-foot-role">(<?php echo esc_html($person['roleCategoryName']); ?>)</span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render referees list for a match
|
||||
* Usage: [swi_foot_referees match_id="12345"]
|
||||
* Lists referees with their role and name formatted as: "Role: Firstname Name" (name in bold)
|
||||
*/
|
||||
public function referees_shortcode($atts)
|
||||
{
|
||||
$atts = shortcode_atts(array(
|
||||
'match_id' => ''
|
||||
), $atts);
|
||||
|
||||
$match_id = $atts['match_id'];
|
||||
if (empty($match_id)) {
|
||||
return '<div class="swi-foot-error">✗ ' . __('Match ID required', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
$referees = $this->api->get_match_referees($match_id);
|
||||
|
||||
if (is_wp_error($referees)) {
|
||||
return $this->render_error_message($referees);
|
||||
}
|
||||
|
||||
if (empty($referees)) {
|
||||
return '<div class="swi-foot-data-unavailable">ℹ️ ' . __('No data available', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="swi-foot-referees-container" data-match-id="<?php echo esc_attr($match_id); ?>">
|
||||
<ul class="referees-list">
|
||||
<?php foreach ($referees as $referee): ?>
|
||||
<li class="referee-item">
|
||||
<span class="referee-role"><?php echo esc_html($referee['refereeRoleName'] ?? ''); ?>:</span>
|
||||
<strong><?php echo esc_html(($referee['firstname'] ?? '') . ' ' . ($referee['name'] ?? '')); ?></strong>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic inline data point shortcode
|
||||
* Extracts a specific field from match data and displays it inline
|
||||
@@ -512,15 +667,16 @@ class Swi_Foot_Shortcodes
|
||||
return null;
|
||||
}
|
||||
|
||||
// Parse the matchDate string - handle multiple formats
|
||||
$timestamp = strtotime($match['matchDate']);
|
||||
if ($timestamp === false) {
|
||||
// Extract date part from ISO datetime string (e.g., "2026-03-27T19:30:00" -> "2026-03-27")
|
||||
// API provides date in Swiss time, use as-is without any timezone conversion
|
||||
$date_part = substr($match['matchDate'], 0, 10);
|
||||
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $date_part)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Use WordPress date format setting
|
||||
// Convert date string to WordPress format
|
||||
$date_format = get_option('date_format');
|
||||
return wp_date($date_format, $timestamp);
|
||||
return date_i18n($date_format, strtotime($date_part));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -535,15 +691,20 @@ class Swi_Foot_Shortcodes
|
||||
return null;
|
||||
}
|
||||
|
||||
// Parse the matchDate string - handle multiple formats
|
||||
$timestamp = strtotime($match['matchDate']);
|
||||
if ($timestamp === false) {
|
||||
// Extract time part from ISO datetime string (e.g., "2026-03-27T19:30:00" -> "19:30:00")
|
||||
// API provides time in Swiss time, use as-is without any timezone conversion
|
||||
if (strpos($match['matchDate'], 'T') === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$time_part = substr($match['matchDate'], 11, 8);
|
||||
if (!preg_match('/^\d{2}:\d{2}:\d{2}$/', $time_part)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Use WordPress time format setting
|
||||
// Format time string with WordPress time format setting
|
||||
$time_format = get_option('time_format');
|
||||
return wp_date($time_format, $timestamp);
|
||||
return date_i18n($time_format, strtotime('2000-01-01 ' . $time_part));
|
||||
}
|
||||
|
||||
private function get_match_data($atts)
|
||||
@@ -616,13 +777,13 @@ class Swi_Foot_Shortcodes
|
||||
), $atts);
|
||||
|
||||
if (empty($atts['team_id'])) {
|
||||
return '<span class="swi-foot-error">' . __('Team ID required', 'swi_foot_matchdata') . '</span>';
|
||||
return '<div class="swi-foot-error">' . __('Team ID required', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
$standings = $this->api->get_standings($atts['team_id']);
|
||||
|
||||
if (is_wp_error($standings) || empty($standings)) {
|
||||
return '<span class="swi-foot-error">' . __('Standings data not available', 'swi_foot_matchdata') . '</span>';
|
||||
return '<div class="swi-foot-error">' . __('Standings data not available', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
ob_start();
|
||||
@@ -667,16 +828,18 @@ class Swi_Foot_Shortcodes
|
||||
public function roster_shortcode($atts)
|
||||
{
|
||||
$atts = shortcode_atts(array(
|
||||
'match_id' => '',
|
||||
'team_id' => '',
|
||||
'show_current' => 'false',
|
||||
'side' => '',
|
||||
'with_bench' => 'false'
|
||||
'match_id' => '',
|
||||
'team_id' => '',
|
||||
'show_current' => 'false',
|
||||
'side' => '',
|
||||
'show_starting' => 'true',
|
||||
'show_bench' => 'false',
|
||||
'with_bench' => 'false' // Legacy support
|
||||
), $atts);
|
||||
|
||||
$side = strtolower(trim($atts['side']));
|
||||
if (!in_array($side, array('home', 'away'), true)) {
|
||||
return '<span class="swi-foot-error">' . __('Parameter "side" must be "home" or "away"', 'swi_foot_matchdata') . '</span>';
|
||||
return '<div class="swi-foot-error">' . __('Parameter "side" must be "home" or "away"', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
$match_id = $atts['match_id'];
|
||||
@@ -688,27 +851,27 @@ class Swi_Foot_Shortcodes
|
||||
}
|
||||
|
||||
if (empty($match_id)) {
|
||||
return '<span class="swi-foot-error">' . __('Match ID required', 'swi_foot_matchdata') . '</span>';
|
||||
return '<div class="swi-foot-error">' . __('Match ID required', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
// Parse show_starting and show_bench attributes (handle legacy with_bench)
|
||||
$show_starting = strtolower($atts['show_starting']) === 'true';
|
||||
$show_bench = strtolower($atts['show_bench']) === 'true';
|
||||
|
||||
// Legacy support: if with_bench is true and show_starting is default, show both
|
||||
if (strtolower($atts['with_bench']) === 'true' && !$show_bench) {
|
||||
$show_bench = true;
|
||||
}
|
||||
|
||||
// First check if we have saved final data
|
||||
$saved = $this->api->get_finished_match_data($match_id);
|
||||
if ($saved) {
|
||||
$players = $saved['roster']['players'] ?? array();
|
||||
$bench_players = $saved['roster']['bench'] ?? array();
|
||||
$players = $saved['roster']['players'] ?? array();
|
||||
} else {
|
||||
// Live fetch
|
||||
$players = $this->api->get_match_players($match_id);
|
||||
if (is_wp_error($players)) {
|
||||
return '<span class="swi-foot-error">' . __('Roster data not available', 'swi_foot_matchdata') . ': ' . esc_html($players->get_error_message()) . '</span>';
|
||||
}
|
||||
$bench_players = array();
|
||||
|
||||
if (strtolower($atts['with_bench']) === 'true') {
|
||||
$bench = $this->api->get_match_bench($match_id);
|
||||
if (!is_wp_error($bench)) {
|
||||
$bench_players = $bench;
|
||||
}
|
||||
return $this->render_error_message($players);
|
||||
}
|
||||
|
||||
// Check match ended & possibly save events + roster together
|
||||
@@ -722,68 +885,100 @@ class Swi_Foot_Shortcodes
|
||||
if (is_array($players)) {
|
||||
$this->api->save_finished_match_data(
|
||||
$match_id,
|
||||
array('players' => $players, 'bench' => $bench_players),
|
||||
array('players' => $players),
|
||||
$events
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter roster for side
|
||||
$filtered_players = array_filter($players, function ($p) use ($side) {
|
||||
// Filter players by team side
|
||||
$team_players = array_filter($players, function ($p) use ($side) {
|
||||
return $side === 'home' ? !empty($p['isHomeTeam']) : empty($p['isHomeTeam']);
|
||||
});
|
||||
$filtered_bench = array_filter($bench_players, function ($p) use ($side) {
|
||||
return $side === 'home' ? !empty($p['isHomeTeam']) : empty($p['isHomeTeam']);
|
||||
|
||||
// Split players into starting (assignmentRoleId = 0 or 1 for captain) and bench (assignmentRoleId > 1)
|
||||
$starting_players = array_filter($team_players, function ($p) {
|
||||
return isset($p['assignmentRoleId']) && ((int)$p['assignmentRoleId'] === 0 || (int)$p['assignmentRoleId'] === 1);
|
||||
});
|
||||
$bench_players = array_filter($team_players, function ($p) {
|
||||
return !isset($p['assignmentRoleId']) || ((int)$p['assignmentRoleId'] > 1);
|
||||
});
|
||||
|
||||
// If neither option is checked, return empty div
|
||||
if (!$show_starting && !$show_bench) {
|
||||
return '<div class="swi-foot-error">' . __('No roster display options selected', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<div class="swi-foot-roster" data-match-id="<?php echo esc_attr($match_id); ?>">
|
||||
<h3><?php echo esc_html(ucfirst($side) . ' ' . __('Team Roster', 'swi_foot_matchdata')); ?></h3>
|
||||
<?php if (!empty($filtered_players)): ?>
|
||||
<ul class="roster-list">
|
||||
<?php foreach ($filtered_players as $pl): ?>
|
||||
<li>
|
||||
<?php
|
||||
$jersey = $pl['jerseyNumber'] ?? '';
|
||||
$firstname = $pl['firstname'] ?? '';
|
||||
$name = $pl['name'] ?? '';
|
||||
$secondName = $pl['secondName'] ?? '';
|
||||
$positionName = $pl['positionName'] ?? $pl['position'] ?? '';
|
||||
$displayName = trim($firstname . ' ' . $name . ' ' . $secondName);
|
||||
echo esc_html($jersey . ' – ' . $displayName);
|
||||
if (!empty($positionName)) {
|
||||
echo ' (' . esc_html($positionName) . ')';
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php else: ?>
|
||||
<p><?php _e('No roster data available.', 'swi_foot_matchdata'); ?></p>
|
||||
|
||||
<?php if ($show_starting && !empty($starting_players)): ?>
|
||||
<div class="swi-foot-roster-starting">
|
||||
<h4><?php _e('Starting Squad', 'swi_foot_matchdata'); ?></h4>
|
||||
<ul class="roster-list">
|
||||
<?php foreach ($starting_players as $pl): ?>
|
||||
<li class="roster-player<?php echo isset($pl['assignmentRoleId']) && (int)$pl['assignmentRoleId'] === 1 ? ' roster-player-captain' : ''; ?>">
|
||||
<?php
|
||||
$jersey = $pl['jerseyNumber'] ?? '';
|
||||
$firstname = $pl['firstname'] ?? '';
|
||||
$name = $pl['name'] ?? '';
|
||||
$secondName = $pl['secondName'] ?? '';
|
||||
$positionName = $pl['positionName'] ?? $pl['position'] ?? '';
|
||||
$isCaptain = isset($pl['assignmentRoleId']) && (int)$pl['assignmentRoleId'] === 1;
|
||||
$displayName = trim($firstname . ' ' . $name . ' ' . $secondName);
|
||||
|
||||
// Captain badge
|
||||
if ($isCaptain) {
|
||||
echo '<span class="swi-foot-captain-badge" title="' . esc_attr(__('Captain', 'swi_foot_matchdata')) . '">C</span> ';
|
||||
}
|
||||
|
||||
echo esc_html($jersey . ' – ' . $displayName);
|
||||
|
||||
if (!empty($positionName)) {
|
||||
echo ' <span class="swi-foot-position">(' . esc_html($positionName) . ')</span>';
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($filtered_bench)): ?>
|
||||
<h4><?php _e('Bench', 'swi_foot_matchdata'); ?></h4>
|
||||
<ul class="roster-bench-list">
|
||||
<?php foreach ($filtered_bench as $pl): ?>
|
||||
<li>
|
||||
<?php
|
||||
$jersey = $pl['jerseyNumber'] ?? '';
|
||||
$firstname = $pl['firstname'] ?? '';
|
||||
$name = $pl['name'] ?? '';
|
||||
$secondName = $pl['secondName'] ?? '';
|
||||
$positionName = $pl['positionName'] ?? $pl['position'] ?? '';
|
||||
$displayName = trim($firstname . ' ' . $name . ' ' . $secondName);
|
||||
echo esc_html($jersey . ' – ' . $displayName);
|
||||
if (!empty($positionName)) {
|
||||
echo ' (' . esc_html($positionName) . ')';
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php if ($show_starting && !empty($starting_players) && $show_bench && !empty($bench_players)): ?>
|
||||
<hr class="swi-foot-roster-divider" />
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($show_bench && !empty($bench_players)): ?>
|
||||
<div class="swi-foot-roster-bench">
|
||||
<h4><?php _e('Bench', 'swi_foot_matchdata'); ?></h4>
|
||||
<ul class="roster-bench-list">
|
||||
<?php foreach ($bench_players as $pl): ?>
|
||||
<li class="roster-player">
|
||||
<?php
|
||||
$jersey = $pl['jerseyNumber'] ?? '';
|
||||
$firstname = $pl['firstname'] ?? '';
|
||||
$name = $pl['name'] ?? '';
|
||||
$secondName = $pl['secondName'] ?? '';
|
||||
$positionName = $pl['positionName'] ?? $pl['position'] ?? '';
|
||||
$displayName = trim($firstname . ' ' . $name . ' ' . $secondName);
|
||||
echo esc_html($jersey . ' – ' . $displayName);
|
||||
if (!empty($positionName)) {
|
||||
echo ' <span class="swi-foot-position">(' . esc_html($positionName) . ')</span>';
|
||||
}
|
||||
?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!$show_starting && !empty($bench_players) && !$show_bench): ?>
|
||||
<p><?php _e('No roster data to display.', 'swi_foot_matchdata'); ?></p>
|
||||
<?php elseif ($show_starting && empty($starting_players) && empty($bench_players)): ?>
|
||||
<p><?php _e('No roster data available.', 'swi_foot_matchdata'); ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
@@ -814,7 +1009,7 @@ class Swi_Foot_Shortcodes
|
||||
}
|
||||
|
||||
if (empty($match_id)) {
|
||||
return '<span class="swi-foot-error">' . __('Match ID required', 'swi_foot_matchdata') . '</span>';
|
||||
return '<div class="swi-foot-error">' . __('Match ID required', 'swi_foot_matchdata') . '</div>';
|
||||
}
|
||||
|
||||
// Try saved first
|
||||
@@ -824,7 +1019,7 @@ class Swi_Foot_Shortcodes
|
||||
} else {
|
||||
$events = $this->api->get_match_events($match_id);
|
||||
if (is_wp_error($events)) {
|
||||
return '<span class="swi-foot-error">' . __('Events data not available', 'swi_foot_matchdata') . '</span>';
|
||||
return $this->render_error_message($events);
|
||||
}
|
||||
|
||||
// Check if match ended and store both data sets
|
||||
|
||||
Reference in New Issue
Block a user