// =========================================================================
// SHORTCODE: Goal Value Report - /goal-value/
// =========================================================================
add_shortcode('otg_goal_value', 'otg_render_goal_value');
function otg_render_goal_value($atts) {
global $wpdb;
// 1. Get Parameters & Dropdown Options
$available_seasons = $wpdb->get_col("SELECT DISTINCT season FROM otg_rangers_games ORDER BY season DESC");
$most_recent_season = $wpdb->get_var("SELECT season FROM otg_rangers_games ORDER BY game_date DESC LIMIT 1");
$default_season = !empty($most_recent_season) ? $most_recent_season : (!empty($available_seasons) ? reset($available_seasons) : '');
$game_type = isset($_GET['game_type']) ? sanitize_text_field($_GET['game_type']) : '2';
$season_start = isset($_GET['season_start']) ? sanitize_text_field($_GET['season_start']) : $default_season;
$season_end = isset($_GET['season_end']) ? sanitize_text_field($_GET['season_end']) : $default_season;
$opponent_abbr = isset($_GET['opponent_abbr']) ? sanitize_text_field($_GET['opponent_abbr']) : 'ALL';
// Sorting parameters
$gv_sort = isset($_GET['gv_sort']) ? sanitize_text_field($_GET['gv_sort']) : 'total_value';
$gv_dir = isset($_GET['gv_dir']) ? sanitize_text_field($_GET['gv_dir']) : 'desc';
// Smart Year Validation
if (!empty($season_start) && !empty($season_end) && $season_start > $season_end) {
$season_start = $season_end;
}
$season_where = "";
if (!empty($season_start) && !empty($season_end)) {
$season_where = $wpdb->prepare("AND g.season BETWEEN %s AND %s", $season_start, $season_end);
}
$game_filter = "";
if ($opponent_abbr !== 'ALL') {
$game_filter = $wpdb->prepare("AND g.opponent_abbr = %s", $opponent_abbr);
}
// Fetch Teams for filters
$season_teams_query = $wpdb->prepare("
SELECT DISTINCT st.abbreviation, st.team
FROM otg_standings_nhl st
JOIN otg_rangers_games g ON st.abbreviation = g.opponent_abbr AND st.season = g.season
WHERE g.season = %s
ORDER BY st.team ASC
", $season_start);
$season_teams = $wpdb->get_results($season_teams_query);
$all_teams = $wpdb->get_results("SELECT DISTINCT abbreviation, team FROM otg_standings_nhl ORDER BY team ASC");
$season_team_abbrs = [];
foreach ($season_teams as $st) {
$season_team_abbrs[] = $st->abbreviation;
}
// 2. Fetch all scoring plays for Rangers games matching filters to calculate total game goals & situational weights
$scoring_query = $wpdb->prepare("
SELECT s.game_id, s.period, s.time_elapsed, s.team_abbr, s.scorer_name, s.scorer_id,
s.strength, s.home_score, s.away_score, s.goal_modifier, g.home_team_abbr, g.season, p.id as player_internal_id
FROM otg_rangers_scoring s
JOIN otg_rangers_games g ON s.game_id = g.game_id
LEFT JOIN otg_players p ON s.scorer_id = p.nhl_id
WHERE s.time_elapsed != '00:00'
AND (s.goal_modifier IS NULL OR s.goal_modifier != 'shootout')
AND g.game_type = %s
$season_where
$game_filter
ORDER BY s.game_id ASC, s.period ASC,
CAST(SUBSTRING_INDEX(s.time_elapsed, ':', 1) AS UNSIGNED) ASC,
CAST(SUBSTRING_INDEX(s.time_elapsed, ':', -1) AS UNSIGNED) ASC
", $game_type);
$all_scoring_plays = $wpdb->get_results($scoring_query);
// Group plays by game_id to count total goals per game and track running scores/game-winners
$games_plays = [];
foreach ($all_scoring_plays as $play) {
$games_plays[$play->game_id][] = $play;
}
$player_goal_values = [];
foreach ($games_plays as $game_id => $plays) {
$total_game_goals = count($plays);
if ($total_game_goals <= 0) continue;
$base_fraction = 1 / $total_game_goals;
$final_home = (int)end($plays)->home_score;
$final_away = (int)end($plays)->away_score;
$nyr_won = ($final_home > $final_away && $plays[0]->home_team_abbr === 'NYR') || ($final_away > $final_home && $plays[0]->home_team_abbr !== 'NYR');
$loser_score = ($final_home > $final_away) ? $final_away : $final_home;
$gw_target = $loser_score + 1;
$gwg_assigned = false;
foreach ($plays as $index => $play) {
$is_nyr = ($play->team_abbr === 'NYR');
$home_score = (int)$play->home_score;
$away_score = (int)$play->away_score;
$prev_h = ($index > 0) ? (int)$plays[$index - 1]->home_score : 0;
$prev_a = ($index > 0) ? (int)$plays[$index - 1]->away_score : 0;
// Check GWG for this play
$is_gwg = false;
$is_winner_team = ($final_home > $final_away) ? ($play->home_team_abbr === 'NYR') : ($play->home_team_abbr !== 'NYR');
if ($nyr_won && $is_winner_team && !$gwg_assigned) {
$cur_nyr_score = ($play->home_team_abbr === 'NYR') ? $home_score : $away_score;
if ($cur_nyr_score === $gw_target) {
$is_gwg = true;
$gwg_assigned = true;
}
}
if ($is_nyr) {
$goal_val = $base_fraction;
$is_ot = ((int)$play->period >= 4);
if ($is_ot) $goal_val += 1.0;
$is_first = ($index === 0);
if ($is_first) $goal_val += 0.5;
$was_tied_or_trailing = ($play->home_team_abbr === 'NYR') ? ($prev_h <= $prev_a) : ($prev_a <= $prev_h);
$is_now_leading = ($play->home_team_abbr === 'NYR') ? ($home_score > $away_score) : ($away_score > $home_score);
$is_go_ahead = ($was_tied_or_trailing && $is_now_leading);
if ($is_go_ahead) $goal_val += 0.5;
if ($is_gwg) $goal_val += 0.5;
$was_leading_by_1 = ($play->home_team_abbr === 'NYR') ? ($prev_h == $prev_a + 1) : ($prev_a == $prev_h + 1);
$is_now_leading_by_2 = ($play->home_team_abbr === 'NYR') ? ($home_score == $away_score + 2) : ($away_score == $home_score + 2);
$is_insurance = ($was_leading_by_1 && $is_now_leading_by_2);
if ($is_insurance) $goal_val += 0.25;
$is_sh = (isset($play->strength) && strtolower($play->strength) === 'sh');
if ($is_sh) $goal_val += 0.5;
$is_pp = (isset($play->strength) && strtolower($play->strength) === 'pp');
if ($is_pp) $goal_val += 0.25;
$is_en = (isset($play->goal_modifier) && strtolower($play->goal_modifier) === 'empty-net');
if ($is_en) $goal_val += 0.1;
$p_name = !empty($play->scorer_name) ? $play->scorer_name : 'Unknown';
$p_id = !empty($play->player_internal_id) ? $play->player_internal_id : '';
if (!isset($player_goal_values[$p_name])) {
$player_goal_values[$p_name] = [
'player_internal_id' => $p_id,
'name' => $p_name,
'goals' => 0,
'total_value' => 0.0,
'ot_count' => 0,
'first_count' => 0,
'go_ahead_count' => 0,
'gwg_count' => 0,
'insurance_count' => 0,
'shg_count' => 0,
'ppg_count' => 0,
'eng_count' => 0
];
}
if (empty($player_goal_values[$p_name]['player_internal_id']) && !empty($p_id)) {
$player_goal_values[$p_name]['player_internal_id'] = $p_id;
}
$player_goal_values[$p_name]['goals']++;
$player_goal_values[$p_name]['total_value'] += $goal_val;
if ($is_ot) $player_goal_values[$p_name]['ot_count']++;
if ($is_first) $player_goal_values[$p_name]['first_count']++;
if ($is_go_ahead) $player_goal_values[$p_name]['go_ahead_count']++;
if ($is_gwg) $player_goal_values[$p_name]['gwg_count']++;
if ($is_insurance) $player_goal_values[$p_name]['insurance_count']++;
if ($is_sh) $player_goal_values[$p_name]['shg_count']++;
if ($is_pp) $player_goal_values[$p_name]['ppg_count']++;
if ($is_en) $player_goal_values[$p_name]['eng_count']++;
}
}
}
// Sort player goal values table
uasort($player_goal_values, function($a, $b) use ($gv_sort, $gv_dir) {
$val_a = $a[$gv_sort] ?? 0;
$val_b = $b[$gv_sort] ?? 0;
if ($gv_sort === 'name') {
$cmp = strcasecmp($a['name'], $b['name']);
return ($gv_dir === 'desc') ? -$cmp : $cmp;
}
if ($val_a == $val_b) {
return strcasecmp($a['name'], $b['name']);
}
return ($gv_dir === 'desc') ? ($val_b - $val_a) : ($val_a - $val_b);
});
// Helper for table headers sorting
$render_gv_th = function($col_key, $label, $align = 'center') use ($gv_sort, $gv_dir) {
$is_sorted = ($gv_sort === $col_key);
$arrow = '';
if ($is_sorted) {
$arrow = ($gv_dir === 'desc') ? ' ▲' : ' ▼';
}
$class = $is_sorted ? 'highlight-col' : '';
return '
' . $label . '' . $arrow . ' | ';
};
$input_style = 'width: 100%; height: 38px; padding: 0 10px; background: #222; border: 1px solid #444; color: #fff; border-radius: 4px; box-sizing: border-box; font-size: 0.9em;';
$current_url_clean = strtok($_SERVER["URI"] ?? $_SERVER['REQUEST_URI'], '?');
$output = '';
// Header
$output .= '
';
$output .= '
Rangers Advanced Goal Value Report
';
$base_q_params = '&opponent_abbr='.urlencode($opponent_abbr).'&season_start='.urlencode($season_start).'&season_end='.urlencode($season_end).'&gv_sort='.urlencode($gv_sort).'&gv_dir='.urlencode($gv_dir);
$output .= '
';
$output .= '
';
// Filters Form
$output .= '
';
// Explanation Box / Formula Legend
$output .= '
';
$output .= '
Goal Value Scoring System Legend:';
$output .= '
';
$output .= '
• Base Value: 1 / Total Goals Scored in Game
';
$output .= '
• Overtime Goal (OT): +1.0
';
$output .= '
• First Goal of Game: +0.5
';
$output .= '
• Go-Ahead Goal: +0.5
';
$output .= '
• Game Winner (GWG): +0.5
';
$output .= '
• Insurance Goal (+2 lead): +0.25
';
$output .= '
• Short-Handed Goal (SH): +0.5
';
$output .= '
• Power Play Goal (PP): +0.25
';
$output .= '
• Empty Net Goal (EN): +0.1
';
$output .= '
';
$output .= '
';
// Table Styling
$output .= '';
// Render Table Card
$output .= '
';
$output .= '
Player Goal Value Rankings
';
$output .= '
';
$output .= '
';
$output .= '';
// Name header
$is_name_sorted = ($gv_sort === 'name');
$name_arrow = $is_name_sorted ? (($gv_dir === 'asc') ? ' ▲' : ' ▼') : '';
$output .= '| Player Name' . $name_arrow . ' | ';
$output .= $render_gv_th('goals', 'Goals');
$output .= $render_gv_th('total_value', 'Total Goal Value');
$output .= $render_gv_th('ot_count', 'OT Goals');
$output .= $render_gv_th('first_count', '1st Goals');
$output .= $render_gv_th('go_ahead_count', 'Go-Ahead');
$output .= $render_gv_th('gwg_count', 'GWG');
$output .= $render_gv_th('insurance_count', 'Insurance');
$output .= $render_gv_th('shg_count', 'SHG');
$output .= $render_gv_th('ppg_count', 'PPG');
$output .= $render_gv_th('eng_count', 'ENG');
$output .= '
';
if (!empty($player_goal_values)) {
$tot_goals = 0;
$tot_value = 0.0;
$tot_ot = 0;
$tot_first = 0;
$tot_go_ahead = 0;
$tot_gwg = 0;
$tot_insurance = 0;
$tot_shg = 0;
$tot_ppg = 0;
$tot_eng = 0;
foreach ($player_goal_values as $p_name => $stats) {
$tot_goals += $stats['goals'];
$tot_value += $stats['total_value'];
$tot_ot += $stats['ot_count'];
$tot_first += $stats['first_count'];
$tot_go_ahead += $stats['go_ahead_count'];
$tot_gwg += $stats['gwg_count'];
$tot_insurance += $stats['insurance_count'];
$tot_shg += $stats['shg_count'];
$tot_ppg += $stats['ppg_count'];
$tot_eng += $stats['eng_count'];
$display_name = esc_html($stats['name']);
if (!empty($stats['player_internal_id'])) {
$p_url = home_url('/profile/?player_id=' . urlencode($stats['player_internal_id']));
$display_name = '' . esc_html($stats['name']) . '';
}
$output .= '';
$output .= '| ' . $display_name . ' | ';
$cells = [
'goals' => $stats['goals'],
'total_value' => number_format($stats['total_value'], 3),
'ot_count' => ($stats['ot_count'] > 0 ? $stats['ot_count'] : '-'),
'first_count' => ($stats['first_count'] > 0 ? $stats['first_count'] : '-'),
'go_ahead_count' => ($stats['go_ahead_count'] > 0 ? $stats['go_ahead_count'] : '-'),
'gwg_count' => ($stats['gwg_count'] > 0 ? $stats['gwg_count'] : '-'),
'insurance_count' => ($stats['insurance_count'] > 0 ? $stats['insurance_count'] : '-'),
'shg_count' => ($stats['shg_count'] > 0 ? $stats['shg_count'] : '-'),
'ppg_count' => ($stats['ppg_count'] > 0 ? $stats['ppg_count'] : '-'),
'eng_count' => ($stats['eng_count'] > 0 ? $stats['eng_count'] : '-')
];
foreach ($cells as $ckey => $cval) {
$is_col_sorted = ($gv_sort === $ckey);
$extra_style = ($ckey === 'total_value') ? 'font-weight: bold; color: #3498db;' : '';
$output .= '' . $cval . ' | ';
}
$output .= '
';
}
// Totals row
$output .= '';
$output .= '| Team Totals | ';
$output .= '' . $tot_goals . ' | ';
$output .= '' . number_format($tot_value, 3) . ' | ';
$output .= '' . $tot_ot . ' | ';
$output .= '' . $tot_first . ' | ';
$output .= '' . $tot_go_ahead . ' | ';
$output .= '' . $tot_gwg . ' | ';
$output .= '' . $tot_insurance . ' | ';
$output .= '' . $tot_shg . ' | ';
$output .= '' . $tot_ppg . ' | ';
$output .= '' . $tot_eng . ' | ';
$output .= '
';
} else {
$output .= '| No goal records found matching the selected filters. |
';
}
$output .= '
';
// JavaScript for Column Sorting
$output .= '';
$output .= '
';
return $output;
}
Where Smit Hits The Fan – Page 15 – OutsideTheGarden Boards
Skip to content