<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rummy Scores</title>
	<atom:link href="https://rummygin.co.uk/feed/" rel="self" type="application/rss+xml" />
	<link>https://rummygin.co.uk</link>
	<description>Individual &#38; Team tournament scoring system</description>
	<lastBuildDate>Mon, 16 Feb 2026 15:35:08 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Hello world!</title>
		<link>https://rummygin.co.uk/hello-world/</link>
					<comments>https://rummygin.co.uk/hello-world/#comments</comments>
		
		<dc:creator><![CDATA[admin]]></dc:creator>
		<pubDate>Mon, 22 Dec 2025 19:06:40 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://dfcchickengrill.co.uk/?p=1</guid>

					<description><![CDATA[&#60;?php/*Plugin Name: Rummy RoyaleDescription: Individual &#38; Team tournament scoring with automatic totals, winner detection, summary tables, lifetime record, winner messages, and lifetime stats.Version: 6.0Author: Raggy &#8211; Hassam X*/ if (!defined(&#8216;ABSPATH&#8217;)) exit;/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;POST TYPE &#38; TAXONOMY&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */add_action(&#8216;init&#8217;, function () {register_post_type(&#8216;tournament&#8217;, [&#8216;labels&#8217; =&#62; [&#8216;name&#8217;=&#62;&#8217;Tournaments&#8217;,&#8217;singular_name&#8217;=&#62;&#8217;Tournament&#8217;],&#8216;public&#8217;=&#62;true,&#8217;show_in_rest&#8217;=&#62;true,&#8217;supports&#8217;=&#62;[&#8216;title&#8217;,&#8217;editor&#8217;],&#8217;menu_icon&#8217;=&#62;&#8217;dashicons-awards&#8217;]);register_taxonomy(&#8216;tournament_category&#8217;,&#8217;tournament&#8217;,[&#8216;labels&#8217;=&#62;[&#8216;name&#8217;=&#62;&#8217;Tournament Categories&#8217;,&#8217;singular_name&#8217;=&#62;&#8217;Tournament Category&#8217;,&#8217;search_items&#8217;=&#62;&#8217;Search Categories&#8217;,&#8216;all_items&#8217;=&#62;&#8217;All Categories&#8217;,&#8217;edit_item&#8217;=&#62;&#8217;Edit Category&#8217;,&#8217;update_item&#8217;=&#62;&#8217;Update Category&#8217;,&#8216;add_new_item&#8217;=&#62;&#8217;Add New Category&#8217;,&#8217;new_item_name&#8217;=&#62;&#8217;New Category Name&#8217;,&#8217;menu_name&#8217;=&#62;&#8217;Categories&#8217;],&#8216;hierarchical&#8217;=&#62;true,&#8217;show_ui&#8217;=&#62;true,&#8217;show_admin_column&#8217;=&#62;true,&#8217;show_in_rest&#8217;=&#62;true,&#8216;rewrite&#8217;=&#62;[&#8216;slug&#8217;=&#62;&#8217;tournament-category&#8217;],&#8217;show_in_menu&#8217;=&#62;false]);}); /* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;TOURNAMENT SUBMENUS [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>&lt;?php<br />/*<br />Plugin Name: Rummy Royale<br />Description: Individual &amp; Team tournament scoring with automatic totals, winner detection, summary tables, lifetime record, winner messages, and lifetime stats.<br />Version: 6.0<br />Author: Raggy &#8211; Hassam X<br />*/</p>
<p>if (!defined(&#8216;ABSPATH&#8217;)) exit;<br />/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />POST TYPE &amp; TAXONOMY<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_action(&#8216;init&#8217;, function () {<br />register_post_type(&#8216;tournament&#8217;, [<br />&#8216;labels&#8217; =&gt; [&#8216;name&#8217;=&gt;&#8217;Tournaments&#8217;,&#8217;singular_name&#8217;=&gt;&#8217;Tournament&#8217;],<br />&#8216;public&#8217;=&gt;true,&#8217;show_in_rest&#8217;=&gt;true,&#8217;supports&#8217;=&gt;[&#8216;title&#8217;,&#8217;editor&#8217;],&#8217;menu_icon&#8217;=&gt;&#8217;dashicons-awards&#8217;<br />]);<br />register_taxonomy(&#8216;tournament_category&#8217;,&#8217;tournament&#8217;,[<br />&#8216;labels&#8217;=&gt;[<br />&#8216;name&#8217;=&gt;&#8217;Tournament Categories&#8217;,&#8217;singular_name&#8217;=&gt;&#8217;Tournament Category&#8217;,&#8217;search_items&#8217;=&gt;&#8217;Search Categories&#8217;,<br />&#8216;all_items&#8217;=&gt;&#8217;All Categories&#8217;,&#8217;edit_item&#8217;=&gt;&#8217;Edit Category&#8217;,&#8217;update_item&#8217;=&gt;&#8217;Update Category&#8217;,<br />&#8216;add_new_item&#8217;=&gt;&#8217;Add New Category&#8217;,&#8217;new_item_name&#8217;=&gt;&#8217;New Category Name&#8217;,&#8217;menu_name&#8217;=&gt;&#8217;Categories&#8217;<br />],<br />&#8216;hierarchical&#8217;=&gt;true,&#8217;show_ui&#8217;=&gt;true,&#8217;show_admin_column&#8217;=&gt;true,&#8217;show_in_rest&#8217;=&gt;true,<br />&#8216;rewrite&#8217;=&gt;[&#8216;slug&#8217;=&gt;&#8217;tournament-category&#8217;],&#8217;show_in_menu&#8217;=&gt;false<br />]);<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />TOURNAMENT SUBMENUS WITH HELP PAGE<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_action(&#8216;admin_menu&#8217;, function() {</p>
<p>// 1&#x20e3; Add New Game (redirect to Add New Tournament)<br />add_submenu_page(<br />&#8216;edit.php?post_type=tournament&#8217;, <br />&#8216;Add New Game&#8217;, <br />&#8216;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2795.png" alt="➕" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Add New Game&#8217;, <br />&#8216;manage_options&#8217;, <br />&#8216;ts_add_new_game&#8217;, <br />&#8216;__return_null&#8217; <br />);</p>
<p>// 2&#x20e3; Tournament Categories<br />add_submenu_page(<br />&#8216;edit.php?post_type=tournament&#8217;,<br />&#8216;Tournament Categories&#8217;,<br />&#8216;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c2.png" alt="📂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Categories&#8217;,<br />&#8216;manage_options&#8217;,<br />&#8216;edit-tags.php?taxonomy=tournament_category&amp;post_type=tournament&#8217;<br />);</p>
<p>// 3&#x20e3; Remove Player<br />add_submenu_page(<br />&#8216;edit.php?post_type=tournament&#8217;,<br />&#8216;Remove Player&#8217;,<br />&#8216;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Remove Player&#8217;,<br />&#8216;manage_options&#8217;,<br />&#8216;ts_remove_player&#8217;,<br />&#8216;ts_remove_player_page&#8217;<br />);</p>
<p>// 4&#x20e3; Table Styles<br />add_submenu_page(<br />&#8216;edit.php?post_type=tournament&#8217;,<br />&#8216;Table Styles&#8217;,<br />&#8216;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3a8.png" alt="🎨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Table Styles&#8217;,<br />&#8216;manage_options&#8217;,<br />&#8216;ts_table_styles&#8217;,<br />&#8216;ts_table_styles_page&#8217;<br />);</p>
<p>// 5&#x20e3; Help Page (below Table Styles)<br />add_submenu_page(<br />&#8216;edit.php?post_type=tournament&#8217;,<br />&#8216;Rummy Scores Help&#8217;,<br />&#8216;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Help&#8217;,<br />&#8216;manage_options&#8217;,<br />&#8216;rummy-scores-help&#8217;,<br />&#8216;rummy_scores_help_page&#8217;<br />);<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />SAFE REDIRECT FOR &#8220;ADD NEW GAME&#8221;<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_action(&#8216;admin_init&#8217;, function() {<br />if ( isset($_GET[&#8216;page&#8217;]) &amp;&amp; $_GET[&#8216;page&#8217;] === &#8216;ts_add_new_game&#8217; ) {<br />wp_redirect(admin_url(&#8216;post-new.php?post_type=tournament&#8217;));<br />exit;<br />}<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CLEAN DEFAULT MENUS<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_action(&#8216;admin_menu&#8217;, function(){<br />remove_submenu_page(&#8216;edit.php?post_type=tournament&#8217;,&#8217;post-new.php?post_type=tournament&#8217;);<br />remove_menu_page(&#8216;edit-tags.php?taxonomy=tournament_category&amp;post_type=tournament&#8217;);<br />}, 999);</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />DYNAMIC HELP PAGE CONTENT GROUPED BY TYPE<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function rummy_scores_help_page() {<br />?&gt;<br />&lt;div class=&#8221;wrap&#8221;&gt;<br />&lt;h1&gt;Rummy Scores Plugin Help&lt;/h1&gt;<br />&lt;p&gt;This page lists all shortcodes registered by the plugin, grouped by category with live previews.&lt;/p&gt;</p>
<p>&lt;?php<br />global $shortcode_tags;</p>
<p>// Automatic grouping based on shortcode name<br />$categories = [<br />&#8216;Leaderboard&#8217; =&gt; [],<br />&#8216;Individual Records&#8217; =&gt; [],<br />&#8216;Other&#8217; =&gt; []<br />];</p>
<p>// Collect all plugin shortcodes<br />foreach ($shortcode_tags as $tag =&gt; $function) {<br />if (strpos($tag, &#8216;tournament&#8217;) === 0) {<br />// Assign to category based on name<br />if (strpos($tag, &#8216;highest_score&#8217;) !== false || strpos($tag, &#8216;global&#8217;) !== false) {<br />$categories[&#8216;Leaderboard&#8217;][] = $tag;<br />} elseif (strpos($tag, &#8216;individual&#8217;) !== false) {<br />$categories[&#8216;Individual Records&#8217;][] = $tag;<br />} else {<br />$categories[&#8216;Other&#8217;][] = $tag;<br />}<br />}<br />}</p>
<p>// Display grouped tables<br />foreach ($categories as $cat_name =&gt; $shortcodes) :<br />if (!empty($shortcodes)) :<br />?&gt;<br />&lt;h2&gt;&lt;?php echo esc_html($cat_name); ?&gt;&lt;/h2&gt;<br />&lt;table class=&#8221;widefat striped&#8221;&gt;<br />&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;Shortcode&lt;/th&gt;<br />&lt;th&gt;Description / Preview&lt;/th&gt;<br />&lt;th&gt;Usage Example&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;<br />&lt;tbody&gt;<br />&lt;?php foreach ($shortcodes as $tag) : ?&gt;<br />&lt;tr&gt;<br />&lt;td&gt;&lt;?php echo esc_html(&#8220;[$tag]&#8221;); ?&gt;&lt;/td&gt;<br />&lt;td&gt;<br />&lt;div style=&#8221;max-height:200px; overflow:auto; padding:5px; border:1px solid #ddd; background:#fff;&#8221;&gt;<br />&lt;?php<br />$preview = do_shortcode(&#8220;[$tag]&#8221;);<br />if (!$preview || stripos($preview, &#8216;no&#8217;) !== false) {<br />echo &#8216;&lt;em&gt;No data to display. Try adding a tournament first!&lt;/em&gt;&#8217;;<br />} else {<br />echo $preview;<br />}<br />?&gt;<br />&lt;/div&gt;<br />&lt;/td&gt;<br />&lt;td&gt;&lt;code&gt;&lt;?php echo esc_html(&#8220;[$tag]&#8221;); ?&gt;&lt;/code&gt;&lt;/td&gt;<br />&lt;/tr&gt;<br />&lt;?php endforeach; ?&gt;<br />&lt;/tbody&gt;<br />&lt;/table&gt;<br />&lt;?php<br />endif;<br />endforeach;<br />?&gt;</p>
<p>&lt;h2&gt;How to Use&lt;/h2&gt;<br />&lt;ul&gt;<br />&lt;li&gt;Copy the shortcode you want to use.&lt;/li&gt;<br />&lt;li&gt;Paste it into any page, post, or widget.&lt;/li&gt;<br />&lt;li&gt;Ensure tournament data exists for it to display properly.&lt;/li&gt;<br />&lt;/ul&gt;</p>
<p>&lt;h2&gt;Tips&lt;/h2&gt;<br />&lt;ul&gt;<br />&lt;li&gt;Use Leaderboard shortcodes to display global or tournament high scores.&lt;/li&gt;<br />&lt;li&gt;Use Individual Records shortcodes to display personal player stats.&lt;/li&gt;<br />&lt;li&gt;“Other” category shortcodes may include custom displays or additional tools.&lt;/li&gt;<br />&lt;/ul&gt;<br />&lt;/div&gt;<br />&lt;?php<br />}</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />ADMIN: TABLE STYLES PAGE WITH PRESETS &amp; LIVE PREVIEW<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function ts_table_styles_page(){</p>
<p>// Default colors<br />$defaults = [<br />&#8216;header_bg&#8217;=&gt;&#8217;#4CAF50&#8242;,&#8217;header_text&#8217;=&gt;&#8217;#ffffff&#8217;,<br />&#8216;row_even&#8217;=&gt;&#8217;#f2f2f2&#8242;,&#8217;row_odd&#8217;=&gt;&#8217;#ffffff&#8217;,<br />&#8216;winner_bg&#8217;=&gt;&#8217;#d4edda&#8217;,&#8217;table_text&#8217;=&gt;&#8217;#000000&#8242;<br />];</p>
<p>// Get saved options<br />$options = get_option(&#8216;ts_table_styles&#8217;, $defaults);</p>
<p>// Handle form submission<br />if(isset($_POST[&#8216;ts_table_styles_nonce&#8217;]) &amp;&amp; wp_verify_nonce($_POST[&#8216;ts_table_styles_nonce&#8217;],&#8217;ts_table_styles_save&#8217;)){<br />$options = [<br />&#8216;header_bg&#8217;=&gt;sanitize_hex_color($_POST[&#8216;header_bg&#8217;] ?? $defaults[&#8216;header_bg&#8217;]),<br />&#8216;header_text&#8217;=&gt;sanitize_hex_color($_POST[&#8216;header_text&#8217;] ?? $defaults[&#8216;header_text&#8217;]),<br />&#8216;row_even&#8217;=&gt;sanitize_hex_color($_POST[&#8216;row_even&#8217;] ?? $defaults[&#8216;row_even&#8217;]),<br />&#8216;row_odd&#8217;=&gt;sanitize_hex_color($_POST[&#8216;row_odd&#8217;] ?? $defaults[&#8216;row_odd&#8217;]),<br />&#8216;winner_bg&#8217;=&gt;sanitize_hex_color($_POST[&#8216;winner_bg&#8217;] ?? $defaults[&#8216;winner_bg&#8217;]),<br />&#8216;table_text&#8217;=&gt;sanitize_hex_color($_POST[&#8216;table_text&#8217;] ?? $defaults[&#8216;table_text&#8217;]),<br />];<br />update_option(&#8216;ts_table_styles&#8217;,$options);<br />echo &#8216;&lt;div class=&#8221;notice notice-success&#8221;&gt;&lt;p&gt;Table styles saved!&lt;/p&gt;&lt;/div&gt;&#8217;;<br />}</p>
<p>// Presets<br />$presets = [<br />&#8216;classic&#8217; =&gt; [<br />&#8216;header_bg&#8217;=&gt;&#8217;#4CAF50&#8242;,&#8217;header_text&#8217;=&gt;&#8217;#ffffff&#8217;,<br />&#8216;row_even&#8217;=&gt;&#8217;#f2f2f2&#8242;,&#8217;row_odd&#8217;=&gt;&#8217;#ffffff&#8217;,<br />&#8216;winner_bg&#8217;=&gt;&#8217;#d4edda&#8217;,&#8217;table_text&#8217;=&gt;&#8217;#000000&#8242;<br />],<br />&#8216;dark&#8217; =&gt; [<br />&#8216;header_bg&#8217;=&gt;&#8217;#1f2937&#8242;,&#8217;header_text&#8217;=&gt;&#8217;#ffffff&#8217;,<br />&#8216;row_even&#8217;=&gt;&#8217;#111827&#8242;,&#8217;row_odd&#8217;=&gt;&#8217;#1f2937&#8217;,<br />&#8216;winner_bg&#8217;=&gt;&#8217;#064e3b&#8217;,&#8217;table_text&#8217;=&gt;&#8217;#e5e7eb&#8217;<br />],<br />&#8216;casino&#8217; =&gt; [<br />&#8216;header_bg&#8217;=&gt;&#8217;#7c2d12&#8242;,&#8217;header_text&#8217;=&gt;&#8217;#fff7ed&#8217;,<br />&#8216;row_even&#8217;=&gt;&#8217;#fff7ed&#8217;,&#8217;row_odd&#8217;=&gt;&#8217;#ffedd5&#8242;,<br />&#8216;winner_bg&#8217;=&gt;&#8217;#fde68a&#8217;,&#8217;table_text&#8217;=&gt;&#8217;#431407&#8242;<br />],<br />&#8216;neon&#8217; =&gt; [<br />&#8216;header_bg&#8217;=&gt;&#8217;#7c3aed&#8217;,&#8217;header_text&#8217;=&gt;&#8217;#fdf4ff&#8217;,<br />&#8216;row_even&#8217;=&gt;&#8217;#fdf4ff&#8217;,&#8217;row_odd&#8217;=&gt;&#8217;#fae8ff&#8217;,<br />&#8216;winner_bg&#8217;=&gt;&#8217;#a7f3d0&#8242;,&#8217;table_text&#8217;=&gt;&#8217;#312e81&#8217;<br />]<br />];<br />?&gt;<br />&lt;div class=&#8221;wrap&#8221;&gt;<br />&lt;h1&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3a8.png" alt="🎨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Tournament Table Styles&lt;/h1&gt;</p>
<p>&lt;!&#8211; Presets Buttons &#8211;&gt;<br />&lt;h2&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3a8.png" alt="🎨" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Presets&lt;/h2&gt;<br />&lt;div style=&#8221;margin-bottom:15px;&#8221;&gt;<br />&lt;?php foreach ($presets as $key =&gt; $set): ?&gt;<br />&lt;button type=&#8221;button&#8221; class=&#8221;button ts-preset&#8221;<br />data-preset='&lt;?php echo json_encode($set); ?&gt;&#8217;&gt;<br />&lt;?php echo ucfirst($key); ?&gt;<br />&lt;/button&gt;<br />&lt;?php endforeach; ?&gt;<br />&lt;/div&gt;</p>
<p>&lt;!&#8211; Color Pickers Form &#8211;&gt;<br />&lt;form method=&#8221;post&#8221;&gt;<br />&lt;?php wp_nonce_field(&#8216;ts_table_styles_save&#8217;,&#8217;ts_table_styles_nonce&#8217;); ?&gt;<br />&lt;table class=&#8221;form-table&#8221;&gt;<br />&lt;tr&gt;&lt;th&gt;Header Background&lt;/th&gt;&lt;td&gt;&lt;input type=&#8221;color&#8221; name=&#8221;header_bg&#8221; value=&#8221;&lt;?php echo esc_attr($options[&#8216;header_bg&#8217;]); ?&gt;&#8221;&gt;&lt;/td&gt;&lt;/tr&gt;<br />&lt;tr&gt;&lt;th&gt;Header Text&lt;/th&gt;&lt;td&gt;&lt;input type=&#8221;color&#8221; name=&#8221;header_text&#8221; value=&#8221;&lt;?php echo esc_attr($options[&#8216;header_text&#8217;]); ?&gt;&#8221;&gt;&lt;/td&gt;&lt;/tr&gt;<br />&lt;tr&gt;&lt;th&gt;Even Row Background&lt;/th&gt;&lt;td&gt;&lt;input type=&#8221;color&#8221; name=&#8221;row_even&#8221; value=&#8221;&lt;?php echo esc_attr($options[&#8216;row_even&#8217;]); ?&gt;&#8221;&gt;&lt;/td&gt;&lt;/tr&gt;<br />&lt;tr&gt;&lt;th&gt;Odd Row Background&lt;/th&gt;&lt;td&gt;&lt;input type=&#8221;color&#8221; name=&#8221;row_odd&#8221; value=&#8221;&lt;?php echo esc_attr($options[&#8216;row_odd&#8217;]); ?&gt;&#8221;&gt;&lt;/td&gt;&lt;/tr&gt;<br />&lt;tr&gt;&lt;th&gt;Winner Row Background&lt;/th&gt;&lt;td&gt;&lt;input type=&#8221;color&#8221; name=&#8221;winner_bg&#8221; value=&#8221;&lt;?php echo esc_attr($options[&#8216;winner_bg&#8217;]); ?&gt;&#8221;&gt;&lt;/td&gt;&lt;/tr&gt;<br />&lt;tr&gt;&lt;th&gt;Table Text&lt;/th&gt;&lt;td&gt;&lt;input type=&#8221;color&#8221; name=&#8221;table_text&#8221; value=&#8221;&lt;?php echo esc_attr($options[&#8216;table_text&#8217;]); ?&gt;&#8221;&gt;&lt;/td&gt;&lt;/tr&gt;<br />&lt;/table&gt;<br />&lt;p&gt;&lt;input type=&#8221;submit&#8221; class=&#8221;button button-primary&#8221; value=&#8221;Save Styles&#8221;&gt;&lt;/p&gt;<br />&lt;/form&gt;</p>
<p>&lt;!&#8211; Live Preview &#8211;&gt;<br />&lt;h2&gt;Live Preview&lt;/h2&gt;<br />&lt;table class=&#8221;tournament-table&#8221; style=&#8221;margin-top:15px;&#8221;&gt;<br />&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Score&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;<br />&lt;tbody&gt;<br />&lt;tr&gt;&lt;td&gt;Player 1&lt;/td&gt;&lt;td&gt;1000&lt;/td&gt;&lt;/tr&gt;<br />&lt;tr class=&#8221;winner&#8221;&gt;&lt;td&gt;Player 2&lt;/td&gt;&lt;td&gt;1200&lt;/td&gt;&lt;/tr&gt;<br />&lt;tr&gt;&lt;td&gt;Player 3&lt;/td&gt;&lt;td&gt;900&lt;/td&gt;&lt;/tr&gt;<br />&lt;tr&gt;&lt;td&gt;Player 4&lt;/td&gt;&lt;td&gt;800&lt;/td&gt;&lt;/tr&gt;<br />&lt;/tbody&gt;<br />&lt;/table&gt;<br />&lt;/div&gt;</p>
<p>&lt;!&#8211; Inline CSS variables for preview &#8211;&gt;<br />&lt;style&gt;<br />:root {<br />&#8211;ts-header-bg: &lt;?php echo esc_attr($options[&#8216;header_bg&#8217;]); ?&gt;;<br />&#8211;ts-header-text: &lt;?php echo esc_attr($options[&#8216;header_text&#8217;]); ?&gt;;<br />&#8211;ts-row-even: &lt;?php echo esc_attr($options[&#8216;row_even&#8217;]); ?&gt;;<br />&#8211;ts-row-odd: &lt;?php echo esc_attr($options[&#8216;row_odd&#8217;]); ?&gt;;<br />&#8211;ts-winner-bg: &lt;?php echo esc_attr($options[&#8216;winner_bg&#8217;]); ?&gt;;<br />&#8211;ts-table-text: &lt;?php echo esc_attr($options[&#8216;table_text&#8217;]); ?&gt;;<br />&#8211;ts-border: rgba(0,0,0,0.1);<br />&#8211;ts-hover: rgba(0,0,0,0.05);<br />}<br />&lt;/style&gt;</p>
<p>&lt;!&#8211; JS for Presets and Live Preview &#8211;&gt;<br />&lt;script&gt;<br />function updatePreview() {<br />const root = document.documentElement;<br />const fields = [&#8216;header_bg&#8217;,&#8217;header_text&#8217;,&#8217;row_even&#8217;,&#8217;row_odd&#8217;,&#8217;winner_bg&#8217;,&#8217;table_text&#8217;];<br />fields.forEach(key =&gt; {<br />const input = document.querySelector(`[name=&#8221;${key}&#8221;]`);<br />if (input) {<br />let varName = &#8216;&#8211;ts-&#8216; + (key === &#8216;table_text&#8217; ? &#8216;table-text&#8217; : key.replace(&#8216;_&#8217;,&#8217;-&#8216;));<br />root.style.setProperty(varName, input.value);<br />}<br />});<br />}</p>
<p>document.querySelectorAll(&#8216;input[type=&#8221;color&#8221;]&#8217;).forEach(input =&gt; {<br />input.addEventListener(&#8216;input&#8217;, updatePreview);<br />});</p>
<p>document.querySelectorAll(&#8216;.ts-preset&#8217;).forEach(btn =&gt; {<br />btn.addEventListener(&#8216;click&#8217;, () =&gt; {<br />const preset = JSON.parse(btn.dataset.preset);<br />for (const key in preset) {<br />const input = document.querySelector(`[name=&#8221;${key}&#8221;]`);<br />if (input) input.value = preset[key];<br />}<br />updatePreview();<br />});<br />});</p>
<p>updatePreview();<br />&lt;/script&gt;<br />&lt;?php<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />FRONTEND STYLES (ADMIN COLORS)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_action(&#8216;wp_enqueue_scripts&#8217;, function () {</p>
<p>$s = get_option(&#8216;ts_table_styles&#8217;, []);<br />$s = wp_parse_args($s, [<br />&#8216;header_bg&#8217; =&gt; &#8216;#4CAF50&#8217;,<br />&#8216;header_text&#8217; =&gt; &#8216;#ffffff&#8217;,<br />&#8216;row_even&#8217; =&gt; &#8216;#f2f2f2&#8217;,<br />&#8216;row_odd&#8217; =&gt; &#8216;#ffffff&#8217;,<br />&#8216;winner_bg&#8217; =&gt; &#8216;#d4edda&#8217;,<br />&#8216;table_text&#8217; =&gt; &#8216;#000000&#8217;<br />]);</p>
<p>wp_register_style(&#8216;ts-table-styles&#8217;, false);<br />wp_enqueue_style(&#8216;ts-table-styles&#8217;);</p>
<p>$css = &#8220;<br />:root {<br />&#8211;ts-header-bg: {$s[&#8216;header_bg&#8217;]};<br />&#8211;ts-header-text: {$s[&#8216;header_text&#8217;]};<br />&#8211;ts-row-even: {$s[&#8216;row_even&#8217;]};<br />&#8211;ts-row-odd: {$s[&#8216;row_odd&#8217;]};<br />&#8211;ts-winner-bg: {$s[&#8216;winner_bg&#8217;]};<br />&#8211;ts-table-text: {$s[&#8216;table_text&#8217;]};<br />&#8211;ts-border: rgba(0,0,0,0.12);<br />&#8211;ts-hover: rgba(0,0,0,0.06);<br />}</p>
<p>table.tournament-table {<br />width: 100%;<br />border-collapse: collapse;<br />border-radius: 8px;<br />overflow: hidden;<br />color: var(&#8211;ts-table-text);<br />}</p>
<p>table.tournament-table thead th {<br />background: var(&#8211;ts-header-bg);<br />color: var(&#8211;ts-header-text);<br />padding: 10px;<br />text-align: center;<br />}</p>
<p>table.tournament-table tbody td {<br />padding: 10px;<br />text-align: center;<br />border-bottom: 1px solid var(&#8211;ts-border);<br />}</p>
<p>/* ONLY body rows */<br />table.tournament-table tbody tr:nth-child(odd) td {<br />background: var(&#8211;ts-row-odd);<br />}</p>
<p>table.tournament-table tbody tr:nth-child(even) td {<br />background: var(&#8211;ts-row-even);<br />}</p>
<p>table.tournament-table tbody tr:hover td {<br />background: var(&#8211;ts-hover);<br />}</p>
<p>/* Winner row */<br />table.tournament-table tr.winner td {<br />background: var(&#8211;ts-winner-bg) !important;<br />font-weight: bold;<br />}<br />&#8220;;</p>
<p>wp_add_inline_style(&#8216;ts-table-styles&#8217;, $css);<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />REGISTER POST TYPE<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_action(&#8216;init&#8217;, function () {<br />register_post_type(&#8216;tournament&#8217;, [<br />&#8216;labels&#8217; =&gt; [<br />&#8216;name&#8217; =&gt; &#8216;Rummy Royale&#8217;,<br />&#8216;singular_name&#8217; =&gt; &#8216;Tournament&#8217;<br />],<br />&#8216;public&#8217; =&gt; true,<br />&#8216;show_in_rest&#8217; =&gt; true,<br />&#8216;supports&#8217; =&gt; [&#8216;title&#8217;, &#8216;editor&#8217;],<br />&#8216;menu_icon&#8217; =&gt; &#8216;dashicons-awards&#8217;<br />]);<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />REGISTER TAXONOMY<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_action(&#8216;init&#8217;, function () {<br />register_taxonomy(&#8216;tournament_category&#8217;, &#8216;tournament&#8217;, [<br />&#8216;labels&#8217; =&gt; [<br />&#8216;name&#8217; =&gt; &#8216;Tournament Categories&#8217;,<br />&#8216;singular_name&#8217; =&gt; &#8216;Tournament Category&#8217;,<br />&#8216;search_items&#8217; =&gt; &#8216;Search Categories&#8217;,<br />&#8216;all_items&#8217; =&gt; &#8216;All Categories&#8217;,<br />&#8216;edit_item&#8217; =&gt; &#8216;Edit Category&#8217;,<br />&#8216;update_item&#8217; =&gt; &#8216;Update Category&#8217;,<br />&#8216;add_new_item&#8217; =&gt; &#8216;Add New Category&#8217;,<br />&#8216;new_item_name&#8217; =&gt; &#8216;New Category Name&#8217;,<br />&#8216;menu_name&#8217; =&gt; &#8216;Categories&#8217;,<br />],<br />&#8216;hierarchical&#8217; =&gt; true,<br />&#8216;show_ui&#8217; =&gt; true,<br />&#8216;show_admin_column&#8217; =&gt; true,<br />&#8216;show_in_rest&#8217; =&gt; true,<br />&#8216;rewrite&#8217; =&gt; [&#8216;slug&#8217; =&gt; &#8216;tournament-category&#8217;],<br />&#8216;show_in_menu&#8217; =&gt; false, // &lt;&#8211; This prevents WordPress from adding the top-level menu<br />]);<br />});</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CLEAN TOURNAMENT ADMIN MENU<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function ts_clean_tournament_admin_menu() {<br />// Remove default Add New submenu (WordPress adds automatically)<br />remove_submenu_page(&#8216;edit.php?post_type=tournament&#8217;, &#8216;post-new.php?post_type=tournament&#8217;);</p>
<p>// Remove extra top-level Categories menu (WordPress adds automatically for taxonomy)<br />remove_menu_page(&#8216;edit-tags.php?taxonomy=tournament_category&amp;post_type=tournament&#8217;);<br />}<br />add_action(&#8216;admin_menu&#8217;, &#8216;ts_clean_tournament_admin_menu&#8217;, 999);</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />META BOXES<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_action(&#8216;add_meta_boxes&#8217;, function () {<br />add_meta_box(&#8216;ts_players&#8217;, &#8216;Players&#8217;, &#8216;ts_players_box&#8217;, &#8216;tournament&#8217;);<br />add_meta_box(&#8216;ts_games&#8217;, &#8216;Games &amp; Scores&#8217;, &#8216;ts_games_box&#8217;, &#8216;tournament&#8217;);<br />add_meta_box(&#8216;ts_mode&#8217;, &#8216;Tournament Mode&#8217;, &#8216;ts_mode_box&#8217;, &#8216;tournament&#8217;, &#8216;side&#8217;);<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />MODE BOX (Individual / Teams / 1v1)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function ts_mode_box($post) {<br />$mode = get_post_meta($post-&gt;ID, &#8216;ts_mode&#8217;, true);<br />if (!$mode) $mode = &#8216;individual&#8217;;<br />?&gt;<br />&lt;label&gt;&lt;input type=&#8221;radio&#8221; name=&#8221;ts_mode&#8221; value=&#8221;individual&#8221; &lt;?php checked($mode, &#8216;individual&#8217;); ?&gt;&gt; Individual&lt;/label&gt;&lt;br&gt;<br />&lt;label&gt;&lt;input type=&#8221;radio&#8221; name=&#8221;ts_mode&#8221; value=&#8221;teams&#8221; &lt;?php checked($mode, &#8216;teams&#8217;); ?&gt;&gt; Teams (Odd vs Even)&lt;/label&gt;&lt;br&gt;<br />&lt;label&gt;&lt;input type=&#8221;radio&#8221; name=&#8221;ts_mode&#8221; value=&#8221;1v1&#8243; &lt;?php checked($mode, &#8216;1v1&#8217;); ?&gt;&gt; 1 vs 1&lt;/label&gt;<br />&lt;p style=&#8221;color:#555;font-size:12px;&#8221;&gt;1v1 mode allows only 2 players. Stats will appear in 1v1 head-to-head reports.&lt;/p&gt;</p>
<p>&lt;script&gt;<br />document.addEventListener(&#8216;DOMContentLoaded&#8217;, function(){<br />const modeInputs = document.querySelectorAll(&#8216;input[name=&#8221;ts_mode&#8221;]&#8217;);</p>
<p>function updatePlayerFields(mode) {<br />const playerInputs = document.querySelectorAll(&#8216;#ts_players input[type=&#8221;text&#8221;]&#8217;);<br />if(mode === &#8216;1v1&#8217;){<br />// Show only first 2 player fields<br />playerInputs.forEach((p,i)=&gt;p.parentElement.style.display=(i&lt;2?&#8217;block&#8217;:&#8217;none&#8217;));<br />} else {<br />// Show all 7 fields<br />playerInputs.forEach(p=&gt;p.parentElement.style.display=&#8217;block&#8217;);<br />}<br />}</p>
<p>// Listen for mode change<br />modeInputs.forEach(input=&gt;{<br />input.addEventListener(&#8216;change&#8217;, function(){<br />updatePlayerFields(this.value);<br />});<br />});</p>
<p>// Apply visibility on page load<br />const checkedMode = document.querySelector(&#8216;input[name=&#8221;ts_mode&#8221;]:checked&#8217;);<br />if(checkedMode) updatePlayerFields(checkedMode.value);</p>
<p>// Re-apply visibility after adding a new game<br />const addGameBtn = document.getElementById(&#8216;ts-add-game&#8217;);<br />if(addGameBtn){<br />addGameBtn.addEventListener(&#8216;click&#8217;, function(){<br />// Add game row<br />var table = document.getElementById(&#8216;ts-games-table&#8217;);<br />var rowCount = table.rows.length;<br />var newRow = table.insertRow(-1);<br />newRow.insertCell(0).innerText = &#8216;Game &#8216; + rowCount;</p>
<p>var players = table.rows[0].cells.length &#8211; 1;<br />for (var i = 0; i &lt; players; i++) {<br />newRow.insertCell(-1).innerHTML =<br />&#8216;&lt;input type=&#8221;number&#8221; name=&#8221;ts_games[&#8216;+(rowCount-1)+&#8217;][&#8216;+i+&#8217;]&#8221;&gt;&#8217;;<br />}</p>
<p>// Re-apply player visibility based on current mode<br />const checkedMode = document.querySelector(&#8216;input[name=&#8221;ts_mode&#8221;]:checked&#8217;);<br />if(checkedMode) updatePlayerFields(checkedMode.value);<br />});<br />}<br />});<br />&lt;/script&gt;<br />&lt;?php<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />PLAYERS BOX<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function ts_players_box($post) {<br />wp_nonce_field(&#8216;ts_save&#8217;, &#8216;ts_nonce&#8217;);<br />$players = get_post_meta($post-&gt;ID, &#8216;ts_players&#8217;, true);<br />if (!is_array($players)) $players = array_fill(0, 9, &#8221;);</p>
<p>echo &#8216;&lt;p&gt;Enter up to 9 players:&lt;/p&gt;&#8217;;<br />for ($i = 0; $i &lt; 9; $i++) {<br />echo &#8216;&lt;div style=&#8221;margin-bottom:5px&#8221;&gt;&#8217;;<br />echo &#8216;&lt;input style=&#8221;width:100%&#8221; type=&#8221;text&#8221; <br />name=&#8221;ts_players[&#8216;.$i.&#8217;]&#8221; <br />value=&#8221;&#8216;.esc_attr($players[$i]).'&#8221; <br />placeholder=&#8221;Player &#8216;.($i+1).'&#8221;&gt;&#8217;;<br />echo &#8216;&lt;/div&gt;&#8217;;<br />}<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />GAMES BOX<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211; */<br />function ts_games_box($post) {<br />$players = get_post_meta($post-&gt;ID, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($post-&gt;ID, &#8216;ts_games&#8217;, true);<br />if (!is_array($games) || empty($games)) $games = array(array());</p>
<p>// Add JS to remove a game row when clicking &#8220;X&#8221;<br />echo &#8216;&lt;script&gt;<br />function tsDeleteGameRow(btn) {<br />const row = btn.closest(&#8220;tr&#8221;);<br />// Mark row for deletion<br />const index = row.getAttribute(&#8220;data-game-index&#8221;);<br />const input = document.createElement(&#8220;input&#8221;);<br />input.type = &#8220;hidden&#8221;;<br />input.name = &#8220;ts_delete_games[]&#8221;;<br />input.value = index;<br />row.parentNode.appendChild(input);<br />// Remove row visually<br />row.remove();<br />}<br />&lt;/script&gt;&#8217;;</p>
<p>echo &#8216;&lt;table id=&#8221;ts-games-table&#8221; border=&#8221;1&#8243; cellpadding=&#8221;5&#8243;&gt;&#8217;;</p>
<p>// Table header<br />echo &#8216;&lt;tr&gt;&lt;th&gt;Game&lt;/th&gt;&#8217;;<br />foreach ($players as $player) {<br />if ($player) echo &#8216;&lt;th&gt;&#8217;.esc_html($player).'&lt;/th&gt;&#8217;;<br />}<br />echo &#8216;&lt;th&gt;Delete&lt;/th&gt;&#8217;; // Delete column<br />echo &#8216;&lt;/tr&gt;&#8217;;</p>
<p>// Table rows<br />foreach ($games as $g =&gt; $game) {<br />echo &#8216;&lt;tr data-game-index=&#8221;&#8216;.$g.'&#8221;&gt;&#8217;;<br />echo &#8216;&lt;td&gt;Game &#8216;.($g+1).'&lt;/td&gt;&#8217;;</p>
<p>foreach ($players as $p =&gt; $player) {<br />if ($player) {<br />$score = isset($game[$p]) ? $game[$p] : &#8221;;<br />echo &#8216;&lt;td&gt;&lt;input type=&#8221;number&#8221; name=&#8221;ts_games[&#8216;.$g.&#8217;][&#8216;.$p.&#8217;]&#8221; value=&#8221;&#8216;.esc_attr($score).'&#8221;&gt;&lt;/td&gt;&#8217;;<br />}<br />}</p>
<p>// Red X delete button<br />echo &#8216;&lt;td style=&#8221;text-align:center;&#8221;&gt;<br />&lt;button type=&#8221;button&#8221; onclick=&#8221;tsDeleteGameRow(this)&#8221; style=&#8221;<br />color:#fff;<br />background:#e74c3c;<br />border:none;<br />border-radius:4px;<br />padding:2px 6px;<br />cursor:pointer;<br />font-weight:bold;<br />&#8220;&gt;X&lt;/button&gt;<br />&lt;/td&gt;&#8217;;</p>
<p>echo &#8216;&lt;/tr&gt;&#8217;;<br />}</p>
<p>echo &#8216;&lt;/table&gt;&#8217;;<br />echo &#8216;&lt;button type=&#8221;button&#8221; id=&#8221;ts-add-game&#8221; style=&#8221;margin-top:10px;&#8221;&gt;Add Game&lt;/button&gt;&#8217;;<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />TEAM HELPERS<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function ts_get_teams($players) {<br />$teams = array(&#8216;A&#8217;=&gt;array(), &#8216;B&#8217;=&gt;array());<br />foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;<br />if (($i + 1) % 2 === 1) $teams[&#8216;A&#8217;][] = array(&#8216;index&#8217;=&gt;$i,&#8217;name&#8217;=&gt;$name);<br />else $teams[&#8216;B&#8217;][] = array(&#8216;index&#8217;=&gt;$i,&#8217;name&#8217;=&gt;$name);<br />}<br />return $teams;<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />SAVE DATA (Updated)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_action(&#8216;save_post_tournament&#8217;, function ($post_id) {<br />if (defined(&#8216;DOING_AUTOSAVE&#8217;) &amp;&amp; DOING_AUTOSAVE) return;<br />if (!isset($_POST[&#8216;ts_nonce&#8217;])) return;<br />if (!wp_verify_nonce($_POST[&#8216;ts_nonce&#8217;], &#8216;ts_save&#8217;)) return;<br />if (!current_user_can(&#8216;edit_post&#8217;, $post_id)) return;</p>
<p>$mode = sanitize_text_field($_POST[&#8216;ts_mode&#8217;] ?? &#8216;individual&#8217;);<br />update_post_meta($post_id, &#8216;ts_mode&#8217;, $mode);</p>
<p>$players = isset($_POST[&#8216;ts_players&#8217;]) ? array_map(&#8216;sanitize_text_field&#8217;, $_POST[&#8216;ts_players&#8217;]) : [];<br />if($mode === &#8216;1v1&#8217;) $players = array_slice($players, 0, 2); // enforce only 2 players<br />update_post_meta($post_id, &#8216;ts_players&#8217;, $players);</p>
<p>$games = $_POST[&#8216;ts_games&#8217;] ?? array();<br />$clean_games = [];<br />foreach ($games as $g) {<br />$row = [];<br />foreach ($g as $score) $row[] = intval($score);<br />$clean_games[] = $row;<br />}<br />update_post_meta($post_id, &#8216;ts_games&#8217;, $clean_games);<br />});</p>
<p>add_action(&#8216;admin_post_finish_tournament&#8217;, &#8216;ts_finish_tournament_handler&#8217;);<br />add_action(&#8216;admin_post_nopriv_finish_tournament&#8217;, &#8216;ts_finish_tournament_handler&#8217;);</p>
<p>function ts_finish_tournament_handler() {<br />// Verify nonce<br />if (!isset($_POST[&#8216;ts_finish_nonce&#8217;]) || !wp_verify_nonce($_POST[&#8216;ts_finish_nonce&#8217;], &#8216;ts_finish_tournament&#8217;)) {<br />wp_die(&#8216;Nonce verification failed&#8217;);<br />}</p>
<p>// Get tournament ID<br />$tournament_id = intval($_POST[&#8216;tournament_id&#8217;]);<br />if (!$tournament_id) wp_die(&#8216;Invalid tournament ID&#8217;);</p>
<p>// Optional: check user permissions<br />if (!current_user_can(&#8216;manage_options&#8217;)) {<br />wp_die(&#8216;You do not have permission to finish this tournament&#8217;);<br />}</p>
<p>// Mark tournament as finished<br />update_post_meta($tournament_id, &#8216;ts_finished&#8217;, 1);</p>
<p>// Handle auto-finish winner if provided<br />if (isset($_POST[&#8216;ts_finish_auto&#8217;]) &amp;&amp; $_POST[&#8216;ts_finish_auto&#8217;] == &#8216;1&#8217; &amp;&amp; !empty($_POST[&#8216;ts_winner_name_auto&#8217;])) {<br />$winner_name = sanitize_text_field($_POST[&#8216;ts_winner_name_auto&#8217;]);<br />update_post_meta($tournament_id, &#8216;ts_1000plus_winner&#8217;, $winner_name);<br />set_transient(&#8216;ts_1000plus_message_&#8217; . $tournament_id, $winner_name, 30);<br />}</p>
<p>// Redirect back to tournament page<br />wp_safe_redirect(get_permalink($tournament_id));<br />exit;<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />FRONTEND SHORTCODE<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_scores&#8217;, function () {<br />global $post;<br />$players = get_post_meta($post-&gt;ID, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($post-&gt;ID, &#8216;ts_games&#8217;, true);<br />$mode = get_post_meta($post-&gt;ID, &#8216;ts_mode&#8217;, true);<br />$finished = get_post_meta($post-&gt;ID, &#8216;ts_finished&#8217;, true);</p>
<p>if (!$mode) $mode = &#8216;individual&#8217;;<br />if (!is_array($players) || empty($players)) return &#8216;No players found.&#8217;;<br />if (!is_array($games) || empty($games)) $games = array();</p>
<p>&nbsp;</p>
<p>// Remove the &#8220;has_scores&#8221; check<br />// $has_scores = false; // no longer needed</p>
<p>// Handle Finish Tournament (ADMIN ONLY)<br />if (<br />isset($_POST[&#8216;ts_finish_tournament&#8217;], $_POST[&#8216;ts_finish_nonce&#8217;]) &amp;&amp;<br />$_POST[&#8216;ts_finish_tournament&#8217;] === &#8216;1&#8217; &amp;&amp;<br />wp_verify_nonce($_POST[&#8216;ts_finish_nonce&#8217;], &#8216;ts_finish_tournament&#8217;) &amp;&amp;<br />current_user_can(&#8216;manage_options&#8217;)<br />) {<br />update_post_meta($post-&gt;ID, &#8216;ts_finished&#8217;, 1);</p>
<p>// Auto 1000+ end<br />if (isset($_POST[&#8216;ts_finish_auto&#8217;]) &amp;&amp; $_POST[&#8216;ts_finish_auto&#8217;] == &#8216;1&#8217; &amp;&amp; !empty($_POST[&#8216;ts_winner_name_auto&#8217;])) {<br />$winner_name = sanitize_text_field($_POST[&#8216;ts_winner_name_auto&#8217;]);<br />update_post_meta($post-&gt;ID, &#8216;ts_1000plus_winner&#8217;, $winner_name);<br />set_transient(&#8216;ts_1000plus_message_&#8217; . $post-&gt;ID, $winner_name, 30);<br />}</p>
<p>// Refresh page to show finished tables<br />wp_safe_redirect(get_permalink($post-&gt;ID));<br />exit;<br />}</p>
<p>&nbsp;</p>
<p>// Calculate totals<br />$totals = array_fill(0, count($players), 0);<br />foreach ($games as $game) {<br />foreach ($game as $p =&gt; $score) $totals[$p] += intval($score);<br />}</p>
<p>$out = &#8221;;</p>
<p>// &#8212; Buttons &#8212;<br />if (!$finished &amp;&amp; current_user_can(&#8216;manage_options&#8217;)) {</p>
<p>// Normal Finish Tournament button<br />$out .= &#8216;&lt;form method=&#8221;post&#8221; action=&#8221;&#8216; . admin_url(&#8216;admin-post.php&#8217;) . &#8216;&#8221; style=&#8221;display:inline-block;margin-right:10px;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;input type=&#8221;hidden&#8221; name=&#8221;action&#8221; value=&#8221;finish_tournament&#8221;&gt;&#8217;;<br />$out .= wp_nonce_field(&#8216;ts_finish_tournament&#8217;, &#8216;ts_finish_nonce&#8217;, true, false);<br />$out .= &#8216;&lt;input type=&#8221;hidden&#8221; name=&#8221;tournament_id&#8221; value=&#8221;&#8216; . get_the_ID() . &#8216;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;input type=&#8221;hidden&#8221; name=&#8221;ts_finish_auto&#8221; value=&#8221;0&#8243;&gt;&#8217;;<br />$out .= &#8216;&lt;button type=&#8221;submit&#8221; style=&#8221;padding:10px 20px;background:#4CAF50;color:#fff;border:none;border-radius:4px;font-size:16px;margin-bottom:20px;&#8221;&gt;Finish Tournament&lt;/button&gt;&#8217;;<br />$out .= &#8216;&lt;/form&gt;&#8217;;</p>
<p>// Auto-End Game if any player &gt;= 1000<br />foreach ($totals as $i =&gt; $score) {<br />if ($score &gt;= 1000) {<br />$winner_name = $players[$i];</p>
<p>$out .= &#8216;&lt;form id=&#8221;ts_auto_finish_form&#8221; method=&#8221;post&#8221; action=&#8221;&#8216; . admin_url(&#8216;admin-post.php&#8217;) . &#8216;&#8221; style=&#8221;display:none;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;input type=&#8221;hidden&#8221; name=&#8221;action&#8221; value=&#8221;finish_tournament&#8221;&gt;&#8217;;<br />$out .= wp_nonce_field(&#8216;ts_finish_tournament&#8217;, &#8216;ts_finish_nonce&#8217;, true, false);<br />$out .= &#8216;&lt;input type=&#8221;hidden&#8221; name=&#8221;tournament_id&#8221; value=&#8221;&#8216; . get_the_ID() . &#8216;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;input type=&#8221;hidden&#8221; name=&#8221;ts_finish_auto&#8221; value=&#8221;1&#8243;&gt;&#8217;;<br />$out .= &#8216;&lt;input type=&#8221;hidden&#8221; name=&#8221;ts_winner_name_auto&#8221; value=&#8221;&#8216; . esc_attr($winner_name) . &#8216;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;/form&gt;&#8217;;</p>
<p>// Auto-submit script<br />$out .= &#8216;&lt;script type=&#8221;text/javascript&#8221;&gt;<br />document.addEventListener(&#8220;DOMContentLoaded&#8221;, function() {<br />document.getElementById(&#8220;ts_auto_finish_form&#8221;).submit();<br />});<br />&lt;/script&gt;&#8217;;</p>
<p>break; // only trigger for first player reaching 1000<br />}<br />}</p>
<p>}</p>
<p>&nbsp;</p>
<p>// &#8212; Display message for 1000+ end &#8212;<br />if ($msg_player = get_transient(&#8216;ts_1000plus_message_&#8217; . $post-&gt;ID)) {<br />delete_transient(&#8216;ts_1000plus_message_&#8217; . $post-&gt;ID);<br />$out .= &#8216;&lt;p style=&#8221;background:#d4edda;padding:10px;border:1px solid #4CAF50;&#8221;&gt;<br /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Congratulations &#8216;.esc_html($msg_player).&#8217;! You reached 1000+ points and the game has ended! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br />&lt;/p&gt;&#8217;;<br />}</p>
<p>&nbsp;</p>
<p>if ($msg_team = get_transient(&#8216;ts_1000plus_team_message_&#8217; . $post-&gt;ID)) {<br />delete_transient(&#8216;ts_1000plus_team_message_&#8217; . $post-&gt;ID);<br />$out .= &#8216;&lt;p style=&#8221;background:#d4edda;padding:10px;border:1px solid #4CAF50;&#8221;&gt;<br /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Congratulations Team &#8216;.$msg_team[&#8216;team&#8217;].&#8217; (&#8216;.implode(&#8216;, &#8216;, $msg_team[&#8216;members&#8217;]).&#8217;)! You reached 1000+ points! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br />&lt;/p&gt;&#8217;;<br />}</p>
<p>// &#8212; Game-by-Game Scores &#8212;<br />if (!empty($games)) {<br />$out .= &#8216;&lt;h3&gt;Game-by-Game Scores&lt;/h3&gt;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;tr&gt;&lt;th&gt;Game&lt;/th&gt;&#8217;;<br />foreach ($players as $p =&gt; $name) if ($name) $out .= &#8216;&lt;th&gt;&#8217;.esc_html($name).'&lt;/th&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;</p>
<p>$totals_for_table = array_fill(0, count($players), 0);</p>
<p>foreach ($games as $g =&gt; $game) {<br />$out .= &#8216;&lt;tr&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&lt;strong&gt;Game &#8216;.($g+1).'&lt;/strong&gt;&lt;/td&gt;&#8217;;</p>
<p>foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;<br />$score = isset($game[$p]) ? intval($game[$p]) : 0; // 0 if not played<br />$totals_for_table[$p] += $score;<br />$out .= &#8216;&lt;td&gt;&#8217;.$score.'&lt;/td&gt;&#8217;;<br />}</p>
<p>$out .= &#8216;&lt;/tr&gt;&#8217;;<br />}</p>
<p>// TOTAL row<br />$out .= &#8216;&lt;tr class=&#8221;total-row&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;TOTAL&lt;/td&gt;&#8217;;</p>
<p>foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;<br />$out .= &#8216;&lt;td&gt;&#8217; . intval($totals_for_table[$p]) . &#8216;&lt;/td&gt;&#8217;;<br />}</p>
<p>$out .= &#8216;&lt;/tr&gt;&#8217;;<br />$out .= &#8216;&lt;/table&gt;&#8217;;</p>
<p>}</p>
<p>// &#8212; Individual Mode &#8212;<br />if ($mode === &#8216;individual&#8217;) {<br />$max_total = max($totals);<br />$winning_indexes = [];<br />foreach ($totals as $p =&gt; $total) if ($total === $max_total &amp;&amp; $total &gt; 0) $winning_indexes[] = $p;</p>
<p>if ($finished &amp;&amp; !empty($winning_indexes)) {<br />foreach ($winning_indexes as $i) {<br />$out .= &#8216;&lt;p style=&#8221;background:#e6ffe6;padding:10px;border:1px solid #4CAF50;&#8221;&gt;<br /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Congratulations &#8216;.esc_html($players[$i]).&#8217;! You won with &#8216;.$totals[$i].&#8217; points! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br />&lt;/p&gt;&#8217;;<br />}<br />}</p>
<p>$rows = [];<br />foreach ($players as $i =&gt; $name) if ($name) $rows[] = [&#8216;index&#8217;=&gt;$i,&#8217;name&#8217;=&gt;$name,&#8217;total&#8217;=&gt;$totals[$i]];<br />usort($rows, fn($a,$b)=&gt;$b[&#8216;total&#8217;]-$a[&#8216;total&#8217;]);</p>
<p>$out .= &#8216;&lt;h3&gt;Leaderboard&lt;/h3&gt;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;<br />$rank = 1;<br />foreach ($rows as $row) {<br />$highlight = ($finished &amp;&amp; in_array($row[&#8216;index&#8217;], $winning_indexes)) ? &#8216; style=&#8221;background:#e6ffe6;font-weight:bold&#8221;&#8216; : &#8221;;<br />$trophy = ($finished &amp;&amp; in_array($row[&#8216;index&#8217;], $winning_indexes)) ? &#8216; <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217; : &#8221;;<br />$out .= &#8216;&lt;tr&#8217;.$highlight.&#8217;&gt;&lt;td&gt;&#8217;.$rank.'&lt;/td&gt;&lt;td&gt;&#8217;.esc_html($row[&#8216;name&#8217;]).$trophy.'&lt;/td&gt;&lt;td&gt;&#8217;.$row[&#8216;total&#8217;].'&lt;/td&gt;&lt;/tr&gt;&#8217;;<br />$rank++;<br />}<br />$out .= &#8216;&lt;/table&gt;&#8217;;<br />return $out;<br />}</p>
<p>// SAFETY: never allow team data in 1v1<br />if ($mode === &#8216;1v1&#8217;) {<br />delete_transient(&#8216;ts_1000plus_team_message_&#8217; . $post-&gt;ID);<br />$winning_teams = [];<br />$teams = [];<br />$team_totals = [];<br />}</p>
<p>// &#8212; TEAM MODE ONLY &#8212;<br />if ($mode === &#8216;teams&#8217;) {</p>
<p>$teams = ts_get_teams($players); // get team members<br />$team_totals = [&#8216;A&#8217;=&gt;0,&#8217;B&#8217;=&gt;0]; // initialize totals</p>
<p>// Sum team points from games<br />foreach ($games as $game) {<br />foreach ($teams as $team =&gt; $members) {<br />foreach ($members as $m) {<br />$team_totals[$team] += $game[$m[&#8216;index&#8217;]] ?? 0;<br />}<br />}<br />}</p>
<p>// Check if any team reached 1000+ points<br />foreach ($team_totals as $team =&gt; $total) {<br />if ($total &gt;= 1000) {</p>
<p>// Get team member names<br />$winner_names = array_map(fn($m) =&gt; $m[&#8216;name&#8217;], $teams[$team]);<br />$winner_display = implode(&#8216;, &#8216;, $winner_names);</p>
<p>// Store winner in post meta<br />update_post_meta($post-&gt;ID, &#8216;ts_1000plus_winner_team&#8217;, [<br />&#8216;team&#8217; =&gt; $team,<br />&#8216;members&#8217; =&gt; $winner_names,<br />&#8216;total_points&#8217; =&gt; $total<br />]);</p>
<p>// Set transient for message (like individual)<br />set_transient(&#8216;ts_1000plus_team_message_&#8217; . $post-&gt;ID, [<br />&#8216;team&#8217; =&gt; $team,<br />&#8216;members&#8217; =&gt; $winner_names,<br />&#8216;total_points&#8217; =&gt; $total<br />], 30); // 30 seconds</p>
<p>// Mark the game finished<br />$finished = true;<br />update_post_meta($post-&gt;ID, &#8216;ts_finished&#8217;, 1);</p>
<p>break; // stop after first team reaching 1000<br />}<br />}</p>
<p>// &#8212; Display team 1000+ message (like individual) &#8212;<br />if ($msg_team = get_transient(&#8216;ts_1000plus_team_message_&#8217; . $post-&gt;ID)) {<br />delete_transient(&#8216;ts_1000plus_team_message_&#8217; . $post-&gt;ID);</p>
<p>$out .= &#8216;&lt;p style=&#8221;background:#d4edda;padding:10px;border:1px solid #4CAF50;&#8221;&gt;<br /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Congratulations Team &#8216;.esc_html($msg_team[&#8216;team&#8217;]).&#8217; (&#8216;.implode(&#8216;, &#8216;, array_map(&#8216;esc_html&#8217;, $msg_team[&#8216;members&#8217;])).&#8217;)! <br />You reached 1000+ points! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br />&lt;/p&gt;&#8217;;</p>
<p>// Ensure finished flag is true for display logic<br />$finished = true;<br />update_post_meta($post-&gt;ID, &#8216;ts_finished&#8217;, 1);<br />}</p>
<p>// Determine winning teams for leaderboard (even if &lt;1000)<br />$max_total = max($team_totals);<br />$winning_teams = [];<br />foreach ($team_totals as $team =&gt; $total) {<br />if ($total === $max_total &amp;&amp; $total &gt; 0) {<br />$winning_teams[] = $team;<br />}<br />}<br />}</p>
<p>// &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />// OUTPUT WINNER MESSAGE<br />// &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>// 1v1 MODE → PLAYER WINNER ONLY<br />if ($mode === &#8216;1v1&#8217;) {</p>
<p>$winner_index = array_search(max($totals), $totals);</p>
<p>if ($finished &amp;&amp; isset($players[$winner_index])) {<br />$out .= &#8216;&lt;p style=&#8221;background:#e6ffe6;padding:10px;border:1px solid #4CAF50;&#8221;&gt;<br /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Congratulations &#8216;.esc_html($players[$winner_index]).&#8217;! <br />You won with &#8216;.$totals[$winner_index].&#8217; points! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br />&lt;/p&gt;&#8217;;<br />}</p>
<p>// TEAMS MODE → TEAM WINNER ONLY<br />} elseif ($mode === &#8216;teams&#8217;) {</p>
<p>if ($finished &amp;&amp; !empty($winning_teams)) {<br />foreach ($winning_teams as $team) {<br />$names = implode(&#8216;, &#8216;, array_map(fn($m) =&gt; $m[&#8216;name&#8217;], $teams[$team]));<br />$out .= &#8216;&lt;p style=&#8221;background:#e6ffe6;padding:10px;border:1px solid #4CAF50;&#8221;&gt;<br /><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Congratulations Team &#8216;.$team.&#8217; (&#8216;.$names.&#8217;)! <br />You won with &#8216;.$team_totals[$team].&#8217; points! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br />&lt;/p&gt;&#8217;;<br />}<br />}<br />}</p>
<p>&nbsp;</p>
<p>// Only show Team Summary if not 1v1<br />if (!($mode === &#8216;1v1&#8217; || (count(array_filter($players)) === 2 &amp;&amp; $mode === &#8216;teams&#8217;))) {<br />$out .= &#8216;&lt;h3&gt;Team Summary&lt;/h3&gt;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;tr&gt;&lt;th&gt;Team&lt;/th&gt;&lt;th&gt;Players&lt;/th&gt;&lt;th&gt;Total Points&lt;/th&gt;&lt;/tr&gt;&#8217;;<br />foreach ($team_totals as $team =&gt; $total) {<br />$names = implode(&#8216;, &#8216;, array_map(fn($m) =&gt; $m[&#8216;name&#8217;], $teams[$team]));<br />$highlight = ($finished &amp;&amp; in_array($team, $winning_teams)) ? &#8216; style=&#8221;background:#e6ffe6;font-weight:bold&#8221;&#8216; : &#8221;;<br />$trophy = ($finished &amp;&amp; in_array($team, $winning_teams)) ? &#8216; <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217; : &#8221;;<br />$out .= &#8216;&lt;tr&#8217;.$highlight.&#8217;&gt;&lt;td&gt;Team &#8216;.$team.$trophy.'&lt;/td&gt;&lt;td&gt;&#8217;.$names.'&lt;/td&gt;&lt;td&gt;&#8217;.$total.'&lt;/td&gt;&lt;/tr&gt;&#8217;;<br />}<br />$out .= &#8216;&lt;/table&gt;&#8217;;<br />}</p>
<p>// Individual Leaderboard within Team Mode<br />$rows = [];<br />foreach ($players as $i =&gt; $name) if ($name) $rows[] = [&#8216;index&#8217;=&gt;$i,&#8217;name&#8217;=&gt;$name,&#8217;total&#8217;=&gt;$totals[$i]];<br />usort($rows, fn($a,$b)=&gt;$b[&#8216;total&#8217;]-$a[&#8216;total&#8217;]);<br />$out .= &#8216;&lt;h3&gt;Leaderboard&lt;/h3&gt;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;<br />$rank = 1;<br />foreach ($rows as $row) {<br />$out .= &#8216;&lt;tr&gt;&lt;td&gt;&#8217;.$rank.'&lt;/td&gt;&lt;td&gt;&#8217;.esc_html($row[&#8216;name&#8217;]).'&lt;/td&gt;&lt;td&gt;&#8217;.$row[&#8216;total&#8217;].'&lt;/td&gt;&lt;/tr&gt;&#8217;;<br />$rank++;<br />}<br />$out .= &#8216;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>/**<br />* Shortcode: No finished 1v1 tournaments found.<br />* Displays finished 1v1 tournaments with game-by-game scores.<br />*/<br />add_shortcode(&#8216;tournament_1v1_stats&#8217;, function() {</p>
<p>// Get admin table colors<br />$s = get_option(&#8216;ts_table_styles&#8217;, []);<br />$s = wp_parse_args($s, [<br />&#8216;header_bg&#8217;=&gt;&#8217;#4CAF50&#8242;,&#8217;header_text&#8217;=&gt;&#8217;#ffffff&#8217;,<br />&#8216;row_even&#8217;=&gt;&#8217;#f2f2f2&#8242;,&#8217;row_odd&#8217;=&gt;&#8217;#ffffff&#8217;,<br />&#8216;winner_bg&#8217;=&gt;&#8217;#d4edda&#8217;,&#8217;table_text&#8217;=&gt;&#8217;#000000&#8242;<br />]);</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;1v1&#8217;],<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; &#8216;1&#8217;],<br />],<br />&#8216;orderby&#8217; =&gt; &#8216;date&#8217;,<br />&#8216;order&#8217; =&gt; &#8216;DESC&#8217;,<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished 1v1 tournaments found.&#8217;;</p>
<p>$out = &#8221;;</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$tournament_id = get_the_ID();<br />$tournament_name = get_the_title();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || count(array_filter($players)) &lt; 2) continue;<br />if (!is_array($games) || empty($games)) continue;</p>
<p>$active_players = array_values(array_filter($players)); // remove empty</p>
<p>$out .= &#8216;&lt;table class=&#8221;tournament-table&#8221; style=&#8221;width:100%; border-collapse:collapse; margin-top:20px;&#8221;&gt;&#8217;;</p>
<p>// &#8212; TITLE ROW SPANNED FULL WIDTH &#8212;<br />$colspan = count($active_players) + 1;<br />$out .= &#8216;&lt;thead&gt;&#8217;;<br />$out .= &#8216;&lt;tr style=&#8221;background:&#8217;.$s[&#8216;header_bg&#8217;].&#8217;; color:&#8217;.$s[&#8216;header_text&#8217;].&#8217;; font-weight:bold; text-align:center;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;th colspan=&#8221;&#8216;.$colspan.'&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3ae.png" alt="🎮" class="wp-smiley" style="height: 1em; max-height: 1em;" /> &#8216;.esc_html($tournament_name).&#8217; (1v1)&lt;/th&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;</p>
<p>// &#8212; COLUMN HEADERS &#8212;<br />$out .= &#8216;&lt;tr style=&#8221;background:&#8217;.$s[&#8216;header_bg&#8217;].&#8217;; color:&#8217;.$s[&#8216;header_text&#8217;].&#8217;;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;th&gt;Game&lt;/th&gt;&#8217;;<br />foreach ($active_players as $player) {<br />$out .= &#8216;&lt;th&gt;&#8217;.esc_html($player).'&lt;/th&gt;&#8217;;<br />}<br />$out .= &#8216;&lt;/tr&gt;&#8217;;<br />$out .= &#8216;&lt;/thead&gt;&#8217;;</p>
<p>$out .= &#8216;&lt;tbody&gt;&#8217;;<br />$totals = array_fill(0, count($active_players), 0);</p>
<p>// &#8212; GAME ROWS &#8212;<br />foreach ($games as $g =&gt; $game) {<br />$row_color = ($g % 2 === 0) ? $s[&#8216;row_even&#8217;] : $s[&#8216;row_odd&#8217;];<br />$out .= &#8216;&lt;tr style=&#8221;background:&#8217;.$row_color.&#8217;;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;Game &#8216;.($g+1).'&lt;/td&gt;&#8217;;<br />foreach ($active_players as $i =&gt; $player) {<br />$score = isset($game[$i]) ? intval($game[$i]) : 0;<br />$totals[$i] += $score;<br />$out .= &#8216;&lt;td&gt;&#8217;.$score.'&lt;/td&gt;&#8217;;<br />}<br />$out .= &#8216;&lt;/tr&gt;&#8217;;<br />}</p>
<p>// &#8212; TOTALS ROW &#8212;<br />$row_color = (count($games) % 2 === 0) ? $s[&#8216;row_even&#8217;] : $s[&#8216;row_odd&#8217;];<br />$out .= &#8216;&lt;tr style=&#8221;background:&#8217;.$row_color.&#8217;; font-weight:bold; border-top:2px solid &#8216;.$s[&#8216;header_bg&#8217;].&#8217;;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;Total&lt;/td&gt;&#8217;;<br />foreach ($totals as $total) $out .= &#8216;&lt;td&gt;&#8217;.$total.'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;</p>
<p>// &#8212; WINNER ROW &#8212;<br />$max_total = max($totals);<br />$winners = [];<br />foreach ($totals as $i =&gt; $total) {<br />if ($total === $max_total) $winners[] = $active_players[$i];<br />}<br />$winner_names = implode(&#8216;, &#8216;, $winners);</p>
<p>$out .= &#8216;&lt;tr class=&#8221;winner&#8221; style=&#8221;background:&#8217;.$s[&#8216;winner_bg&#8217;].&#8217;; font-weight:bold; text-align:center;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;td colspan=&#8221;&#8216;.$colspan.'&#8221;&gt;Winner: &#8216;.esc_html($winner_names).&#8217; <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /> (&#8216;.$max_total.&#8217; points)&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;&#8217;;<br />}</p>
<p>wp_reset_postdata();<br />return $out;<br />});</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CURRENT HIGHEST SCORE HOLDER (1v1 ONLY) &#8211; Clickable Tournament<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_highest_1v1_holder&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;1v1&#8217;],<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished 1v1 tournaments found.&#8217;;</p>
<p>$highest_score = 0;<br />$holder = [&#8216;player&#8217;=&gt;&#8221;,&#8217;score&#8217;=&gt;0,&#8217;tournament&#8217;=&gt;&#8221;,&#8217;game&#8217;=&gt;&#8221;,&#8217;tournament_id&#8217;=&gt;0];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$tournament_id = get_the_ID();<br />$tournament_name = get_the_title();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;</p>
<p>$score = intval($game[$p] ?? 0);<br />if ($score &gt; $highest_score) {<br />$highest_score = $score;<br />$holder = [<br />&#8216;player&#8217; =&gt; $name,<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; $tournament_name,<br />&#8216;tournament_id&#8217; =&gt; $tournament_id,<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if ($highest_score === 0) return &#8216;No 1v1 game scores found yet.&#8217;;</p>
<p>$tournament_link = get_permalink($holder[&#8216;tournament_id&#8217;]);</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />max-width:420px;<br />margin:30px auto;<br />padding:20px;<br />border-radius:14px;<br />background:linear-gradient(135deg,#e8f5e9,#d4edda);<br />border:1px solid #4CAF50;<br />text-align:center;<br />box-shadow:0 6px 14px rgba(0,0,0,0.12);<br />font-family:inherit;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:42px; line-height:1; margin-bottom:12px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;<br />&lt;div style=&#8221;font-size:20px; font-weight:bold; margin-bottom:18px;&#8221;&gt;<br />Current Top Score Holder<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:18px; font-weight:bold; margin-bottom:8px; border-bottom:1px solid #c8e6c9; padding-bottom:6px;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;player&#8217;]).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:16px; margin-bottom:6px; border-bottom:1px solid #c8e6c9; padding-bottom:6px;&#8221;&gt;<br />Score: &lt;strong&gt;&#8217;.intval($holder[&#8216;score&#8217;]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; margin-bottom:4px;&#8221;&gt;<br />Game: &#8216;.$holder[&#8216;game&#8217;].&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; color:#555;&#8221;&gt;<br />Tournament:&lt;br&gt;<br />&lt;a href=&#8221;&#8216;.esc_url($tournament_link).'&#8221; style=&#8221;color:#4CAF50; text-decoration:none; font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;tournament&#8217;]).&#8217;<br />&lt;/a&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />HIGHEST SCORE HISTORY (1v1) &#8211; Styled<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_highest_1v1_history&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;1v1&#8217;],<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished 1v1 tournaments found.&#8217;;</p>
<p>$history = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$tournament_id = get_the_ID();<br />$tournament_name = get_the_title();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;<br />$score = intval($game[$p] ?? 0);<br />if ($score &gt; 0) {<br />$history[] = [<br />&#8216;player&#8217; =&gt; $name,<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; $tournament_name,<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($history)) return &#8216;No 1v1 game scores found yet.&#8217;;</p>
<p>// Sort by score descending<br />usort($history, function($a, $b) { return $b[&#8216;score&#8217;] &#8211; $a[&#8216;score&#8217;]; });</p>
<p>// Build table using the plugin&#8217;s class<br />$out = &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;<br />&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Score&lt;/th&gt;<br />&lt;th&gt;Tournament&lt;/th&gt;<br />&lt;th&gt;Game&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;<br />&lt;tbody&gt;&#8217;;</p>
<p>foreach ($history as $row) {<br />$out .= &#8216;&lt;tr&gt;<br />&lt;td&gt;&#8217;.esc_html($row[&#8216;player&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($row[&#8216;score&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($row[&#8216;tournament&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($row[&#8216;game&#8217;]).'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>add_shortcode(&#8216;tournament_1v1_lifetime_stats&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;1v1&#8217;],<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished 1v1 tournaments found.&#8217;;</p>
<p>$player_stats = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$tournament_id = get_the_ID();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;</p>
<p>if (!isset($player_stats[$name])) {<br />$player_stats[$name] = [<br />&#8216;total_games&#8217; =&gt; 0,<br />&#8216;total_points&#8217; =&gt; 0,<br />&#8216;total_wins&#8217; =&gt; 0,<br />&#8216;highest_points&#8217; =&gt; 0<br />];<br />}<br />}</p>
<p>// Loop through each game to calculate points, highest, and wins<br />foreach ($games as $game) {<br />$max_score = max($game); // highest score this game</p>
<p>foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;</p>
<p>$score = intval($game[$p] ?? 0);<br />$player_stats[$name][&#8216;total_games&#8217;]++;<br />$player_stats[$name][&#8216;total_points&#8217;] += $score;<br />if ($score &gt; $player_stats[$name][&#8216;highest_points&#8217;]) {<br />$player_stats[$name][&#8216;highest_points&#8217;] = $score;<br />}</p>
<p>// Count win if this player has the highest score this game<br />if ($score === $max_score) {<br />$player_stats[$name][&#8216;total_wins&#8217;]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($player_stats)) return &#8216;No 1v1 game stats found yet.&#8217;;</p>
<p>// Sort players by total points descending<br />uasort($player_stats, function($a, $b) {<br />return $b[&#8216;total_points&#8217;] &lt;=&gt; $a[&#8216;total_points&#8217;];<br />});</p>
<p>// Build table<br />$out = &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;<br />&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Total Games&lt;/th&gt;<br />&lt;th&gt;Total Points&lt;/th&gt;<br />&lt;th&gt;Total Wins&lt;/th&gt;<br />&lt;th&gt;Highest Points&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;<br />&lt;tbody&gt;&#8217;;</p>
<p>foreach ($player_stats as $name =&gt; $stats) {<br />$out .= &#8216;&lt;tr&gt;<br />&lt;td&gt;&#8217;.esc_html($name).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($stats[&#8216;total_games&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($stats[&#8216;total_points&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($stats[&#8216;total_wins&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($stats[&#8216;highest_points&#8217;]).'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CURRENT LOWEST SCORE HOLDER (1v1 ONLY) &#8211; Clickable Tournament<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_lowest_1v1_holder&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;1v1&#8217;],<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished 1v1 tournaments found.&#8217;;</p>
<p>$lowest_score = null;<br />$holder = [&#8216;player&#8217;=&gt;&#8221;,&#8217;score&#8217;=&gt;0,&#8217;tournament&#8217;=&gt;&#8221;,&#8217;game&#8217;=&gt;&#8221;,&#8217;tournament_id&#8217;=&gt;0];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$tournament_id = get_the_ID();<br />$tournament_name = get_the_title();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;<br />$score = intval($game[$p] ?? 0);<br />if (is_null($lowest_score) || $score &lt; $lowest_score) {<br />$lowest_score = $score;<br />$holder = [<br />&#8216;player&#8217; =&gt; $name,<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; $tournament_name,<br />&#8216;tournament_id&#8217; =&gt; $tournament_id,<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (is_null($lowest_score)) return &#8216;No 1v1 game scores found yet.&#8217;;</p>
<p>$tournament_link = get_permalink($holder[&#8216;tournament_id&#8217;]);</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />max-width:420px;<br />margin:30px auto;<br />padding:20px;<br />border-radius:14px;<br />background:linear-gradient(135deg,#fbe9e7,#f8d7da);<br />border:1px solid #f44336;<br />text-align:center;<br />box-shadow:0 6px 14px rgba(0,0,0,0.12);<br />font-family:inherit;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:42px; line-height:1; margin-bottom:12px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;<br />&lt;div style=&#8221;font-size:20px; font-weight:bold; margin-bottom:18px;&#8221;&gt;<br />Current Lowest Score Holder<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:18px; font-weight:bold; margin-bottom:8px; border-bottom:1px solid #f5c6cb; padding-bottom:6px;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;player&#8217;]).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:16px; margin-bottom:6px; border-bottom:1px solid #f5c6cb; padding-bottom:6px;&#8221;&gt;<br />Score: &lt;strong&gt;&#8217;.intval($holder[&#8216;score&#8217;]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; margin-bottom:4px;&#8221;&gt;<br />Game: &#8216;.$holder[&#8216;game&#8217;].&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; color:#555;&#8221;&gt;<br />Tournament:&lt;br&gt;<br />&lt;a href=&#8221;&#8216;.esc_url($tournament_link).'&#8221; style=&#8221;color:#f44336; text-decoration:none; font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;tournament&#8217;]).&#8217;<br />&lt;/a&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />SINGLE 1v1 LEADERBOARD<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_1v1_leaderboard&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;1v1&#8217;],<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished 1v1 tournaments found.&#8217;;</p>
<p>$stats = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$tournament_id = get_the_ID();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;</p>
<p>// Initialize player stats<br />if (!isset($stats[$name])) {<br />$stats[$name] = [<br />&#8216;player&#8217; =&gt; $name,<br />&#8216;games_played&#8217; =&gt; 0,<br />&#8216;total_points&#8217; =&gt; 0,<br />&#8216;total_wins&#8217; =&gt; 0,<br />];<br />}<br />}</p>
<p>foreach ($games as $g =&gt; $game) {<br />// Determine game winner<br />$max_score = -1;<br />$winner = &#8221;;<br />foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;<br />$score = intval($game[$p] ?? 0);<br />$stats[$name][&#8216;games_played&#8217;]++;<br />$stats[$name][&#8216;total_points&#8217;] += $score;</p>
<p>if ($score &gt; $max_score) {<br />$max_score = $score;<br />$winner = $name;<br />}<br />}<br />// Add win to winner<br />if ($winner) $stats[$winner][&#8216;total_wins&#8217;]++;<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($stats)) return &#8216;No 1v1 game stats found yet.&#8217;;</p>
<p>// Sort by total points descending<br />usort($stats, function($a, $b) {<br />return $b[&#8216;total_points&#8217;] &#8211; $a[&#8216;total_points&#8217;];<br />});</p>
<p>// Build table<br />$out = &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;<br />&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;Rank&lt;/th&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Total Games Played&lt;/th&gt;<br />&lt;th&gt;Total Wins&lt;/th&gt;<br />&lt;th&gt;Total Points&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;<br />&lt;tbody&gt;&#8217;;</p>
<p>$rank = 1;<br />foreach ($stats as $player) {<br />$out .= &#8216;&lt;tr&gt;<br />&lt;td&gt;&#8217;.esc_html($rank).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($player[&#8216;player&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($player[&#8216;games_played&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($player[&#8216;total_wins&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($player[&#8216;total_points&#8217;]).'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;<br />$rank++;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />HIGHEST LIFETIME SINGLE-GAME SCORE<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_highest_record_holder&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No score records found.&#8217;;</p>
<p>$record = [<br />&#8216;score&#8217; =&gt; 0,<br />&#8216;player&#8217; =&gt; &#8221;,<br />&#8216;tournament&#8217; =&gt; &#8221;,<br />&#8216;tournament_id&#8217; =&gt; 0,<br />&#8216;game&#8217; =&gt; &#8221;<br />];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$tournament_id = get_the_ID();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />foreach ($game as $p =&gt; $score) {<br />if (!isset($players[$p]) || !$players[$p]) continue;</p>
<p>$score = intval($score);</p>
<p>if ($score &gt; $record[&#8216;score&#8217;]) {<br />$record = [<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;player&#8217; =&gt; $players[$p],<br />&#8216;tournament&#8217; =&gt; get_the_title(),<br />&#8216;tournament_id&#8217; =&gt; $tournament_id,<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if ($record[&#8216;score&#8217;] === 0) return &#8216;No score records found.&#8217;;</p>
<p>$tournament_link = get_permalink($record[&#8216;tournament_id&#8217;]);</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />max-width:420px;<br />margin:30px auto;<br />padding:20px;<br />border-radius:14px;<br />background:linear-gradient(135deg,#e8f5e9,#d4edda);<br />border:1px solid #4CAF50;<br />text-align:center;<br />box-shadow:0 6px 14px rgba(0,0,0,0.12);<br />font-family:inherit;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:42px; line-height:1; margin-bottom:12px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:20px; font-weight:bold; margin-bottom:18px;&#8221;&gt;<br />Highest Score<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;<br />font-size:18px;<br />font-weight:bold;<br />margin-bottom:10px;<br />border-bottom:1px solid #c8e6c9;<br />padding-bottom:6px;<br />&#8220;&gt;<br />&#8216;.esc_html($record[&#8216;player&#8217;]).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:16px; margin-bottom:10px;&#8221;&gt;<br />Score: &lt;strong&gt;&#8217;.intval($record[&#8216;score&#8217;]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; margin-bottom:6px;&#8221;&gt;<br />&lt;strong&gt;Game:&lt;/strong&gt; &#8216;.$record[&#8216;game&#8217;].&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; color:#555;&#8221;&gt;<br />&lt;strong&gt;Tournament:&lt;/strong&gt;&lt;br&gt;<br />&lt;a href=&#8221;&#8216;.esc_url($tournament_link).'&#8221; style=&#8221;<br />color:#2e7d32;<br />font-weight:bold;<br />text-decoration:none;<br />&#8220;&gt;<br />&#8216;.esc_html($record[&#8216;tournament&#8217;]).&#8217;<br />&lt;/a&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />LOWEST LIFETIME SINGLE-GAME SCORE<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_lowest_record_holder&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No score records found.&#8217;;</p>
<p>$record = [<br />&#8216;score&#8217; =&gt; null,<br />&#8216;player&#8217; =&gt; &#8221;,<br />&#8216;tournament&#8217; =&gt; &#8221;,<br />&#8216;tournament_id&#8217;=&gt; 0,<br />&#8216;game&#8217; =&gt; &#8221;<br />];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$tournament_id = get_the_ID();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />foreach ($game as $p =&gt; $score) {<br />if (!isset($players[$p]) || !$players[$p]) continue;</p>
<p>$score = intval($score);</p>
<p>if ($record[&#8216;score&#8217;] === null || $score &lt; $record[&#8216;score&#8217;]) {<br />$record = [<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;player&#8217; =&gt; $players[$p],<br />&#8216;tournament&#8217; =&gt; get_the_title(),<br />&#8216;tournament_id&#8217; =&gt; $tournament_id,<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if ($record[&#8216;score&#8217;] === null) return &#8216;No score records found.&#8217;;</p>
<p>$tournament_link = get_permalink($record[&#8216;tournament_id&#8217;]);</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />max-width:420px;<br />margin:30px auto;<br />padding:20px;<br />border-radius:14px;<br />background:linear-gradient(135deg,#fdecea,#f8d7da);<br />border:1px solid #f44336;<br />text-align:center;<br />box-shadow:0 6px 14px rgba(0,0,0,0.12);<br />font-family:inherit;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:42px; line-height:1; margin-bottom:12px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f7e5.png" alt="🟥" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:20px; font-weight:bold; margin-bottom:18px;&#8221;&gt;<br />Lowest Score<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;<br />font-size:18px;<br />font-weight:bold;<br />margin-bottom:10px;<br />border-bottom:1px solid #f5b7b1;<br />padding-bottom:6px;<br />&#8220;&gt;<br />&#8216;.esc_html($record[&#8216;player&#8217;]).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:16px; margin-bottom:10px;&#8221;&gt;<br />Score: &lt;strong&gt;&#8217;.intval($record[&#8216;score&#8217;]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; margin-bottom:6px;&#8221;&gt;<br />&lt;strong&gt;Game:&lt;/strong&gt; &#8216;.$record[&#8216;game&#8217;].&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; color:#555;&#8221;&gt;<br />&lt;strong&gt;Tournament:&lt;/strong&gt;&lt;br&gt;<br />&lt;a href=&#8221;&#8216;.esc_url($tournament_link).'&#8221; style=&#8221;<br />color:#c62828;<br />font-weight:bold;<br />text-decoration:none;<br />&#8220;&gt;<br />&#8216;.esc_html($record[&#8216;tournament&#8217;]).&#8217;<br />&lt;/a&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />LIFETIME HIGHEST POINTS HOLDER (INDIVIDUAL ONLY)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_lifetime_points_holder_individual&#8217;, function () {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;,<br />&#8216;value&#8217; =&gt; &#8216;individual&#8217;<br />]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No individual lifetime scores found.&#8217;;</p>
<p>$totals = [];<br />$games_played = [];<br />$games_won = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $game) {</p>
<p>// Determine winner of this game<br />$max_score = max($game);<br />$winner_index = array_search($max_score, $game, true);</p>
<p>foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;</p>
<p>if (!isset($totals[$name])) {<br />$totals[$name] = 0;<br />$games_played[$name] = 0;<br />$games_won[$name] = 0;<br />}</p>
<p>$score = intval($game[$p] ?? 0);</p>
<p>// Lifetime points<br />$totals[$name] += $score;</p>
<p>// Games played<br />$games_played[$name]++;</p>
<p>// Games won<br />if ($p === $winner_index) {<br />$games_won[$name]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($totals)) return &#8216;No individual lifetime scores found.&#8217;;</p>
<p>// Top individual lifetime scorer<br />arsort($totals);<br />$top_player = key($totals);<br />$top_score = current($totals);</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />max-width:420px;<br />margin:30px auto;<br />padding:20px;<br />border-radius:14px;<br />background:linear-gradient(135deg,#e8f5e9,#d4edda);<br />border:1px solid #4CAF50;<br />text-align:center;<br />box-shadow:0 6px 14px rgba(0,0,0,0.12);<br />font-family:inherit;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:42px; line-height:1; margin-bottom:12px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:20px; font-weight:bold; margin-bottom:18px;&#8221;&gt;<br />Total Overall Points<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;<br />font-size:18px;<br />font-weight:bold;<br />margin-bottom:12px;<br />border-bottom:1px solid #c8e6c9;<br />padding-bottom:6px;<br />&#8220;&gt;<br />&#8216;.esc_html($top_player).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:16px; margin-bottom:6px;&#8221;&gt;<br />Total Points: &lt;strong&gt;&#8217;.intval($top_score).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; margin-bottom:4px;&#8221;&gt;<br />Games Played: &lt;strong&gt;&#8217;.intval($games_played[$top_player]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px;&#8221;&gt;<br />Games Won: &lt;strong&gt;&#8217;.intval($games_won[$top_player]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:12px; color:#000; margin-top:8px;&#8221;&gt;<br />&lt;b&gt;Singles Tournaments Only&lt;/b&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>/* Lifetime stats table (games played, points, wins, highest score) &#8211; admin colors applied */<br />add_shortcode(&#8216;tournament_lifetime_stats&#8217;, function() {<br />$query = new WP_Query([<br />&#8216;post_type&#8217;=&gt;&#8217;tournament&#8217;,<br />&#8216;posts_per_page&#8217;=&gt;-1,<br />&#8216;post_status&#8217;=&gt;&#8217;publish&#8217;<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No tournaments found.&#8217;;</p>
<p>$stats = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$players = get_post_meta(get_the_ID(),&#8217;ts_players&#8217;,true);<br />$games = get_post_meta(get_the_ID(),&#8217;ts_games&#8217;,true);<br />$mode = get_post_meta(get_the_ID(),&#8217;ts_mode&#8217;,true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>// Initialize stats<br />foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;<br />$stats[$name] = $stats[$name] ?? [<br />&#8216;games&#8217; =&gt; 0,<br />&#8216;points&#8217; =&gt; 0,<br />&#8216;wins&#8217; =&gt; 0,<br />&#8216;highest&#8217; =&gt; 0<br />];<br />}</p>
<p>if ($mode === &#8216;individual&#8217;) {<br />foreach ($games as $game) {<br />$max_score = max(array_map(&#8216;intval&#8217;,$game));<br />foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;<br />$score = intval($game[$p] ?? 0);<br />$stats[$name][&#8216;games&#8217;]++;<br />$stats[$name][&#8216;points&#8217;] += $score;<br />if ($score &gt; $stats[$name][&#8216;highest&#8217;]) $stats[$name][&#8216;highest&#8217;] = $score;<br />if ($score === $max_score &amp;&amp; $max_score &gt; 0) $stats[$name][&#8216;wins&#8217;]++;<br />}<br />}<br />} else {<br />// Teams<br />$teams = ts_get_teams($players);<br />foreach ($games as $game) {<br />$team_scores = [];<br />foreach ($teams as $team =&gt; $members) {<br />$team_scores[$team] = 0;<br />foreach ($members as $m) {<br />$score = intval($game[$m[&#8216;index&#8217;]] ?? 0);<br />$stats[$m[&#8216;name&#8217;]][&#8216;games&#8217;]++;<br />$stats[$m[&#8216;name&#8217;]][&#8216;points&#8217;] += $score;<br />if ($score &gt; $stats[$m[&#8216;name&#8217;]][&#8216;highest&#8217;]) $stats[$m[&#8216;name&#8217;]][&#8216;highest&#8217;] = $score;<br />$team_scores[$team] += $score;<br />}<br />}<br />$max_team = max($team_scores);<br />foreach ($teams as $team =&gt; $members) {<br />if ($team_scores[$team] === $max_team &amp;&amp; $max_team &gt; 0) {<br />foreach ($members as $m) $stats[$m[&#8216;name&#8217;]][&#8216;wins&#8217;]++;<br />}<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($stats)) return &#8216;No player stats found.&#8217;;</p>
<p>uasort($stats, fn($a,$b)=&gt;$b[&#8216;points&#8217;]-$a[&#8216;points&#8217;]);</p>
<p>// Build table</p>
<p>$out .= &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;</p>
<p>// Table header<br />$out .= &#8216;&lt;thead&gt;&lt;tr&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Total Games&lt;/th&gt;<br />&lt;th&gt;Total Points&lt;/th&gt;<br />&lt;th&gt;Total Wins&lt;/th&gt;<br />&lt;th&gt;Highest Points in a Game&lt;/th&gt;<br />&lt;/tr&gt;&lt;/thead&gt;&#8217;;</p>
<p>// Table body<br />$out .= &#8216;&lt;tbody&gt;&#8217;;<br />foreach ($stats as $player =&gt; $data) {<br />$out .= &#8216;&lt;tr&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.esc_html($player).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.intval($data[&#8216;games&#8217;]).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.intval($data[&#8216;points&#8217;]).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.intval($data[&#8216;wins&#8217;]).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.intval($data[&#8216;highest&#8217;]).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;<br />}<br />$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />LIFETIME HIGHEST POINTS HOLDER (ALL TOURNAMENTS)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_lifetime_points_holder&#8217;, function () {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No lifetime scores found.&#8217;;</p>
<p>$totals = [];<br />$games_played = [];<br />$games_won = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $game) {</p>
<p>// Find game winner (highest score in this game)<br />$max_score = max($game);<br />$winner_index = array_search($max_score, $game);</p>
<p>foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;</p>
<p>if (!isset($totals[$name])) {<br />$totals[$name] = 0;<br />$games_played[$name] = 0;<br />$games_won[$name] = 0;<br />}</p>
<p>$score = intval($game[$p] ?? 0);</p>
<p>// Total points<br />$totals[$name] += $score;</p>
<p>// Games played<br />$games_played[$name]++;</p>
<p>// Games won<br />if ($p === $winner_index) {<br />$games_won[$name]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($totals)) return &#8216;No lifetime scores found.&#8217;;</p>
<p>// Get top lifetime scorer<br />arsort($totals);<br />$top_player = key($totals);<br />$top_score = current($totals);</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />max-width:420px;<br />margin:30px auto;<br />padding:20px;<br />border-radius:14px;<br />background:linear-gradient(135deg,#e8f5e9,#d4edda);<br />border:1px solid #4CAF50;<br />text-align:center;<br />box-shadow:0 6px 14px rgba(0,0,0,0.12);<br />font-family:inherit;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:42px; line-height:1; margin-bottom:12px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:20px; font-weight:bold; margin-bottom:18px;&#8221;&gt;<br />Current Highest Points Holder<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;<br />font-size:18px;<br />font-weight:bold;<br />margin-bottom:12px;<br />border-bottom:1px solid #c8e6c9;<br />padding-bottom:6px;<br />&#8220;&gt;<br />&#8216;.esc_html($top_player).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:16px; margin-bottom:6px;&#8221;&gt;<br />Total Points: &lt;strong&gt;&#8217;.intval($top_score).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; margin-bottom:4px;&#8221;&gt;<br />Games Played: &lt;strong&gt;&#8217;.intval($games_played[$top_player]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px;&#8221;&gt;<br />Games Won: &lt;strong&gt;&#8217;.intval($games_won[$top_player]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:12px; color:#000; margin-top:8px;&#8221;&gt;<br />&lt;b&gt;Across All Tournaments&lt;/b&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />ALL GAMES TOP 5 HIGHEST SCORE HISTORY<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_all_games_top5_scores&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No tournaments found.&#8217;;</p>
<p>$history = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$tournament_id = get_the_ID();<br />$tournament_name = get_the_title();</p>
<p>$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />foreach ($game as $p =&gt; $score) {<br />if (!isset($players[$p]) || $players[$p] === &#8221;) continue;</p>
<p>$score = intval($score);<br />$player_name = $players[$p];</p>
<p>$history[] = [<br />&#8216;player&#8217; =&gt; $player_name,<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; $tournament_name,<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($history)) return &#8216;No game scores found.&#8217;;</p>
<p>// Sort descending by score<br />usort($history, fn($a,$b) =&gt; $b[&#8216;score&#8217;] &#8211; $a[&#8216;score&#8217;]);</p>
<p>// Keep only top 5<br />$history = array_slice($history, 0, 6);</p>
<p>// Build table</p>
<p>$out .= &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;</p>
<p>// HEADER<br />$out .= &#8216;&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;#&lt;/th&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Points&lt;/th&gt;<br />&lt;th&gt;Tournament&lt;/th&gt;<br />&lt;th&gt;Game&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;&#8217;;</p>
<p>// BODY<br />$out .= &#8216;&lt;tbody&gt;&#8217;;<br />foreach ($history as $i =&gt; $record) {<br />$class = ($i === 0) ? &#8216;winner&#8217; : &#8221;;<br />$out .= &#8216;&lt;tr class=&#8221;&#8216;.$class.'&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.($i + 1).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.esc_html($record[&#8216;player&#8217;]).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.intval($record[&#8216;score&#8217;]).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.esc_html($record[&#8216;tournament&#8217;]).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.esc_html($record[&#8216;game&#8217;]).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;<br />}<br />$out .= &#8216;&lt;/tbody&gt;&#8217;;</p>
<p>$out .= &#8216;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>add_filter(&#8216;the_content&#8217;, function ($content) {</p>
<p>// Only on single tournament posts (frontend)<br />if (!is_singular(&#8216;tournament&#8217;) || !in_the_loop() || !is_main_query()) {<br />return $content;<br />}</p>
<p>// Prevent duplicate output<br />if (has_shortcode($content, &#8216;tournament_game_durations_table&#8217;)) {<br />return $content;<br />}</p>
<p>// Append shortcode output<br />$content .= do_shortcode(&#8216;&#8216;);</p>
<p>return $content;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />AUTO-ADD SCORES + ADMIN TABLE TO ALL TOURNAMENT PAGES<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_filter(&#8216;the_content&#8217;, function ($content) {<br />// Only apply to single tournament pages in the main query<br />if (is_singular(&#8216;tournament&#8217;) &amp;&amp; in_the_loop() &amp;&amp; is_main_query() &amp;&amp; !is_admin()) {<br />// Append scores shortcode<br />$scores_html = do_shortcode(&#8216;No players found.&#8216;);<br />// Append admin-style table below scores<br />$table_html = do_shortcode(&#8216;&#8216;);</p>
<p>// Combine content<br />$content .= $scores_html . $table_html;<br />}</p>
<p>return $content;<br />});</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>add_shortcode(&#8216;tournament_lifetime_stats_1v1&#8217;, function() {<br />$query = new WP_Query([<br />&#8216;post_type&#8217;=&gt;&#8217;tournament&#8217;,<br />&#8216;posts_per_page&#8217;=&gt;-1,<br />&#8216;post_status&#8217;=&gt;&#8217;publish&#8217;,<br />&#8216;meta_query&#8217;=&gt;[<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;,<br />&#8216;value&#8217; =&gt; &#8216;1v1&#8217;<br />]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No 1v1 tournaments found.&#8217;;</p>
<p>$out = &#8216;&lt;h3&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 1v1 Game-by-Game Stats&lt;/h3&gt;&#8217;;</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$tournament_id = get_the_ID();<br />$tournament_name = get_the_title();<br />$players = get_post_meta($tournament_id,&#8217;ts_players&#8217;,true);<br />$games = get_post_meta($tournament_id,&#8217;ts_games&#8217;,true);</p>
<p>if(!is_array($players) || !is_array($games)) continue;</p>
<p>$players = array_values(array_filter($players));<br />if(count($players) !== 2) continue; // only 2 players</p>
<p>$totals = array_fill(0, count($players), 0);</p>
<p>$out .= &#8216;&lt;h4&gt;&#8217;.esc_html($tournament_name).'&lt;/h4&gt;&#8217;;<br />$out .= &#8216;&lt;table class=&#8221;tournament-table&#8221; style=&#8221;border-collapse:collapse;width:100%&#8221;&gt;&#8217;;</p>
<p>// Header row<br />$out .= &#8216;&lt;tr style=&#8221;background:#f1f1f1;&#8221;&gt;&lt;th&gt;Game&lt;/th&gt;&#8217;;<br />foreach($players as $player) {<br />$out .= &#8216;&lt;th&gt;&#8217;.esc_html($player).'&lt;/th&gt;&#8217;;<br />}<br />$out .= &#8216;&lt;/tr&gt;&#8217;;</p>
<p>// Game rows (neutral color)<br />foreach($games as $g_index =&gt; $game) {<br />$out .= &#8216;&lt;tr&gt;&#8217;; // &lt;&#8211; no inline background color</p>
<p>$out .= &#8216;&lt;td&gt;&#8217;.($g_index + 1).'&lt;/td&gt;&#8217;;</p>
<p>foreach($players as $p_index =&gt; $player_name) {<br />$score = intval($game[$p_index] ?? 0);<br />$totals[$p_index] += $score;<br />$out .= &#8216;&lt;td&gt;&#8217;.$score.'&lt;/td&gt;&#8217;;<br />}</p>
<p>$out .= &#8216;&lt;/tr&gt;&#8217;;<br />}</p>
<p>// Determine winner for totals row<br />$max_total = max($totals);<br />$winner_index = array_search($max_total, $totals);</p>
<p>// Totals row with winner highlighted<br />$out .= &#8216;&lt;tr style=&#8221;font-weight:bold; background:#f9f9f9;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;Total&lt;/td&gt;&#8217;;<br />foreach($totals as $p_index =&gt; $total) {<br />$highlight = ($p_index === $winner_index) ? &#8216; style=&#8221;background:#d4edda;&#8221;&#8216; : &#8221;;<br />$out .= &#8216;&lt;td&#8217;.$highlight.&#8217;&gt;&#8217;.$total.'&lt;/td&gt;&#8217;;<br />}<br />$out .= &#8216;&lt;/tr&gt;&#8217;;</p>
<p>$out .= &#8216;&lt;/table&gt;&lt;br&gt;&#8217;;<br />}</p>
<p>wp_reset_postdata();</p>
<p>return $out;<br />});</p>
<p>&nbsp;</p>
<p>function ts_remove_player_page() {<br />echo &#8216;&lt;div class=&#8221;wrap&#8221;&gt;&lt;h1&gt;Remove Player from Tournaments&lt;/h1&gt;&#8217;;</p>
<p>// Handle form submission<br />if (isset($_POST[&#8216;ts_remove_player_nonce&#8217;]) &amp;&amp; wp_verify_nonce($_POST[&#8216;ts_remove_player_nonce&#8217;], &#8216;ts_remove_player&#8217;)) {<br />$player_name_to_remove = sanitize_text_field($_POST[&#8216;player_name&#8217;]);</p>
<p>if ($player_name_to_remove) {<br />$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />]);</p>
<p>$removed_count = 0;</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$tournament_id = get_the_ID();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players)) continue;</p>
<p>foreach ($players as $i =&gt; $name) {<br />if ($name === $player_name_to_remove) {<br />unset($players[$i]);<br />if (is_array($games)) {<br />foreach ($games as &amp;$game) {<br />unset($game[$i]);<br />}<br />}<br />$removed_count++;<br />}<br />}</p>
<p>// Reindex arrays<br />$players = array_values($players);<br />$games = is_array($games) ? array_map(&#8216;array_values&#8217;, $games) : [];</p>
<p>update_post_meta($tournament_id, &#8216;ts_players&#8217;, $players);<br />update_post_meta($tournament_id, &#8216;ts_games&#8217;, $games);<br />}</p>
<p>wp_reset_postdata();</p>
<p>echo &#8216;&lt;div style=&#8221;padding:10px;background:#d4edda;border:1px solid #c3e6cb;margin-bottom:20px;&#8221;&gt;&#8217;;<br />echo &#8216;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Removed player &lt;strong&gt;&#8217;.esc_html($player_name_to_remove).'&lt;/strong&gt; from &#8216;.$removed_count.&#8217; tournaments.&#8217;;<br />echo &#8216;&lt;/div&gt;&#8217;;<br />} else {<br />echo &#8216;&lt;div style=&#8221;padding:10px;background:#f8d7da;border:1px solid #f5c6cb;margin-bottom:20px;&#8221;&gt;Please select a player.&lt;/div&gt;&#8217;;<br />}<br />}</p>
<p>// Collect all unique players from all tournaments<br />$all_players = [];<br />$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />]);<br />while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />if (is_array($players)) {<br />foreach ($players as $p) {<br />if ($p) $all_players[$p] = $p;<br />}<br />}<br />}<br />wp_reset_postdata();</p>
<p>if (empty($all_players)) {<br />echo &#8216;&lt;p&gt;No players found in tournaments.&lt;/p&gt;&lt;/div&gt;&#8217;;<br />return;<br />}</p>
<p>// Form with dropdown<br />echo &#8216;&lt;form method=&#8221;post&#8221;&gt;&#8217;;<br />echo wp_nonce_field(&#8216;ts_remove_player&#8217;, &#8216;ts_remove_player_nonce&#8217;, true, false);<br />echo &#8216;&lt;table class=&#8221;form-table&#8221;&gt;&lt;tr&gt;&#8217;;<br />echo &#8216;&lt;th&gt;&lt;label for=&#8221;player_name&#8221;&gt;Select Player&lt;/label&gt;&lt;/th&gt;&#8217;;<br />echo &#8216;&lt;td&gt;&lt;select name=&#8221;player_name&#8221; id=&#8221;player_name&#8221;&gt;&#8217;;<br />echo &#8216;&lt;option value=&#8221;&#8221;&gt;&#8211; Select a player &#8211;&lt;/option&gt;&#8217;;<br />foreach ($all_players as $player) {<br />echo &#8216;&lt;option value=&#8221;&#8216;.esc_attr($player).'&#8221;&gt;&#8217;.esc_html($player).'&lt;/option&gt;&#8217;;<br />}<br />echo &#8216;&lt;/select&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&#8217;;<br />echo &#8216;&lt;p&gt;&lt;input type=&#8221;submit&#8221; class=&#8221;button button-primary&#8221; value=&#8221;Remove Player&#8221;&gt;&lt;/p&gt;&#8217;;<br />echo &#8216;&lt;/form&gt;&lt;/div&gt;&#8217;;<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />1v1 Leaderboard<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_wins_1v1&#8217;, function() {<br />$query = new WP_Query([<br />&#8216;post_type&#8217;=&gt;&#8217;tournament&#8217;,<br />&#8216;posts_per_page&#8217;=&gt;-1,<br />&#8216;post_status&#8217;=&gt;&#8217;publish&#8217;,<br />&#8216;meta_query&#8217;=&gt;[<br />[&#8216;key&#8217;=&gt;&#8217;ts_mode&#8217;,&#8217;value&#8217;=&gt;&#8217;1v1&#8242;]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No 1v1 tournaments found.&#8217;;</p>
<p>$stats = [];<br />while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$players = get_post_meta(get_the_ID(),&#8217;ts_players&#8217;,true);<br />$games = get_post_meta(get_the_ID(),&#8217;ts_games&#8217;,true);<br />if(!is_array($players) || !is_array($games)) continue;</p>
<p>foreach($players as $i=&gt;$name){<br />if(!$name) continue;<br />if(!isset($stats[$name])) $stats[$name] = [&#8216;wins&#8217;=&gt;0,&#8217;points&#8217;=&gt;0];<br />foreach($games as $game){<br />$score = intval($game[$i] ?? 0);<br />$stats[$name][&#8216;points&#8217;] += $score;<br />}<br />}</p>
<p>// Count wins per tournament<br />foreach($games as $game){<br />$max_score = max($game);<br />foreach($players as $i=&gt;$name){<br />if(!$name) continue;<br />if(intval($game[$i] ?? 0) === $max_score &amp;&amp; $max_score&gt;0) $stats[$name][&#8216;wins&#8217;]++;<br />}<br />}<br />}<br />wp_reset_postdata();</p>
<p>if(empty($stats)) return &#8216;No stats found.&#8217;;<br />uasort($stats, fn($a,$b)=&gt;$b[&#8216;points&#8217;]-$a[&#8216;points&#8217;]); // sort by total points</p>
<p>$out = &#8216;&lt;h3&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 1v1 Leaderboard&lt;/h3&gt;&lt;table class=&#8221;tournament-table&#8221;&gt;&lt;tr&gt;&lt;th&gt;Rank&lt;/th&gt;&lt;th&gt;Player&lt;/th&gt;&lt;th&gt;Wins&lt;/th&gt;&lt;th&gt;Total Points&lt;/th&gt;&lt;/tr&gt;&#8217;;<br />$rank = 1;<br />foreach($stats as $player=&gt;$data){<br />$out .= &#8216;&lt;tr&gt;&lt;td&gt;&#8217;.$rank.'&lt;/td&gt;&lt;td&gt;&#8217;.esc_html($player).'&lt;/td&gt;&lt;td&gt;&#8217;.$data[&#8216;wins&#8217;].'&lt;/td&gt;&lt;td&gt;&#8217;.$data[&#8216;points&#8217;].'&lt;/td&gt;&lt;/tr&gt;&#8217;;<br />$rank++;<br />}<br />$out .= &#8216;&lt;/table&gt;&#8217;;<br />return $out;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />Individual Leaderboard (Admin Colors Applied)<br />&#8211; Total Wins, Total Points<br />&#8211; Highest Points in Single Game<br />&#8211; Total Games Played<br />&#8211; Win/Loss Percentage<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_wins_individual&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217;=&gt;&#8217;ts_mode&#8217;,&#8217;value&#8217;=&gt;&#8217;individual&#8217;]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No Individual tournaments found.&#8217;;</p>
<p>$stats = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$players = get_post_meta(get_the_ID(),&#8217;ts_players&#8217;,true);<br />$games = get_post_meta(get_the_ID(),&#8217;ts_games&#8217;,true);</p>
<p>if(!is_array($players) || !is_array($games)) continue;</p>
<p>// Initialize stats<br />foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;<br />$stats[$name] = $stats[$name] ?? [<br />&#8216;wins&#8217; =&gt; 0,<br />&#8216;points&#8217; =&gt; 0,<br />&#8216;highest&#8217; =&gt; 0,<br />&#8216;games&#8217; =&gt; 0<br />];<br />}</p>
<p>// Add points, highest, games played<br />foreach ($games as $game) {<br />foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;<br />$score = intval($game[$i] ?? 0);<br />$stats[$name][&#8216;points&#8217;] += $score;<br />$stats[$name][&#8216;games&#8217;]++; // count this game<br />if ($score &gt; $stats[$name][&#8216;highest&#8217;]) {<br />$stats[$name][&#8216;highest&#8217;] = $score;<br />}<br />}<br />}</p>
<p>// Count wins<br />foreach ($games as $game) {<br />$max_score = max(array_map(&#8216;intval&#8217;, $game));<br />foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;<br />if (intval($game[$i] ?? 0) === $max_score &amp;&amp; $max_score &gt; 0) {<br />$stats[$name][&#8216;wins&#8217;]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($stats)) return &#8216;No stats found.&#8217;;</p>
<p>// Sort players by total points descending<br />uasort($stats, fn($a,$b) =&gt; $b[&#8216;points&#8217;] &lt;=&gt; $a[&#8216;points&#8217;]);</p>
<p>// Build table</p>
<p>$out .= &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;</p>
<p>// Header<br />$out .= &#8216;&lt;thead&gt;&lt;tr&gt;<br />&lt;th&gt;Rank&lt;/th&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Total Games&lt;/th&gt;<br />&lt;th&gt;Total Wins&lt;/th&gt;<br />&lt;th&gt;Win %&lt;/th&gt;<br />&lt;th&gt;Total Points&lt;/th&gt;<br />&lt;th&gt;Highest Points&lt;/th&gt;<br />&lt;/tr&gt;&lt;/thead&gt;&#8217;;</p>
<p>// Body<br />$out .= &#8216;&lt;tbody&gt;&#8217;;<br />$rank = 1;<br />foreach ($stats as $player =&gt; $data) {<br />$win_percent = $data[&#8216;games&#8217;] &gt; 0 ? round(($data[&#8216;wins&#8217;] / $data[&#8216;games&#8217;]) * 100, 1) : 0;<br />$class = ($rank === 1) ? &#8216;winner&#8217; : &#8221;;<br />$out .= &#8216;&lt;tr class=&#8221;&#8216;.$class.'&#8221;&gt;<br />&lt;td&gt;&#8217;.$rank.'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($player).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;games&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;wins&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.$win_percent.&#8217;%&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;points&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;highest&#8217;]).'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;<br />$rank++;<br />}<br />$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />Team Leaderboard (Admin Colors Applied)<br />&#8211; Total Wins, Total Points<br />&#8211; Highest Points in Single Game<br />&#8211; Total Games Played<br />&#8211; Win/Loss Percentage<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_wins_team&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;teams&#8217;]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No Team tournaments found.&#8217;;</p>
<p>$stats = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>// In team mode, ts_players holds team names<br />$teams = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($teams) || !is_array($games)) continue;</p>
<p>// Initialize stats<br />foreach ($teams as $i =&gt; $team_name) {<br />if (!$team_name) continue;<br />$stats[$team_name] = $stats[$team_name] ?? [<br />&#8216;wins&#8217; =&gt; 0,<br />&#8216;points&#8217; =&gt; 0,<br />&#8216;highest&#8217; =&gt; 0,<br />&#8216;games&#8217; =&gt; 0<br />];<br />}</p>
<p>// Add points, highest, games played<br />foreach ($games as $game) {<br />foreach ($teams as $i =&gt; $team_name) {<br />if (!$team_name) continue;</p>
<p>$score = intval($game[$i] ?? 0);<br />$stats[$team_name][&#8216;points&#8217;] += $score;<br />$stats[$team_name][&#8216;games&#8217;]++;</p>
<p>if ($score &gt; $stats[$team_name][&#8216;highest&#8217;]) {<br />$stats[$team_name][&#8216;highest&#8217;] = $score;<br />}<br />}<br />}</p>
<p>// Count wins<br />foreach ($games as $game) {<br />$max_score = max(array_map(&#8216;intval&#8217;, $game));</p>
<p>foreach ($teams as $i =&gt; $team_name) {<br />if (!$team_name) continue;</p>
<p>if (intval($game[$i] ?? 0) === $max_score &amp;&amp; $max_score &gt; 0) {<br />$stats[$team_name][&#8216;wins&#8217;]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($stats)) return &#8216;No stats found.&#8217;;</p>
<p>// Sort teams by total points descending<br />uasort($stats, fn($a, $b) =&gt; $b[&#8216;points&#8217;] &lt;=&gt; $a[&#8216;points&#8217;]);</p>
<p>// Build table<br />$out = &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;</p>
<p>// Header<br />$out .= &#8216;&lt;thead&gt;&lt;tr&gt;<br />&lt;th&gt;Rank&lt;/th&gt;<br />&lt;th&gt;Team&lt;/th&gt;<br />&lt;th&gt;Total Games&lt;/th&gt;<br />&lt;th&gt;Total Wins&lt;/th&gt;<br />&lt;th&gt;Win %&lt;/th&gt;<br />&lt;th&gt;Total Points&lt;/th&gt;<br />&lt;th&gt;Highest Points&lt;/th&gt;<br />&lt;/tr&gt;&lt;/thead&gt;&#8217;;</p>
<p>// Body<br />$out .= &#8216;&lt;tbody&gt;&#8217;;<br />$rank = 1;</p>
<p>foreach ($stats as $team =&gt; $data) {<br />$win_percent = $data[&#8216;games&#8217;] &gt; 0<br />? round(($data[&#8216;wins&#8217;] / $data[&#8216;games&#8217;]) * 100, 1)<br />: 0;</p>
<p>$class = ($rank === 1) ? &#8216;winner&#8217; : &#8221;;</p>
<p>$out .= &#8216;&lt;tr class=&#8221;&#8216;.$class.'&#8221;&gt;<br />&lt;td&gt;&#8217;.$rank.'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($team).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;games&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;wins&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.$win_percent.&#8217;%&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;points&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;highest&#8217;]).'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;</p>
<p>$rank++;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CURRENT HIGHEST SCORE HOLDER (Individual Mode)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_highest_individual&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;,<br />&#8216;value&#8217; =&gt; &#8216;individual&#8217;<br />],<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;,<br />&#8216;value&#8217; =&gt; 1<br />]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) {<br />return &#8216;No finished individual tournaments found.&#8217;;<br />}</p>
<p>$highest_score = 0;<br />$holder = [<br />&#8216;player&#8217; =&gt; &#8221;,<br />&#8216;score&#8217; =&gt; 0,<br />&#8216;tournament&#8217; =&gt; &#8221;,<br />&#8216;tournament_url&#8217; =&gt; &#8221;,<br />&#8216;game&#8217; =&gt; 0<br />];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$tournament_id = get_the_ID();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;</p>
<p>$score = intval($game[$p] ?? 0);</p>
<p>if ($score &gt; $highest_score) {<br />$highest_score = $score;<br />$holder = [<br />&#8216;player&#8217; =&gt; $name,<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; get_the_title(),<br />&#8216;tournament_url&#8217; =&gt; get_permalink(),<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if ($highest_score === 0) {<br />return &#8216;No individual game scores found yet.&#8217;;<br />}</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />border:1px solid #4CAF50;<br />padding:14px;<br />background:#d4edda;<br />border-radius:10px;<br />max-width:420px;<br />margin:20px auto;<br />text-align:center;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:36px; margin-bottom:10px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;strong&gt;Highest Score&lt;/strong&gt;&lt;br&gt;&lt;br&gt;</p>
<p>&lt;div style=&#8221;font-size:18px; font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;player&#8217;]).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Score: &lt;strong&gt;&#8217;.intval($holder[&#8216;score&#8217;]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Game: &#8216;.$holder[&#8216;game&#8217;].&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:8px;&#8221;&gt;<br />Tournament:&lt;br&gt;<br />&lt;a href=&#8221;&#8216;.esc_url($holder[&#8216;tournament_url&#8217;]).'&#8221; style=&#8221;font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;tournament&#8217;]).&#8217;<br />&lt;/a&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CURRENT LOWEST SCORE HOLDER (Individual Mode)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_lowest_individual&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;,<br />&#8216;value&#8217; =&gt; &#8216;individual&#8217;<br />],<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;,<br />&#8216;value&#8217; =&gt; 1<br />]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) {<br />return &#8216;No finished individual tournaments found.&#8217;;<br />}</p>
<p>$lowest_score = PHP_INT_MAX;<br />$holder = [<br />&#8216;player&#8217; =&gt; &#8221;,<br />&#8216;score&#8217; =&gt; 0,<br />&#8216;tournament&#8217; =&gt; &#8221;,<br />&#8216;tournament_url&#8217; =&gt; &#8221;,<br />&#8216;game&#8217; =&gt; 0<br />];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$tournament_id = get_the_ID();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;</p>
<p>$score = intval($game[$p] ?? 0);</p>
<p>if ($score &lt; $lowest_score) {<br />$lowest_score = $score;<br />$holder = [<br />&#8216;player&#8217; =&gt; $name,<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; get_the_title(),<br />&#8216;tournament_url&#8217; =&gt; get_permalink(),<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if ($lowest_score === PHP_INT_MAX) {<br />return &#8216;No individual game scores found yet.&#8217;;<br />}</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />border:1px solid #f44336;<br />padding:14px;<br />background:#fdecea;<br />border-radius:10px;<br />max-width:420px;<br />margin:20px auto;<br />text-align:center;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:36px; margin-bottom:10px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f7e5.png" alt="🟥" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;strong&gt;Lowest Score&lt;/strong&gt;&lt;br&gt;&lt;br&gt;</p>
<p>&lt;div style=&#8221;font-size:18px; font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;player&#8217;]).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Score: &lt;strong&gt;&#8217;.intval($holder[&#8216;score&#8217;]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Game: &#8216;.$holder[&#8216;game&#8217;].&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:8px;&#8221;&gt;<br />Tournament:&lt;br&gt;<br />&lt;a href=&#8221;&#8216;.esc_url($holder[&#8216;tournament_url&#8217;]).'&#8221; style=&#8221;font-weight:bold; color:#c62828;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;tournament&#8217;]).&#8217;<br />&lt;/a&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />TOP 5 HIGHEST SCORES (ALL INDIVIDUAL GAMES)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_individual_top5_scores&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;individual&#8217;],<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) {<br />return &#8216;No finished individual tournaments found.&#8217;;<br />}</p>
<p>$all_scores = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$tournament_id = get_the_ID();<br />$tournament_name = get_the_title();<br />$tournament_link = get_permalink($tournament_id);<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />foreach ($players as $p =&gt; $player_name) {<br />if (!$player_name) continue;</p>
<p>$score = intval($game[$p] ?? 0);</p>
<p>// Collect every single game score<br />$all_scores[] = [<br />&#8216;player&#8217; =&gt; $player_name,<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; $tournament_name,<br />&#8216;link&#8217; =&gt; $tournament_link,<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($all_scores)) {<br />return &#8216;No scores found.&#8217;;<br />}</p>
<p>// Sort by score DESC<br />usort($all_scores, fn($a, $b) =&gt; $b[&#8216;score&#8217;] &lt;=&gt; $a[&#8216;score&#8217;]);</p>
<p>// Keep only top 5<br />$top_scores = array_slice($all_scores, 0, 5);</p>
<p>// Output table<br />$out = &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;Rank&lt;/th&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Score&lt;/th&gt;<br />&lt;th&gt;Tournament&lt;/th&gt;<br />&lt;th&gt;Game&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;<br />&lt;tbody&gt;&#8217;;</p>
<p>$rank = 1;<br />foreach ($top_scores as $row) {<br />$class = ($rank === 1) ? &#8216;winner&#8217; : &#8221;;</p>
<p>$out .= &#8216;&lt;tr class=&#8221;&#8216;.$class.'&#8221;&gt;<br />&lt;td&gt;&#8217;.$rank.($class ? &#8216; <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217; : &#8221;).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($row[&#8216;player&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.$row[&#8216;score&#8217;].'&lt;/td&gt;<br />&lt;td&gt;<br />&lt;a href=&#8221;&#8216;.esc_url($row[&#8216;link&#8217;]).'&#8221; class=&#8221;tournament-link&#8221;&gt;<br />&#8216;.esc_html($row[&#8216;tournament&#8217;]).&#8217;<br />&lt;/a&gt;<br />&lt;/td&gt;<br />&lt;td&gt;&#8217;.$row[&#8216;game&#8217;].'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;</p>
<p>$rank++;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />INDIVIDUAL LIFETIME STATS<br />(Correct points and wins)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_individual_lifetime_stats&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217;=&gt;&#8217;ts_mode&#8217;,&#8217;value&#8217;=&gt;&#8217;individual&#8217;],<br />[&#8216;key&#8217;=&gt;&#8217;ts_finished&#8217;,&#8217;value&#8217;=&gt;1]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished individual tournaments found.&#8217;;</p>
<p>$stats = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$players = get_post_meta(get_the_ID(),&#8217;ts_players&#8217;,true);<br />$games = get_post_meta(get_the_ID(),&#8217;ts_games&#8217;,true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>// Initialize stats per player<br />foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;<br />$stats[$name] = $stats[$name] ?? [<br />&#8216;games&#8217; =&gt; 0,<br />&#8216;wins&#8217; =&gt; 0,<br />&#8216;points&#8217; =&gt; 0,<br />&#8216;high&#8217; =&gt; 0<br />];<br />}</p>
<p>// Count points and track highest per player<br />foreach ($games as $game) {<br />$max_score = max(array_map(&#8216;intval&#8217;, $game)); // highest score in this game</p>
<p>foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;</p>
<p>$score = intval($game[$i] ?? 0);</p>
<p>$stats[$name][&#8216;games&#8217;]++;<br />$stats[$name][&#8216;points&#8217;] += $score;<br />if ($score &gt; $stats[$name][&#8216;high&#8217;]) {<br />$stats[$name][&#8216;high&#8217;] = $score;<br />}</p>
<p>// Count wins<br />if ($score === $max_score &amp;&amp; $max_score &gt; 0) {<br />$stats[$name][&#8216;wins&#8217;]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($stats)) return &#8216;No individual stats found yet.&#8217;;</p>
<p>// Sort by total points descending<br />uasort($stats, fn($a,$b) =&gt; $b[&#8216;points&#8217;] &lt;=&gt; $a[&#8216;points&#8217;]);</p>
<p>// Build table<br />$out = &#8216;&lt;h3&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Individual Lifetime Stats&lt;/h3&gt;&#8217;;<br />$out .= &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;<br />&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;Rank&lt;/th&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Total Games&lt;/th&gt;<br />&lt;th&gt;Total Wins&lt;/th&gt;<br />&lt;th&gt;Total Points&lt;/th&gt;<br />&lt;th&gt;Highest Points&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;<br />&lt;tbody&gt;&#8217;;</p>
<p>$rank = 1;<br />foreach ($stats as $player =&gt; $data) {<br />$out .= &#8216;&lt;tr&#8217;.($rank===1?&#8217; class=&#8221;winner&#8221;&#8216;:&#8221;).&#8217;&gt;<br />&lt;td&gt;&#8217;.$rank.'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($player).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;games&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;wins&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;points&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;high&#8217;]).'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;<br />$rank++;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CURRENT HIGHEST SCORE HOLDER (Team Mode)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_highest_team&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;,<br />&#8216;value&#8217; =&gt; &#8216;teams&#8217;<br />],<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;,<br />&#8216;value&#8217; =&gt; 1<br />]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) {<br />return &#8216;No finished team tournaments found.&#8217;;<br />}</p>
<p>$highest_score = 0;<br />$holder = [<br />&#8216;team&#8217; =&gt; &#8221;,<br />&#8216;score&#8217; =&gt; 0,<br />&#8216;tournament&#8217; =&gt; &#8221;,<br />&#8216;tournament_url&#8217; =&gt; &#8221;,<br />&#8216;game&#8217; =&gt; 0<br />];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$tournament_id = get_the_ID();<br />$teams = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true); // team names<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($teams) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />foreach ($teams as $t =&gt; $team_name) {<br />if (!$team_name) continue;</p>
<p>$score = intval($game[$t] ?? 0);</p>
<p>if ($score &gt; $highest_score) {<br />$highest_score = $score;<br />$holder = [<br />&#8216;team&#8217; =&gt; $team_name,<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; get_the_title(),<br />&#8216;tournament_url&#8217; =&gt; get_permalink(),<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if ($highest_score === 0) {<br />return &#8216;No team game scores found yet.&#8217;;<br />}</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />border:1px solid #4CAF50;<br />padding:14px;<br />background:#d4edda;<br />border-radius:10px;<br />max-width:420px;<br />margin:20px auto;<br />text-align:center;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:36px; margin-bottom:10px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;strong&gt;Highest Team Score&lt;/strong&gt;&lt;br&gt;&lt;br&gt;</p>
<p>&lt;div style=&#8221;font-size:18px; font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;team&#8217;]).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Score: &lt;strong&gt;&#8217;.intval($holder[&#8216;score&#8217;]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Game: &#8216;.$holder[&#8216;game&#8217;].&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:8px;&#8221;&gt;<br />Tournament:&lt;br&gt;<br />&lt;a href=&#8221;&#8216;.esc_url($holder[&#8216;tournament_url&#8217;]).'&#8221; style=&#8221;font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;tournament&#8217;]).&#8217;<br />&lt;/a&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CURRENT LOWEST SCORE HOLDER (Team Mode)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_lowest_team&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;,<br />&#8216;value&#8217; =&gt; &#8216;teams&#8217;<br />],<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;,<br />&#8216;value&#8217; =&gt; 1<br />]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) {<br />return &#8216;No finished team tournaments found.&#8217;;<br />}</p>
<p>$lowest_score = PHP_INT_MAX;<br />$holder = [<br />&#8216;team&#8217; =&gt; &#8221;,<br />&#8216;score&#8217; =&gt; 0,<br />&#8216;tournament&#8217; =&gt; &#8221;,<br />&#8216;tournament_url&#8217; =&gt; &#8221;,<br />&#8216;game&#8217; =&gt; 0<br />];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$tournament_id = get_the_ID();<br />$teams = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($teams) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />foreach ($teams as $t =&gt; $team_name) {<br />if (!$team_name) continue;</p>
<p>$score = intval($game[$t] ?? 0);</p>
<p>if ($score &lt; $lowest_score) {<br />$lowest_score = $score;<br />$holder = [<br />&#8216;team&#8217; =&gt; $team_name,<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; get_the_title(),<br />&#8216;tournament_url&#8217; =&gt; get_permalink(),<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if ($lowest_score === PHP_INT_MAX) {<br />return &#8216;No team game scores found yet.&#8217;;<br />}</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />border:1px solid #f44336;<br />padding:14px;<br />background:#f8d7da;<br />border-radius:10px;<br />max-width:420px;<br />margin:20px auto;<br />text-align:center;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:36px; margin-bottom:10px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f976.png" alt="🥶" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;strong&gt;Lowest Team Score&lt;/strong&gt;&lt;br&gt;&lt;br&gt;</p>
<p>&lt;div style=&#8221;font-size:18px; font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;team&#8217;]).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Score: &lt;strong&gt;&#8217;.intval($holder[&#8216;score&#8217;]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Game: &#8216;.$holder[&#8216;game&#8217;].&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:8px;&#8221;&gt;<br />Tournament:&lt;br&gt;<br />&lt;a href=&#8221;&#8216;.esc_url($holder[&#8216;tournament_url&#8217;]).'&#8221; style=&#8221;font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;tournament&#8217;]).&#8217;<br />&lt;/a&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />TEAMS HIGHEST POINT HISTORY (with links)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_teams_highest_history&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;teams&#8217;],<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished team tournaments found.&#8217;;</p>
<p>$highest_scores = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$tournament_id = get_the_ID();<br />$tournament_name = get_the_title();<br />$tournament_link = get_permalink($tournament_id); // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> link to tournament page<br />$teams = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true); // in teams mode, ts_players stores team names<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($teams) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />$max_score = 0;<br />$winner = &#8221;;<br />foreach ($teams as $t =&gt; $team_name) {<br />if (!$team_name) continue;<br />$score = intval($game[$t] ?? 0);<br />if ($score &gt; $max_score) {<br />$max_score = $score;<br />$winner = $team_name;<br />}<br />}<br />if ($max_score &gt; 0) {<br />$highest_scores[] = [<br />&#8216;team&#8217; =&gt; $winner,<br />&#8216;score&#8217; =&gt; $max_score,<br />&#8216;tournament&#8217; =&gt; $tournament_name,<br />&#8216;tournament_link&#8217; =&gt; $tournament_link, // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> store link<br />&#8216;game&#8217; =&gt; $g + 1<br />];<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($highest_scores)) return &#8216;No high score history found yet.&#8217;;</p>
<p>// Sort descending by score<br />usort($highest_scores, function($a, $b) {<br />return $b[&#8216;score&#8217;] &#8211; $a[&#8216;score&#8217;];<br />});</p>
<p>// Build table<br />$out = &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;<br />&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;Tournament&lt;/th&gt;<br />&lt;th&gt;Game&lt;/th&gt;<br />&lt;th&gt;Team&lt;/th&gt;<br />&lt;th&gt;Score&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;<br />&lt;tbody&gt;&#8217;;</p>
<p>foreach ($highest_scores as $row) {<br />$out .= &#8216;&lt;tr&gt;<br />&lt;td&gt;&lt;a href=&#8221;&#8216;.esc_url($row[&#8216;tournament_link&#8217;]).'&#8221;&gt;&#8217;.esc_html($row[&#8216;tournament&#8217;]).'&lt;/a&gt;&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($row[&#8216;game&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($row[&#8216;team&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($row[&#8216;score&#8217;]).'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />LIFETIME STATS FOR ALL MODES<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_lifetime_stats_all&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished tournaments found.&#8217;;</p>
<p>$stats = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$mode = get_post_meta(get_the_ID(), &#8216;ts_mode&#8217;, true);<br />$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);<br />$winners = get_post_meta(get_the_ID(), &#8216;ts_winner&#8217;, true); // for teams</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>// 1v1 &amp; Individual logic<br />if ($mode === &#8216;1v1&#8217; || $mode === &#8216;individual&#8217;) {<br />foreach ($players as $i =&gt; $player_name) {<br />if (!$player_name) continue;</p>
<p>if (!isset($stats[$player_name])) {<br />$stats[$player_name] = [&#8216;games&#8217;=&gt;0,&#8217;wins&#8217;=&gt;0,&#8217;points&#8217;=&gt;0,&#8217;high&#8217;=&gt;0];<br />}</p>
<p>foreach ($games as $game) {<br />$score = intval($game[$i] ?? 0);<br />$stats[$player_name][&#8216;games&#8217;]++;<br />$stats[$player_name][&#8216;points&#8217;] += $score;<br />if ($score &gt; $stats[$player_name][&#8216;high&#8217;]) $stats[$player_name][&#8216;high&#8217;] = $score;<br />}</p>
<p>// Count wins<br />foreach ($games as $game) {<br />$max_score = max($game);<br />if (intval($game[$i] ?? 0) === $max_score &amp;&amp; $max_score &gt; 0) {<br />$stats[$player_name][&#8216;wins&#8217;]++;<br />}<br />}<br />}<br />}</p>
<p>// Teams logic<br />if ($mode === &#8216;teams&#8217;) {<br />$teams = [];<br />foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;<br />$teams[($i+1)%2===1?&#8217;A&#8217;:&#8217;B&#8217;][] = $name;<br />}</p>
<p>foreach ($games as $game) {<br />$team_scores = [];<br />foreach ($teams as $team_name =&gt; $members) {<br />$score = 0;<br />foreach ($members as $m) {<br />$idx = array_search($m, $players);<br />$score += intval($game[$idx] ?? 0);<br />if (!isset($stats[$m])) $stats[$m] = [&#8216;games&#8217;=&gt;0,&#8217;wins&#8217;=&gt;0,&#8217;points&#8217;=&gt;0,&#8217;high&#8217;=&gt;0];<br />$stats[$m][&#8216;games&#8217;]++;<br />$stats[$m][&#8216;points&#8217;] += intval($game[$idx] ?? 0);<br />if (intval($game[$idx] ?? 0) &gt; $stats[$m][&#8216;high&#8217;]) $stats[$m][&#8216;high&#8217;] = intval($game[$idx] ?? 0);<br />}<br />$team_scores[$team_name] = $score;<br />}<br />$max_score = max($team_scores);<br />foreach ($teams as $team_name =&gt; $members) {<br />if ($team_scores[$team_name] === $max_score &amp;&amp; $max_score&gt;0) {<br />foreach ($members as $m) $stats[$m][&#8216;wins&#8217;]++;<br />}<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($stats)) return &#8216;No stats found yet.&#8217;;</p>
<p>uasort($stats, fn($a,$b)=&gt;$b[&#8216;points&#8217;]-$a[&#8216;points&#8217;]);</p>
<p>$out = &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;<br />&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;Rank&lt;/th&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Total Games&lt;/th&gt;<br />&lt;th&gt;Total Wins&lt;/th&gt;<br />&lt;th&gt;Total Points&lt;/th&gt;<br />&lt;th&gt;Highest Points&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;<br />&lt;tbody&gt;&#8217;;</p>
<p>$rank = 1;<br />foreach ($stats as $player =&gt; $data) {<br />$out .= &#8216;&lt;tr&gt;<br />&lt;td&gt;&#8217;.$rank.'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($player).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;games&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;wins&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;points&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;high&#8217;]).'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;<br />$rank++;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />HIGHEST SCORE HISTORY (ALL TOURNAMENTS) – Top Row Highlighted<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_highest_score_history_all&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished tournaments found.&#8217;;</p>
<p>$highest_scores = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$tournament_name = get_the_title();<br />$mode = get_post_meta(get_the_ID(), &#8216;ts_mode&#8217;, true);<br />$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($players as $i =&gt; $player_name) {<br />if (!$player_name) continue;<br />foreach ($games as $j =&gt; $game) {<br />if (!isset($game[$i])) continue;<br />$score = intval($game[$i]);<br />if (!isset($highest_scores[$player_name]) || $score &gt; $highest_scores[$player_name][&#8216;score&#8217;]) {<br />$highest_scores[$player_name] = [<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; $tournament_name,<br />&#8216;game_number&#8217; =&gt; $j + 1,<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($highest_scores)) return &#8216;No scores recorded yet.&#8217;;</p>
<p>// Sort descending by highest score<br />uasort($highest_scores, fn($a,$b) =&gt; $b[&#8216;score&#8217;] &#8211; $a[&#8216;score&#8217;]);</p>
<p>// Build table<br />$out = &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;<br />&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;Rank&lt;/th&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Highest Score&lt;/th&gt;<br />&lt;th&gt;Tournament&lt;/th&gt;<br />&lt;th&gt;Game #&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;<br />&lt;tbody&gt;&#8217;;</p>
<p>$rank = 1;<br />foreach ($highest_scores as $player =&gt; $data) {<br />// Highlight top row<br />$row_class = ($rank === 1) ? &#8216;top-winner&#8217; : &#8221;;<br />$out .= &#8216;&lt;tr class=&#8221;&#8216;.$row_class.'&#8221;&gt;<br />&lt;td&gt;&#8217;.$rank.'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($player).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;score&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($data[&#8216;tournament&#8217;]).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.intval($data[&#8216;game_number&#8217;]).'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;<br />$rank++;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>// Optional inline CSS to highlight the top player<br />$out .= &#8216;<br />&lt;style&gt;<br />.tournament-table .top-winner {<br />background-color: #d4edda; /* light green */<br />font-weight: bold;<br />}<br />&lt;/style&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>&nbsp;</p>
<p>add_shortcode(&#8216;tournament_individual_lifetime_stats_all&#8217;, function () {<br />$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;<br />]);</p>
<p>$stats = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$mode = get_post_meta(get_the_ID(), &#8216;ts_mode&#8217;, true);<br />if ($mode !== &#8216;individual&#8217;) continue;</p>
<p>$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($players as $p =&gt; $player_name) {<br />if (!$player_name) continue;<br />if (!isset($stats[$player_name])) {<br />$stats[$player_name] = [<br />&#8216;games&#8217; =&gt; 0,<br />&#8216;wins&#8217; =&gt; 0,<br />&#8216;points&#8217; =&gt; 0,<br />&#8216;highest&#8217; =&gt; 0<br />];<br />}<br />}</p>
<p>foreach ($games as $game) {<br />if (!is_array($game)) continue;<br />$max_score = max(array_map(&#8216;intval&#8217;, $game));<br />foreach ($players as $p =&gt; $player_name) {<br />if (!$player_name) continue;<br />$score = intval($game[$p] ?? 0);<br />$stats[$player_name][&#8216;games&#8217;]++;<br />$stats[$player_name][&#8216;points&#8217;] += $score;<br />if ($score &gt; $stats[$player_name][&#8216;highest&#8217;]) {<br />$stats[$player_name][&#8216;highest&#8217;] = $score;<br />}<br />if ($score === $max_score &amp;&amp; $max_score &gt; 0) {<br />$stats[$player_name][&#8216;wins&#8217;]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($stats)) return &#8216;No lifetime stats recorded yet.&#8217;;</p>
<p>uasort($stats, function($a, $b) {<br />if ($b[&#8216;wins&#8217;] === $a[&#8216;wins&#8217;]) return $b[&#8216;points&#8217;] &lt;=&gt; $a[&#8216;points&#8217;];<br />return $b[&#8216;wins&#8217;] &lt;=&gt; $a[&#8216;wins&#8217;];<br />});</p>
<p>$out = &#8216;&lt;h3&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Individual Lifetime Stats (All Games)&lt;/h3&gt;&#8217;;<br />$out .= &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;</p>
<p>// Header<br />$out .= &#8216;&lt;thead&gt;&#8217;;<br />$out .= &#8216;&lt;tr&gt;<br />&lt;th&gt;Rank&lt;/th&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Total Games&lt;/th&gt;<br />&lt;th&gt;Total Wins&lt;/th&gt;<br />&lt;th&gt;Total Points&lt;/th&gt;<br />&lt;th&gt;Highest Points&lt;/th&gt;<br />&lt;/tr&gt;&#8217;;<br />$out .= &#8216;&lt;/thead&gt;&#8217;;</p>
<p>// Body<br />$out .= &#8216;&lt;tbody&gt;&#8217;;<br />$rank = 1;<br />foreach ($stats as $player =&gt; $data) {<br />$class = ($rank === 1) ? &#8216;winner&#8217; : &#8221;;<br />$out .= &#8216;&lt;tr class=&#8221;&#8216;.$class.'&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217; . $rank . &#8216;&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217; . esc_html($player) . &#8216;&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217; . $data[&#8216;games&#8217;] . &#8216;&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217; . $data[&#8216;wins&#8217;] . &#8216;&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217; . $data[&#8216;points&#8217;] . &#8216;&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217; . $data[&#8216;highest&#8217;] . &#8216;&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;<br />$rank++;<br />}<br />$out .= &#8216;&lt;/tbody&gt;&#8217;;</p>
<p>$out .= &#8216;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>&nbsp;</p>
<p>add_shortcode(&#8216;tournament_lifetime_wins_all&#8217;, function () {<br />$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;<br />]);</p>
<p>$wins = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();<br />$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $game) {<br />$max_score = max($game);<br />foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;<br />if (intval($game[$p]) === $max_score) {<br />$wins[$name] = $wins[$name] ?? 0;<br />$wins[$name]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($wins)) return &#8216;No lifetime wins recorded yet.&#8217;;</p>
<p>arsort($wins);</p>
<p>$out .= &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;</p>
<p>// HEADER<br />$out .= &#8216;&lt;thead&gt;&#8217;;<br />$out .= &#8216;&lt;tr&gt;<br />&lt;th&gt;Rank&lt;/th&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Wins&lt;/th&gt;<br />&lt;/tr&gt;&#8217;;<br />$out .= &#8216;&lt;/thead&gt;&#8217;;</p>
<p>// BODY<br />$out .= &#8216;&lt;tbody&gt;&#8217;;<br />$rank = 1;<br />foreach ($wins as $player =&gt; $count) {<br />$out .= &#8216;&lt;tr&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217; . $rank . &#8216;&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217; . esc_html($player) . &#8216;&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217; . $count . &#8216;&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;<br />$rank++;<br />}<br />$out .= &#8216;&lt;/tbody&gt;&#8217;;</p>
<p>$out .= &#8216;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />INDIVIDUAL LIFETIME WINS (MATCHES tournament_wins_individual)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_individual_lifetime_wins_exact&#8217;, function () {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;individual&#8217;]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No individual tournaments found.&#8217;;</p>
<p>$wins = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $game) {<br />$max_score = max(array_map(&#8216;intval&#8217;, $game));</p>
<p>foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;</p>
<p>if (intval($game[$i] ?? 0) === $max_score &amp;&amp; $max_score &gt; 0) {<br />$wins[$name] = ($wins[$name] ?? 0) + 1;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($wins)) return &#8216;No wins recorded yet.&#8217;;</p>
<p>arsort($wins);</p>
<p>$out .= &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;<br />&lt;thead&gt;<br />&lt;tr&gt;<br />&lt;th&gt;Rank&lt;/th&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Total Wins&lt;/th&gt;<br />&lt;/tr&gt;<br />&lt;/thead&gt;<br />&lt;tbody&gt;&#8217;;</p>
<p>$rank = 1;<br />foreach ($wins as $player =&gt; $count) {<br />$class = ($rank === 1) ? &#8216;winner&#8217; : &#8221;;</p>
<p>$out .= &#8216;&lt;tr class=&#8221;&#8216;.$class.'&#8221;&gt;<br />&lt;td&gt;&#8217;.$rank.'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($player).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.$count.'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;</p>
<p>$rank++;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />FRONT-END ADMIN-STYLE GAME TABLE WITH DELETE BUTTON<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_admin_style_table&#8217;, function() {</p>
<p>if (!is_singular(&#8216;tournament&#8217;)) return &#8221;;<br />if (!is_user_logged_in()) return &#8216;&lt;p&gt;Please log in to edit scores.&lt;/p&gt;&#8217;;</p>
<p>global $post;<br />$tournament_id = $post-&gt;ID;</p>
<p>// &#8212; Get all players &#8212;<br />$all_players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />if (!is_array($all_players)) $all_players = [];<br />$all_players = array_filter($all_players);</p>
<p>if (empty($all_players)) {<br />return &#8216;&lt;p&gt;No players found. Please add players to this tournament first.&lt;/p&gt;&#8217;;<br />}</p>
<p>// &#8212; Get mode &#8212;<br />$mode = get_post_meta($tournament_id, &#8216;ts_mode&#8217;, true);<br />if (!$mode) $mode = &#8216;individual&#8217;;</p>
<p>// &#8212; Build players array with original indices &#8212;<br />$players = [];<br />if ($mode === &#8216;1v1&#8217;) {<br />$first_two = array_slice($all_players, 0, 2, true);<br />foreach ($first_two as $i =&gt; $name) $players[] = [&#8216;name&#8217;=&gt;$name, &#8216;index&#8217;=&gt;$i];<br />} elseif ($mode === &#8216;teams&#8217;) {<br />$teams = ts_get_teams($all_players);<br />foreach (array_merge($teams[&#8216;A&#8217;], $teams[&#8216;B&#8217;]) as $p) {<br />$players[] = [&#8216;name&#8217;=&gt;$p[&#8216;name&#8217;], &#8216;index&#8217;=&gt;$p[&#8216;index&#8217;]];<br />}<br />} else {<br />foreach ($all_players as $i =&gt; $name) $players[] = [&#8216;name&#8217;=&gt;$name, &#8216;index&#8217;=&gt;$i];<br />}</p>
<p>// &#8212; Get games &amp; scores &#8212;<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);<br />if (!is_array($games)) $games = [];<br />if (empty($games)) $games = [ [] ]; // at least one row</p>
<p>ob_start();<br />?&gt;<br />&lt;form method=&#8221;post&#8221; class=&#8221;tournament-admin-table&#8221;&gt;<br />&lt;?php wp_nonce_field(&#8216;ts_save_games&#8217;,&#8217;ts_save_nonce&#8217;); ?&gt;<br />&lt;input type=&#8221;hidden&#8221; name=&#8221;tournament_id&#8221; value=&#8221;&lt;?php echo esc_attr($tournament_id); ?&gt;&#8221;&gt;</p>
<p>&lt;script&gt;<br />function tsDeleteGameRow(btn) {<br />const row = btn.closest(&#8220;tr&#8221;);<br />const index = row.getAttribute(&#8220;data-game-index&#8221;);<br />const input = document.createElement(&#8220;input&#8221;);<br />input.type = &#8220;hidden&#8221;;<br />input.name = &#8220;ts_delete_games[]&#8221;;<br />input.value = index;<br />row.parentNode.appendChild(input);<br />row.remove();<br />}<br />&lt;/script&gt;</p>
<p>&lt;table class=&#8221;tournament-table&#8221; border=&#8221;1&#8243; cellpadding=&#8221;5&#8243; style=&#8221;border-collapse:collapse; width:100%; text-align:center;&#8221;&gt;<br />&lt;tr&gt;<br />&lt;th style=&#8221;text-align:center; vertical-align:middle;&#8221;&gt;Game&lt;/th&gt;<br />&lt;?php foreach ($players as $player): ?&gt;<br />&lt;th style=&#8221;text-align:center; vertical-align:middle;&#8221;&gt;&lt;?php echo esc_html($player[&#8216;name&#8217;]); ?&gt;&lt;/th&gt;<br />&lt;?php endforeach; ?&gt;<br />&lt;th&gt;Delete&lt;/th&gt;<br />&lt;/tr&gt;</p>
<p>&lt;?php foreach ($games as $g_index =&gt; $game): ?&gt;<br />&lt;tr data-game-index=&#8221;&lt;?php echo $g_index; ?&gt;&#8221;&gt;<br />&lt;td style=&#8221;text-align:center; vertical-align:middle;&#8221;&gt;Game &lt;?php echo ($g_index + 1); ?&gt;&lt;/td&gt;<br />&lt;?php foreach ($players as $player): ?&gt;<br />&lt;td style=&#8221;text-align:center; vertical-align:middle;&#8221;&gt;<br />&lt;input<br />type=&#8221;text&#8221;<br />name=&#8221;ts_games[&lt;?php echo $g_index; ?&gt;][&lt;?php echo $player[&#8216;index&#8217;]; ?&gt;]&#8221;<br />value=&#8221;&lt;?php echo isset($game[$player[&#8216;index&#8217;]]) &amp;&amp; $game[$player[&#8216;index&#8217;]] !== 0 ? esc_attr($game[$player[&#8216;index&#8217;]]) : &#8221;; ?&gt;&#8221;<br />style=&#8221;width:90px; text-align:center; vertical-align:middle;&#8221;<br />pattern=&#8221;-?\d*&#8221;<br />inputmode=&#8221;numeric&#8221;<br />&gt;<br />&lt;/td&gt;<br />&lt;?php endforeach; ?&gt;</p>
<p>&lt;td style=&#8221;text-align:center;&#8221;&gt;<br />&lt;button type=&#8221;button&#8221; onclick=&#8221;tsDeleteGameRow(this)&#8221; style=&#8221;<br />color:#fff;<br />background:#e74c3c;<br />border:none;<br />border-radius:4px;<br />padding:2px 6px;<br />cursor:pointer;<br />font-weight:bold;<br />&#8220;&gt;X&lt;/button&gt;<br />&lt;/td&gt;</p>
<p>&lt;/tr&gt;<br />&lt;?php endforeach; ?&gt;<br />&lt;/table&gt;</p>
<p>&lt;p style=&#8221;margin-top:10px; text-align:center;&#8221;&gt;<br />&lt;button type=&#8221;submit&#8221; name=&#8221;add_new_game&#8221;&gt;Add New Game&lt;/button&gt;<br />&lt;button type=&#8221;submit&#8221; name=&#8221;save_existing_games&#8221;&gt;Save Scores&lt;/button&gt;<br />&lt;/p&gt;</p>
<p>&lt;/form&gt;<br />&lt;?php<br />return ob_get_clean();<br />});</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />HANDLE FRONT-END GAME TABLE SUBMISSION<br />with automatic per-game timing on Save / Add<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_action(&#8216;init&#8217;, function() {</p>
<p>// Only run if Save Scores or Add New Game clicked<br />if (!isset($_POST[&#8216;save_existing_games&#8217;]) &amp;&amp; !isset($_POST[&#8216;add_new_game&#8217;])) return;</p>
<p>// Security check<br />if (!isset($_POST[&#8216;ts_save_nonce&#8217;]) || !wp_verify_nonce($_POST[&#8216;ts_save_nonce&#8217;], &#8216;ts_save_games&#8217;)) return;</p>
<p>$tournament_id = intval($_POST[&#8216;tournament_id&#8217;]);<br />if (!$tournament_id) return;</p>
<p>// &#8212; Load existing tournament data &#8212;<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true) ?: [];<br />$game_starts = get_post_meta($tournament_id, &#8216;ts_game_starts&#8217;, true) ?: [];<br />$game_ends = get_post_meta($tournament_id, &#8216;ts_game_ends&#8217;, true) ?: [];<br />$game_durations = get_post_meta($tournament_id, &#8216;ts_game_durations&#8217;, true) ?: [];<br />$current_start = get_post_meta($tournament_id, &#8216;ts_current_game_start&#8217;, true);</p>
<p>// &#8212; Save current scores &#8212;<br />if (!empty($_POST[&#8216;ts_games&#8217;]) &amp;&amp; is_array($_POST[&#8216;ts_games&#8217;])) {<br />foreach ($_POST[&#8216;ts_games&#8217;] as $g_index =&gt; $game_data) {<br />if (!is_array($game_data)) continue;<br />foreach ($game_data as $p_index =&gt; $score) {<br />$games[$g_index][$p_index] = intval($score);<br />}<br />}<br />}</p>
<p>// &#8212; End current game timer if running BEFORE adding a new game &#8212;<br />if ($current_start) {<br />$end_time = current_time(&#8216;timestamp&#8217;, true);<br />$duration_seconds = $end_time &#8211; $current_start;</p>
<p>$hours = floor($duration_seconds / 3600);<br />$minutes = floor(($duration_seconds % 3600) / 60);<br />$seconds = $duration_seconds % 60;<br />$duration = sprintf(&#8216;%02dh %02dm %02ds&#8217;, $hours, $minutes, $seconds);</p>
<p>// Save finished game info<br />$game_starts[] = $current_start;<br />$game_ends[] = $end_time;<br />$game_durations[] = $duration;</p>
<p>// Remove current timer before adding new game<br />delete_post_meta($tournament_id, &#8216;ts_current_game_start&#8217;);<br />}</p>
<p>// &#8212; Add new game if requested &#8212;<br />if (isset($_POST[&#8216;add_new_game&#8217;])) {<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true) ?: [];<br />$players = array_filter($players);</p>
<p>$new_game = [];<br />foreach ($players as $p_index =&gt; $player_name) {<br />$new_game[$p_index] = 0; // Initialize blank score<br />}</p>
<p>// Add the new game row<br />$games[] = $new_game;</p>
<p>// Start timer for the new game immediately AFTER previous game has ended<br />update_post_meta($tournament_id, &#8216;ts_current_game_start&#8217;, current_time(&#8216;timestamp&#8217;, true));<br />}</p>
<p>// &#8212; Delete games if requested &#8212;<br />if (!empty($_POST[&#8216;ts_delete_games&#8217;]) &amp;&amp; is_array($_POST[&#8216;ts_delete_games&#8217;])) {<br />foreach ($_POST[&#8216;ts_delete_games&#8217;] as $delete_index) {<br />unset($games[$delete_index], $game_starts[$delete_index], $game_ends[$delete_index], $game_durations[$delete_index]);<br />}</p>
<p>// Reindex arrays to remove gaps<br />$games = array_values($games);<br />$game_starts = array_values($game_starts);<br />$game_ends = array_values($game_ends);<br />$game_durations = array_values($game_durations);<br />}</p>
<p>// &#8212; Save all updated meta &#8212;<br />update_post_meta($tournament_id, &#8216;ts_games&#8217;, $games);<br />update_post_meta($tournament_id, &#8216;ts_game_starts&#8217;, $game_starts);<br />update_post_meta($tournament_id, &#8216;ts_game_ends&#8217;, $game_ends);<br />update_post_meta($tournament_id, &#8216;ts_game_durations&#8217;, $game_durations);</p>
<p>// Reload page so table and durations update correctly<br />wp_safe_redirect(get_permalink($tournament_id));<br />exit;<br />});</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>// &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-<br />// DASHBOARD SECTION BELOW THIS<br />// &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />RUMMY ROYALE — DASHBOARD CARDS<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */</p>
<p>add_action(&#8216;wp_dashboard_setup&#8217;, function () {<br />if (!current_user_can(&#8216;manage_options&#8217;)) return;</p>
<p>// Top 3 Players Widgets<br />wp_add_dashboard_widget(&#8216;rr_top3_1v1_widget&#8217;, &#8216;Top 3 Players — 1v1 Mode <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, &#8216;rr_top3_1v1&#8217;);<br />wp_add_dashboard_widget(&#8216;rr_top3_individual_widget&#8217;, &#8216;Top 3 Players — Individual Mode <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, &#8216;rr_top3_individual&#8217;);</p>
<p>// Team Mode Player Scores<br />wp_add_dashboard_widget(&#8216;rr_team_mode_player_scores_widget&#8217;, &#8216;Team Mode — Player Scores <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c5.png" alt="🏅" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, &#8216;rr_team_mode_player_scores&#8217;);</p>
<p>// Last Winner<br />wp_add_dashboard_widget(&#8216;rr_last_winner_widget&#8217;, &#8216;Rummy Royale — Last Winner <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f947.png" alt="🥇" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, &#8216;rr_last_winner&#8217;);</p>
<p>// Quick Stats<br />wp_add_dashboard_widget(&#8216;rr_quick_stats_widget&#8217;, &#8216;Rummy Royale — Quick Stats <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ca.png" alt="📊" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, &#8216;rr_quick_stats&#8217;);</p>
<p>// Lifetime Player Stats<br />wp_add_dashboard_widget(&#8216;rr_lifetime_player_stats_widget&#8217;, &#8216;Rummy Royale — Lifetime Player Stats <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c5.png" alt="🏅" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, &#8216;rr_lifetime_player_stats&#8217;);</p>
<p>// Start New Tournament button<br />wp_add_dashboard_widget(&#8216;rr_start_new_tournament_widget&#8217;, &#8216;Rummy Royale — Start New Tournament <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3b2.png" alt="🎲" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, &#8216;rr_start_new_tournament&#8217;);<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />HELPER: Aggregate Scores<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function rr_aggregate_scores($tournaments, $mode_filter = null, $is_team = false) {<br />$totals = [];<br />foreach ($tournaments as $t) {<br />$mode = get_post_meta($t-&gt;ID, &#8216;ts_mode&#8217;, true);<br />if ($mode_filter !== null &amp;&amp; $mode !== $mode_filter &amp;&amp; $mode !== $mode_filter.&#8217;s&#8217;) continue;</p>
<p>$entities = $is_team ? get_post_meta($t-&gt;ID, &#8216;ts_teams&#8217;, true) : get_post_meta($t-&gt;ID, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($t-&gt;ID, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($entities)) $entities = [];<br />if (!is_array($games)) $games = [];</p>
<p>foreach ($entities as $name) {<br />if (!empty($name) &amp;&amp; !isset($totals[$name])) $totals[$name] = 0;<br />}</p>
<p>foreach ($games as $game) {<br />if (!is_array($game)) continue;<br />foreach ($game as $index =&gt; $score) {<br />$name = $entities[$index] ?? null;<br />if (!empty($name)) $totals[$name] += intval($score);<br />}<br />}<br />}<br />arsort($totals);<br />return $totals;<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CARD WRAPPER<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function rr_widget_card($title, $content_html) {<br />echo &#8216;&lt;div style=&#8221;padding:15px; background:#fff; border-radius:10px; box-shadow:0 2px 8px rgba(0,0,0,0.1); max-width:400px; margin:0 auto;&#8221;&gt;&#8217;;<br />echo &#8216;&lt;h4 style=&#8221;text-align:center; margin-bottom:15px;&#8221;&gt;&#8217;.esc_html($title).'&lt;/h4&gt;&#8217;;<br />echo $content_html;<br />echo &#8216;&lt;/div&gt;&#8217;;<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />TOP 3 PLAYERS — 1v1<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function rr_top3_1v1() {<br />$tournaments = get_posts([&#8216;post_type&#8217;=&gt;&#8217;tournament&#8217;,&#8217;post_status&#8217;=&gt;&#8217;publish&#8217;,&#8217;posts_per_page&#8217;=&gt;-1]);<br />$totals = rr_aggregate_scores($tournaments, &#8216;1v1&#8217;, false);<br />$top3 = array_slice($totals, 0, 3, true);</p>
<p>$html = &#8216;&lt;ul style=&#8221;list-style:none; padding-left:0; text-align:center;&#8221;&gt;&#8217;;<br />if ($top3) {<br />foreach ($top3 as $player =&gt; $score) {<br />$html .= &#8216;&lt;li&gt;&#8217;.esc_html($player).&#8217; — &#8216;.$score.'&lt;/li&gt;&#8217;;<br />}<br />} else {<br />$html .= &#8216;&lt;li&gt;No 1v1 players yet.&lt;/li&gt;&#8217;;<br />}<br />$html .= &#8216;&lt;/ul&gt;&#8217;;</p>
<p>rr_widget_card(&#8216;Top 3 Players — 1v1 Mode <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, $html);<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />TOP 3 PLAYERS — INDIVIDUAL<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function rr_top3_individual() {<br />$tournaments = get_posts([&#8216;post_type&#8217;=&gt;&#8217;tournament&#8217;,&#8217;post_status&#8217;=&gt;&#8217;publish&#8217;,&#8217;posts_per_page&#8217;=&gt;-1]);<br />$totals = rr_aggregate_scores($tournaments, null, false);</p>
<p>// Remove team tournament players<br />$totals_filtered = [];<br />foreach ($tournaments as $t) {<br />if (get_post_meta($t-&gt;ID,&#8217;ts_mode&#8217;,true) === &#8216;team&#8217; || get_post_meta($t-&gt;ID,&#8217;ts_mode&#8217;,true) === &#8216;teams&#8217;) continue;<br />$players = get_post_meta($t-&gt;ID,&#8217;ts_players&#8217;,true);<br />if (!is_array($players)) continue;<br />foreach ($players as $player) {<br />if (!empty($player)) $totals_filtered[$player] = $totals[$player] ?? 0;<br />}<br />}</p>
<p>arsort($totals_filtered);<br />$top3 = array_slice($totals_filtered,0,3,true);</p>
<p>$html = &#8216;&lt;ul style=&#8221;list-style:none; padding-left:0; text-align:center;&#8221;&gt;&#8217;;<br />if ($top3) {<br />foreach ($top3 as $player =&gt; $score) {<br />$html .= &#8216;&lt;li&gt;&#8217;.esc_html($player).&#8217; — &#8216;.$score.'&lt;/li&gt;&#8217;;<br />}<br />} else {<br />$html .= &#8216;&lt;li&gt;No individual players yet.&lt;/li&gt;&#8217;;<br />}<br />$html .= &#8216;&lt;/ul&gt;&#8217;;</p>
<p>rr_widget_card(&#8216;Top 3 Players — Individual Mode <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, $html);<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />TEAM MODE PLAYER SCORES<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function rr_team_mode_player_scores() {<br />$tournaments = get_posts([&#8216;post_type&#8217;=&gt;&#8217;tournament&#8217;,&#8217;post_status&#8217;=&gt;&#8217;publish&#8217;,&#8217;posts_per_page&#8217;=&gt;-1]);<br />$totals = [];</p>
<p>foreach ($tournaments as $t) {<br />$mode = get_post_meta($t-&gt;ID,&#8217;ts_mode&#8217;,true);<br />if ($mode !== &#8216;team&#8217; &amp;&amp; $mode !== &#8216;teams&#8217;) continue;</p>
<p>$players = get_post_meta($t-&gt;ID,&#8217;ts_players&#8217;,true);<br />$games = get_post_meta($t-&gt;ID,&#8217;ts_games&#8217;,true);</p>
<p>if (!is_array($players)) $players = [];<br />if (!is_array($games)) $games = [];</p>
<p>foreach ($players as $player_name) {<br />if (!empty($player_name) &amp;&amp; !isset($totals[$player_name])) $totals[$player_name] = 0;<br />}</p>
<p>foreach ($games as $game) {<br />if (!is_array($game)) continue;<br />foreach ($game as $index =&gt; $score) {<br />$player_name = $players[$index] ?? null;<br />if (!empty($player_name)) $totals[$player_name] += intval($score);<br />}<br />}<br />}</p>
<p>if (empty($totals)) {<br />$html = &#8216;&lt;p style=&#8221;text-align:center; font-style:italic;&#8221;&gt;No team-mode players yet.&lt;/p&gt;&#8217;;<br />} else {<br />$html = &#8216;&lt;table style=&#8221;width:100%; border-collapse:collapse; text-align:center;&#8221;&gt;&#8217;;<br />$html .= &#8216;&lt;thead&gt;&lt;tr style=&#8221;background:#f7f7f7;&#8221;&gt;&lt;th style=&#8221;padding:8px; border-bottom:1px solid #ddd;&#8221;&gt;Player&lt;/th&gt;&lt;th style=&#8221;padding:8px; border-bottom:1px solid #ddd;&#8221;&gt;Score&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&#8217;;<br />$html .= &#8216;&lt;tbody&gt;&#8217;;<br />arsort($totals);<br />foreach ($totals as $player =&gt; $score) {<br />$html .= &#8216;&lt;tr&gt;&lt;td style=&#8221;padding:8px; border-bottom:1px solid #eee;&#8221;&gt;&#8217;.esc_html($player).'&lt;/td&gt;&lt;td style=&#8221;padding:8px; border-bottom:1px solid #eee;&#8221;&gt;&#8217;.$score.'&lt;/td&gt;&lt;/tr&gt;&#8217;;<br />}<br />$html .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;<br />}</p>
<p>rr_widget_card(&#8216;Team Mode — Player Scores <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c5.png" alt="🏅" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, $html);<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />LAST WINNER<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function rr_last_winner() {<br />$tournaments = get_posts([&#8216;post_type&#8217;=&gt;&#8217;tournament&#8217;,&#8217;posts_per_page&#8217;=&gt;1,&#8217;post_status&#8217;=&gt;&#8217;publish&#8217;,&#8217;orderby&#8217;=&gt;&#8217;ID&#8217;,&#8217;order&#8217;=&gt;&#8217;DESC&#8217;]);<br />$winner = &#8216;N/A&#8217;;</p>
<p>if (!empty($tournaments)) {<br />$t = $tournaments[0];<br />$players = get_post_meta($t-&gt;ID,&#8217;ts_players&#8217;,true);<br />$games = get_post_meta($t-&gt;ID,&#8217;ts_games&#8217;,true);<br />$winner = get_post_meta($t-&gt;ID,&#8217;ts_1000plus_winner&#8217;,true);</p>
<p>if (!$winner &amp;&amp; is_array($games) &amp;&amp; !empty($games)) {<br />$last_game = end($games);<br />if (is_array($last_game)) {<br />arsort($last_game);<br />$index = key($last_game);<br />$winner = $players[$index] ?? &#8216;N/A&#8217;;<br />}<br />}<br />}</p>
<p>$html = &#8216;&lt;p style=&#8221;text-align:center; font-weight:bold; font-size:16px;&#8221;&gt;&#8217;.esc_html($winner).'&lt;/p&gt;&#8217;;<br />rr_widget_card(&#8216;Rummy Royale — Last Winner <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f947.png" alt="🥇" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, $html);<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />QUICK STATS<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function rr_quick_stats() {<br />$tournaments = get_posts([&#8216;post_type&#8217;=&gt;&#8217;tournament&#8217;,&#8217;post_status&#8217;=&gt;&#8217;publish&#8217;,&#8217;posts_per_page&#8217;=&gt;-1]);<br />$all_players = [];<br />$total_games = 0;</p>
<p>foreach ($tournaments as $t) {<br />$players = get_post_meta($t-&gt;ID,&#8217;ts_players&#8217;,true);<br />$games = get_post_meta($t-&gt;ID,&#8217;ts_games&#8217;,true);<br />if (is_array($players)) $all_players = array_merge($all_players,$players);<br />if (is_array($games)) $total_games += count($games);<br />}</p>
<p>$unique_players = array_filter(array_unique($all_players));</p>
<p>$html = &#8216;&lt;ul style=&#8221;list-style:none; padding-left:0; text-align:center;&#8221;&gt;&#8217;;<br />$html .= &#8216;&lt;li&gt;Total Players: &#8216;.count($unique_players).'&lt;/li&gt;&#8217;;<br />$html .= &#8216;&lt;li&gt;Games Played: &#8216;.$total_games.'&lt;/li&gt;&#8217;;<br />$html .= &#8216;&lt;li&gt;Total Tournaments: &#8216;.count($tournaments).'&lt;/li&gt;&#8217;;<br />$html .= &#8216;&lt;/ul&gt;&#8217;;</p>
<p>rr_widget_card(&#8216;Rummy Royale — Quick Stats <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ca.png" alt="📊" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, $html);<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />LIFETIME PLAYER STATS<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function rr_lifetime_player_stats() {<br />$tournaments = get_posts([&#8216;post_type&#8217;=&gt;&#8217;tournament&#8217;,&#8217;post_status&#8217;=&gt;&#8217;publish&#8217;,&#8217;posts_per_page&#8217;=&gt;-1]);<br />$totals = [];<br />$games_played_per_player = [];</p>
<p>foreach ($tournaments as $t) {<br />$players = get_post_meta($t-&gt;ID,&#8217;ts_players&#8217;,true);<br />$games = get_post_meta($t-&gt;ID,&#8217;ts_games&#8217;,true);<br />if (!is_array($players)) $players = [];<br />if (!is_array($games)) $games = [];</p>
<p>foreach ($players as $player_name) {<br />if (!empty($player_name)) {<br />if (!isset($totals[$player_name])) $totals[$player_name] = 0;<br />if (!isset($games_played_per_player[$player_name])) $games_played_per_player[$player_name] = 0;<br />}<br />}</p>
<p>foreach ($games as $game) {<br />if (!is_array($game)) continue;<br />foreach ($game as $index =&gt; $score) {<br />$player_name = $players[$index] ?? null;<br />if (!empty($player_name)) {<br />$totals[$player_name] += intval($score);<br />$games_played_per_player[$player_name] += 1;<br />}<br />}<br />}<br />}</p>
<p>arsort($totals);</p>
<p>$html = &#8216;&lt;table style=&#8221;width:100%; border-collapse:collapse;&#8221;&gt;&#8217;;<br />$html .= &#8216;&lt;thead&gt;&lt;tr style=&#8221;border-bottom:1px solid #ccc;&#8221;&gt;&lt;th style=&#8221;text-align:left; padding:5px;&#8221;&gt;Player&lt;/th&gt;&lt;th style=&#8221;text-align:right; padding:5px;&#8221;&gt;Lifetime Score&lt;/th&gt;&lt;th style=&#8221;text-align:right; padding:5px;&#8221;&gt;Games Played&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&#8217;;<br />$html .= &#8216;&lt;tbody&gt;&#8217;;</p>
<p>foreach ($totals as $player =&gt; $score) {<br />$games_played = $games_played_per_player[$player] ?? 0;<br />$html .= &#8216;&lt;tr&gt;&#8217;;<br />$html .= &#8216;&lt;td style=&#8221;padding:5px;&#8221;&gt;&#8217;.esc_html($player).'&lt;/td&gt;&#8217;;<br />$html .= &#8216;&lt;td style=&#8221;padding:5px; text-align:right;&#8221;&gt;&#8217;.$score.'&lt;/td&gt;&#8217;;<br />$html .= &#8216;&lt;td style=&#8221;padding:5px; text-align:right;&#8221;&gt;&#8217;.$games_played.'&lt;/td&gt;&#8217;;<br />$html .= &#8216;&lt;/tr&gt;&#8217;;<br />}</p>
<p>$html .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>rr_widget_card(&#8216;Rummy Royale — Lifetime Player Stats <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c5.png" alt="🏅" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, $html);<br />}</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />START NEW TOURNAMENT BUTTON<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />function rr_start_new_tournament() {<br />$new_tournament_url = admin_url(&#8216;post-new.php?post_type=tournament&#8217;);<br />$html = &#8216;&lt;p style=&#8221;text-align:center;&#8221;&gt;Click below to start a new Rummy Royale tournament:&lt;/p&gt;&#8217;;<br />$html .= &#8216;&lt;div style=&#8221;text-align:center;&#8221;&gt;&lt;a class=&#8221;button button-primary&#8221; href=&#8221;&#8216;.esc_url($new_tournament_url).'&#8221;&gt;Start New Tournament&lt;/a&gt;&lt;/div&gt;&#8217;;</p>
<p>rr_widget_card(&#8216;Rummy Royale — Start New Tournament <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3b2.png" alt="🎲" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;, $html);<br />}</p>
<p>&nbsp;</p>
<p>add_action(&#8216;wp_enqueue_scripts&#8217;, function(){</p>
<p>$s = get_option(&#8216;ts_table_styles&#8217;, []);<br />$s = wp_parse_args($s, [<br />&#8216;header_bg&#8217; =&gt; &#8216;#4CAF50&#8217;,<br />&#8216;header_text&#8217; =&gt; &#8216;#ffffff&#8217;,<br />&#8216;row_even&#8217; =&gt; &#8216;#f2f2f2&#8217;,<br />&#8216;row_odd&#8217; =&gt; &#8216;#ffffff&#8217;,<br />&#8216;winner_bg&#8217; =&gt; &#8216;#d4edda&#8217;,<br />&#8216;table_text&#8217; =&gt; &#8216;#000000&#8217;<br />]);</p>
<p>wp_register_style(&#8216;ts-table-styles&#8217;, false);<br />wp_enqueue_style(&#8216;ts-table-styles&#8217;);</p>
<p>$css = &lt;&lt;&lt;CSS<br />:root {<br />&#8211;ts-header-bg: {$s[&#8216;header_bg&#8217;]};<br />&#8211;ts-header-text: {$s[&#8216;header_text&#8217;]};<br />&#8211;ts-row-even: {$s[&#8216;row_even&#8217;]};<br />&#8211;ts-row-odd: {$s[&#8216;row_odd&#8217;]};<br />&#8211;ts-winner-bg: {$s[&#8216;winner_bg&#8217;]};<br />&#8211;ts-text: {$s[&#8216;table_text&#8217;]};<br />&#8211;ts-border: rgba(0,0,0,0.1);<br />&#8211;ts-hover: rgba(0,0,0,0.05);<br />}</p>
<p>.tournament-table {<br />width: 100%;<br />border-collapse: collapse;<br />color: var(&#8211;ts-text);<br />background: transparent;<br />font-size: 15px;<br />}</p>
<p>.tournament-table thead th {<br />background: var(&#8211;ts-header-bg);<br />color: var(&#8211;ts-header-text);<br />padding: 10px;<br />text-align: center;<br />border-bottom: 2px solid var(&#8211;ts-border);<br />}</p>
<p>.tournament-table tbody td {<br />padding: 10px;<br />text-align: center;<br />border-bottom: 1px solid var(&#8211;ts-border);<br />}</p>
<p>.tournament-table tbody tr:nth-child(even) {<br />background: var(&#8211;ts-row-even);<br />}</p>
<p>.tournament-table tbody tr:nth-child(odd) {<br />background: var(&#8211;ts-row-odd);<br />}</p>
<p>.tournament-table tbody tr:hover {<br />background: var(&#8211;ts-hover);<br />transition: background 0.2s ease;<br />}</p>
<p>.tournament-table tbody tr.winner {<br />background: var(&#8211;ts-winner-bg) !important;<br />font-weight: bold;<br />box-shadow: inset 4px 0 0 var(&#8211;ts-header-bg);<br />}</p>
<p>table.tournament-table tr:not(.winner):hover td {<br />background-color: var(&#8211;ts-hover);<br />transition: background 0.2s ease;<br />}</p>
<p>.tournament-duration {<br />text-align: center;<br />font-size: 13px;<br />color: #666;<br />margin-bottom: 6px;<br />}</p>
<p>CSS;</p>
<p>wp_add_inline_style(&#8216;ts-table-styles&#8217;, $css);<br />});</p>
<p>add_action(&#8216;wp_footer&#8217;, function () {<br />?&gt;<br />&lt;script&gt;<br />document.addEventListener(&#8216;click&#8217;, function(e){<br />// Only proceed if the clicked element has the toggle-category class<br />if (!e.target.classList.contains(&#8216;toggle-category&#8217;)) return;</p>
<p>const container = e.target.closest(&#8216;.tournament-category-cards&#8217;);<br />if (!container) return;</p>
<p>const hiddenCards = container.querySelectorAll(&#8216;.hidden-card&#8217;);</p>
<p>hiddenCards.forEach(card =&gt; {<br />card.style.display = (card.style.display === &#8216;block&#8217;) ? &#8216;none&#8217; : &#8216;block&#8217;;<br />});</p>
<p>// Toggle button text<br />e.target.textContent = (e.target.textContent === &#8216;Show More&#8217;) ? &#8216;Show Less&#8217; : &#8216;Show More&#8217;;<br />});<br />&lt;/script&gt;<br />&lt;?php<br />});</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />TOURNAMENTS BY CATEGORY PAGE &#8211; ALL GAMES IN CARD VIEW (4 COLUMNS, EQUAL HEIGHT)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_category_games&#8217;, function ($atts) {</p>
<p>// Determine category<br />if (is_category() || is_tax(&#8216;tournament_category&#8217;)) {<br />$term = get_queried_object();<br />$category_slug = $term-&gt;slug;<br />} elseif (!empty($atts[&#8216;category&#8217;])) {<br />$category_slug = sanitize_text_field($atts[&#8216;category&#8217;]);<br />} else {<br />return &#8216;No category specified.&#8217;;<br />}</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;orderby&#8217; =&gt; &#8216;date&#8217;,<br />&#8216;order&#8217; =&gt; &#8216;DESC&#8217;,<br />&#8216;tax_query&#8217; =&gt; [<br />[<br />&#8216;taxonomy&#8217; =&gt; &#8216;tournament_category&#8217;,<br />&#8216;field&#8217; =&gt; &#8216;slug&#8217;,<br />&#8216;terms&#8217; =&gt; $category_slug,<br />]<br />],<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No tournaments found in this category.&#8217;;</p>
<p>$out = &#8216;&lt;div class=&#8221;tournament-category-page&#8221;&gt;&#8217;;</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true) ?: [];<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true) ?: [];</p>
<p>// Total points per player<br />$totals = array_fill(0, count($players), 0);<br />foreach ($games as $game) {<br />foreach ($game as $p =&gt; $score) {<br />$totals[$p] += intval($score);<br />}<br />}<br />$max_score = !empty($totals) ? max($totals) : 0;</p>
<p>// Total games played<br />$total_games = is_array($games) ? count($games) : 0;</p>
<p>// Total duration<br />$game_starts = get_post_meta(get_the_ID(), &#8216;ts_game_starts&#8217;, true) ?: [];<br />$game_ends = get_post_meta(get_the_ID(), &#8216;ts_game_ends&#8217;, true) ?: [];<br />$current_start = get_post_meta(get_the_ID(), &#8216;ts_current_game_start&#8217;, true);<br />$total_seconds = 0;<br />foreach ($game_starts as $i =&gt; $start) {<br />$end = $game_ends[$i] ?? $start;<br />if ($end &gt; $start) $total_seconds += ($end &#8211; $start);<br />}<br />if ($current_start) {<br />$total_seconds += (current_time(&#8216;timestamp&#8217;, true) &#8211; $current_start);<br />}<br />$hours = floor($total_seconds / 3600);<br />$minutes = floor(($total_seconds % 3600) / 60);<br />$seconds = $total_seconds % 60;<br />$duration_text = sprintf(&#8216;%02dh %02dm %02ds&#8217;, $hours, $minutes, $seconds);</p>
<p>$is_finished = get_post_meta(get_the_ID(), &#8216;ts_finished&#8217;, true);</p>
<p>$out .= &#8216;&lt;div class=&#8221;tournament-card&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;div class=&#8221;card-content&#8221;&gt;&#8217;;</p>
<p>// Card header<br />$out .= &#8216;&lt;div class=&#8221;card-header&#8221;&gt;&#8217;;<br />if ($is_finished) {<br />$out .= &#8216;&lt;span class=&#8221;badge finished-badge&#8221;&gt;Finished&lt;/span&gt;&#8217;;<br />}<br />$out .= &#8216;&lt;h3&gt;&lt;a href=&#8221;&#8216;.get_permalink().'&#8221;&gt;&#8217;.get_the_title().'&lt;/a&gt;&lt;/h3&gt;&#8217;;<br />$out .= &#8216;&lt;/div&gt;&#8217;;</p>
<p>// Score table<br />if (!empty($players)) {<br />$out .= &#8216;&lt;table class=&#8221;score-table&#8221;&gt;&#8217;;<br />foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;<br />$highlight = ($totals[$p] === $max_score &amp;&amp; $max_score &gt; 0) ? &#8216;top-scorer&#8217; : &#8221;;<br />$out .= &#8216;&lt;tr class=&#8221;&#8216;.$highlight.'&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.esc_html($name).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td class=&#8221;points&#8221;&gt;&#8217;.intval($totals[$p]).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;<br />}<br />$out .= &#8216;&lt;/table&gt;&#8217;;<br />}</p>
<p>// Meta: games played + duration<br />$out .= &#8216;&lt;div class=&#8221;tournament-meta&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;div&gt;&lt;strong&gt;Games Played:&lt;/strong&gt; &#8216;.intval($total_games).'&lt;/div&gt;&#8217;;<br />$out .= &#8216;&lt;div&gt;&lt;strong&gt;Total Time:&lt;/strong&gt; &#8216;.$duration_text.'&lt;/div&gt;&#8217;;<br />$out .= &#8216;&lt;/div&gt;&#8217;;</p>
<p>$out .= &#8216;&lt;/div&gt;&#8217;; // end card-content</p>
<p>// View tournament button<br />$out .= &#8216;&lt;a href=&#8221;&#8216;.get_permalink().'&#8221; class=&#8221;view-tournament-btn&#8221;&gt;View Tournament&lt;/a&gt;&#8217;;</p>
<p>$out .= &#8216;&lt;/div&gt;&#8217;; // end tournament-card<br />}</p>
<p>wp_reset_postdata();<br />$out .= &#8216;&lt;/div&gt;&#8217;; // end category wrapper</p>
<p>// &#8212;&#8212;&#8212;&#8212;&#8212;- CSS &#8212;&#8212;&#8212;&#8212;&#8212;-<br />$out .= &#8216;<br />&lt;style&gt;<br />.tournament-category-page {<br />display: grid;<br />grid-template-columns: repeat(4, 1fr);<br />gap: 20px;<br />}<br />.tournament-card {<br />display:flex;<br />flex-direction:column;<br />justify-content:space-between;<br />align-items:center;<br />text-align:center;<br />padding:16px;<br />background:#fff;<br />border-radius:12px;<br />border:1px solid #ddd;<br />box-shadow:0 4px 8px rgba(0,0,0,0.08);<br />}<br />.card-content { flex-grow:1; width:100%; }<br />.card-header h3 { margin:6px 0 10px; font-size:16px; }<br />.score-table { width:100%; border-collapse:collapse; margin:8px 0; }<br />.score-table td { padding:4px 0; text-align:center; }<br />.score-table .points { font-weight:bold; }<br />.top-scorer { font-weight:bold; color:#e53935; }<br />.badge { display:inline-block; font-size:11px; padding:3px 6px; border-radius:4px; color:#fff; margin-bottom:5px; }<br />.finished-badge { background:#4CAF50; }<br />.tournament-meta { margin-top:10px; font-size:13px; color:#444; }<br />.view-tournament-btn {<br />margin-top:10px;<br />text-align:center;<br />padding:8px 12px;<br />background:#4CAF50;<br />color:#fff;<br />border-radius:6px;<br />font-weight:bold;<br />text-decoration:none;<br />}<br />/* Responsive */<br />@media(max-width:1200px) { .tournament-category-page { grid-template-columns: repeat(3, 1fr); } }<br />@media(max-width:900px) { .tournament-category-page { grid-template-columns: repeat(2, 1fr); } }<br />@media(max-width:600px) { .tournament-category-page { grid-template-columns: 1fr; } }<br />&lt;/style&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>&nbsp;</p>
<p>add_action(&#8216;wp_footer&#8217;, function () {<br />?&gt;<br />&lt;script&gt;<br />document.addEventListener(&#8216;click&#8217;, function(e){<br />// Toggle parent category<br />if (e.target.classList.contains(&#8216;parent-category&#8217;) || e.target.closest(&#8216;.parent-category&#8217;)) {<br />const header = e.target.closest(&#8216;.parent-category&#8217;);<br />const container = header.nextElementSibling;<br />if(container){<br />container.style.display = (container.style.display === &#8216;block&#8217;) ? &#8216;none&#8217; : &#8216;block&#8217;;<br />}<br />}</p>
<p>// Toggle Show More / hidden cards<br />if(e.target.classList.contains(&#8216;toggle-category&#8217;)){<br />const container = e.target.closest(&#8216;.tournament-category-cards&#8217;);<br />if(!container) return;</p>
<p>const hiddenCards = container.querySelectorAll(&#8216;.hidden-card&#8217;);<br />hiddenCards.forEach(card =&gt; {<br />card.style.display = (card.style.display === &#8216;block&#8217;) ? &#8216;none&#8217; : &#8216;block&#8217;;<br />});</p>
<p>e.target.textContent = (e.target.textContent === &#8216;Show More&#8217;) ? &#8216;Show Less&#8217; : &#8216;Show More&#8217;;<br />}<br />});<br />&lt;/script&gt;<br />&lt;?php<br />});</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />START FIRST GAME TIMER ON PUBLISH<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_action(&#8216;save_post_tournament&#8217;, function($post_id, $post, $update) {<br />if ($update) return; // Only run on first publish<br />if ($post-&gt;post_status !== &#8216;publish&#8217;) return;</p>
<p>// Start first game automatically<br />if (!get_post_meta($post_id, &#8216;ts_current_game_start&#8217;, true)) {<br />update_post_meta($post_id, &#8216;ts_current_game_start&#8217;, current_time(&#8216;timestamp&#8217;, true));<br />}<br />}, 10, 3);</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />TOURNAMENT GAME DURATIONS TABLE + LIVE TIMER<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_game_durations_table&#8217;, function() {</p>
<p>if (!is_singular(&#8216;tournament&#8217;)) return &#8221;;<br />if (!is_user_logged_in()) return &#8221;;</p>
<p>global $post;<br />$tournament_id = $post-&gt;ID;</p>
<p>$game_durations = get_post_meta($tournament_id, &#8216;ts_game_durations&#8217;, true) ?: [];<br />$game_starts = get_post_meta($tournament_id, &#8216;ts_game_starts&#8217;, true) ?: [];<br />$game_ends = get_post_meta($tournament_id, &#8216;ts_game_ends&#8217;, true) ?: [];<br />$current_start = get_post_meta($tournament_id, &#8216;ts_current_game_start&#8217;, true);</p>
<p>// If no current game but no finished games either, start Game 1 timer<br />if (!$current_start &amp;&amp; empty($game_durations)) {<br />$current_start = current_time(&#8216;timestamp&#8217;, true);<br />update_post_meta($tournament_id, &#8216;ts_current_game_start&#8217;, $current_start);<br />}</p>
<p>$total_seconds = 0;</p>
<p>ob_start(); ?&gt;<br />&lt;table border=&#8221;1&#8243; cellpadding=&#8221;6&#8243; style=&#8221;border-collapse:collapse; width:60%; margin:15px auto; text-align:center;&#8221;&gt;<br />&lt;tr style=&#8221;background:#f2f2f2;&#8221;&gt;<br />&lt;th&gt;Game&lt;/th&gt;<br />&lt;th&gt;Duration&lt;/th&gt;<br />&lt;/tr&gt;</p>
<p>&lt;?php<br />// Finished games<br />foreach ($game_durations as $index =&gt; $duration) :<br />$seconds = isset($game_ends[$index], $game_starts[$index]) ? ($game_ends[$index] &#8211; $game_starts[$index]) : 0;<br />$total_seconds += $seconds;<br />?&gt;<br />&lt;tr&gt;<br />&lt;td&gt;&lt;?php echo &#8216;Game &#8216; . ($index + 1); ?&gt;&lt;/td&gt;<br />&lt;td&gt;&lt;?php echo esc_html($duration); ?&gt;&lt;/td&gt;<br />&lt;/tr&gt;<br />&lt;?php endforeach; ?&gt;</p>
<p>&lt;?php if ($current_start) :<br />$current_seconds = current_time(&#8216;timestamp&#8217;, true) &#8211; $current_start;<br />$total_seconds += $current_seconds;<br />$hours = floor($current_seconds / 3600);<br />$minutes = floor(($current_seconds % 3600) / 60);<br />$seconds = $current_seconds % 60;<br />?&gt;<br />&lt;tr style=&#8221;background:#dff0d8; font-weight:bold;&#8221;&gt;<br />&lt;td&gt;&lt;?php echo &#8216;Game &#8216; . (count($game_durations) + 1); ?&gt; (In Progress)&lt;/td&gt;<br />&lt;td id=&#8221;current-game-duration&#8221;&gt;&lt;?php echo sprintf(&#8216;%02dh %02dm %02ds&#8217;, $hours, $minutes, $seconds); ?&gt;&lt;/td&gt;<br />&lt;/tr&gt;<br />&lt;?php endif; ?&gt;</p>
<p>&lt;?php<br />// Total tournament duration<br />$hours = floor($total_seconds / 3600);<br />$minutes = floor(($total_seconds % 3600) / 60);<br />$seconds = $total_seconds % 60;<br />?&gt;<br />&lt;tr style=&#8221;background:#eaeaea; font-weight:bold;&#8221;&gt;<br />&lt;td&gt;TOTAL&lt;/td&gt;<br />&lt;td id=&#8221;total-tournament-duration&#8221;&gt;&lt;?php echo sprintf(&#8216;%02dh %02dm %02ds&#8217;, $hours, $minutes, $seconds); ?&gt;&lt;/td&gt;<br />&lt;/tr&gt;<br />&lt;/table&gt;</p>
<p>&lt;?php if ($current_start) : ?&gt;<br />&lt;script&gt;<br />(function(){<br />const startTimestamp = &lt;?php echo (int)$current_start; ?&gt; * 1000;<br />const durationCell = document.getElementById(&#8216;current-game-duration&#8217;);<br />const totalCell = document.getElementById(&#8216;total-tournament-duration&#8217;);<br />const finishedSeconds = &lt;?php echo (int)$total_seconds &#8211; ($current_start ? (current_time(&#8216;timestamp&#8217;, true) &#8211; $current_start) : 0); ?&gt;;</p>
<p>function updateTimer() {<br />const now = Date.now();<br />let currentSec = Math.floor((now &#8211; startTimestamp) / 1000);</p>
<p>const h = Math.floor(currentSec / 3600);<br />currentSec %= 3600;<br />const m = Math.floor(currentSec / 60);<br />const s = currentSec % 60;</p>
<p>durationCell.textContent = `${h.toString().padStart(2,&#8217;0&#8242;)}h ${m.toString().padStart(2,&#8217;0&#8242;)}m ${s.toString().padStart(2,&#8217;0&#8242;)}s`;</p>
<p>// Update total tournament duration<br />let totalSec = finishedSeconds + Math.floor((now &#8211; startTimestamp) / 1000);<br />const th = Math.floor(totalSec / 3600);<br />totalSec %= 3600;<br />const tm = Math.floor(totalSec / 60);<br />const ts = totalSec % 60;<br />totalCell.textContent = `${th.toString().padStart(2,&#8217;0&#8242;)}h ${tm.toString().padStart(2,&#8217;0&#8242;)}m ${ts.toString().padStart(2,&#8217;0&#8242;)}s`;<br />}</p>
<p>updateTimer();<br />setInterval(updateTimer, 1000);<br />})();<br />&lt;/script&gt;<br />&lt;?php endif;</p>
<p>return ob_get_clean();<br />});</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />ALL TOURNAMENTS LEADERBOARD (Admin Colors Applied)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_wins_all&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />// No meta_query here — all tournaments included<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No tournaments found.&#8217;;</p>
<p>$stats = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$players = get_post_meta(get_the_ID(),&#8217;ts_players&#8217;,true);<br />$games = get_post_meta(get_the_ID(),&#8217;ts_games&#8217;,true);</p>
<p>if(!is_array($players) || !is_array($games)) continue;</p>
<p>// Initialize stats<br />foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;<br />$stats[$name] = $stats[$name] ?? [&#8216;wins&#8217;=&gt;0,&#8217;points&#8217;=&gt;0];<br />}</p>
<p>// Add points<br />foreach ($games as $game) {<br />foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;<br />$score = intval($game[$i] ?? 0);<br />$stats[$name][&#8216;points&#8217;] += $score;<br />}<br />}</p>
<p>// Count wins<br />foreach ($games as $game) {<br />$max_score = max(array_map(&#8216;intval&#8217;, $game));<br />foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;<br />if (intval($game[$i] ?? 0) === $max_score &amp;&amp; $max_score &gt; 0) {<br />$stats[$name][&#8216;wins&#8217;]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($stats)) return &#8216;No stats found.&#8217;;</p>
<p>// Sort players by total points descending<br />uasort($stats, fn($a,$b) =&gt; $b[&#8216;points&#8217;] &lt;=&gt; $a[&#8216;points&#8217;]);</p>
<p>// Build table<br />$out = &#8216;&lt;h3&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" /> All Tournaments Leaderboard&lt;/h3&gt;&#8217;;<br />$out .= &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;</p>
<p>// Header<br />$out .= &#8216;&lt;thead&gt;&lt;tr&gt;<br />&lt;th&gt;Rank&lt;/th&gt;<br />&lt;th&gt;Player&lt;/th&gt;<br />&lt;th&gt;Wins&lt;/th&gt;<br />&lt;th&gt;Total Points&lt;/th&gt;<br />&lt;/tr&gt;&lt;/thead&gt;&#8217;;</p>
<p>// Body<br />$out .= &#8216;&lt;tbody&gt;&#8217;;<br />$rank = 1;<br />foreach ($stats as $player =&gt; $data) {<br />// Add winner class to top player<br />$class = ($rank === 1) ? &#8216;winner&#8217; : &#8221;;<br />$out .= &#8216;&lt;tr class=&#8221;&#8216;.$class.'&#8221;&gt;<br />&lt;td&gt;&#8217;.$rank.'&lt;/td&gt;<br />&lt;td&gt;&#8217;.esc_html($player).'&lt;/td&gt;<br />&lt;td&gt;&#8217;.$data[&#8216;wins&#8217;].'&lt;/td&gt;<br />&lt;td&gt;&#8217;.$data[&#8216;points&#8217;].'&lt;/td&gt;<br />&lt;/tr&gt;&#8217;;<br />$rank++;<br />}<br />$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />LIFETIME HIGHEST POINTS HOLDER (TEAMS ONLY)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_lifetime_points_holder_team&#8217;, function () {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;,<br />&#8216;value&#8217; =&gt; &#8216;teams&#8217;<br />]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No team lifetime scores found.&#8217;;</p>
<p>$totals = [];<br />$games_played = [];<br />$games_won = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$teams = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true); // team names<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($teams) || !is_array($games)) continue;</p>
<p>foreach ($games as $game) {</p>
<p>// Determine winner of this game<br />$max_score = max($game);<br />$winner_index = array_search($max_score, $game, true);</p>
<p>foreach ($teams as $t =&gt; $team_name) {<br />if (!$team_name) continue;</p>
<p>if (!isset($totals[$team_name])) {<br />$totals[$team_name] = 0;<br />$games_played[$team_name] = 0;<br />$games_won[$team_name] = 0;<br />}</p>
<p>$score = intval($game[$t] ?? 0);</p>
<p>// Lifetime points<br />$totals[$team_name] += $score;</p>
<p>// Games played<br />$games_played[$team_name]++;</p>
<p>// Games won<br />if ($t === $winner_index) {<br />$games_won[$team_name]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($totals)) return &#8216;No team lifetime scores found.&#8217;;</p>
<p>// Top team by lifetime points<br />arsort($totals);<br />$top_team = key($totals);<br />$top_score = current($totals);</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />max-width:420px;<br />margin:30px auto;<br />padding:20px;<br />border-radius:14px;<br />background:linear-gradient(135deg,#e8f5e9,#d4edda);<br />border:1px solid #4CAF50;<br />text-align:center;<br />box-shadow:0 6px 14px rgba(0,0,0,0.12);<br />font-family:inherit;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:42px; line-height:1; margin-bottom:12px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:20px; font-weight:bold; margin-bottom:18px;&#8221;&gt;<br />Total Overall Points<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;<br />font-size:18px;<br />font-weight:bold;<br />margin-bottom:12px;<br />border-bottom:1px solid #c8e6c9;<br />padding-bottom:6px;<br />&#8220;&gt;<br />&#8216;.esc_html($top_team).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:16px; margin-bottom:6px;&#8221;&gt;<br />Total Points: &lt;strong&gt;&#8217;.intval($top_score).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; margin-bottom:4px;&#8221;&gt;<br />Games Played: &lt;strong&gt;&#8217;.intval($games_played[$top_team]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px;&#8221;&gt;<br />Games Won: &lt;strong&gt;&#8217;.intval($games_won[$top_team]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:12px; color:#000; margin-top:8px;&#8221;&gt;<br />&lt;b&gt;Team Tournaments Only&lt;/b&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />Teams Tournament History Leaderboard<br />&#8211; Ordered by tournament date<br />&#8211; Winner highlighted with trophy<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_teams_history&#8217;, function() {</p>
<p>// Table styles<br />$s = get_option(&#8216;ts_table_styles&#8217;, []);<br />$s = wp_parse_args($s, [<br />&#8216;header_bg&#8217; =&gt; &#8216;#4CAF50&#8217;,<br />&#8216;header_text&#8217; =&gt; &#8216;#ffffff&#8217;,<br />&#8216;row_even&#8217; =&gt; &#8216;#f2f2f2&#8217;,<br />&#8216;row_odd&#8217; =&gt; &#8216;#ffffff&#8217;,<br />&#8216;table_text&#8217; =&gt; &#8216;#000000&#8217;,<br />&#8216;winner_bg&#8217; =&gt; &#8216;#ffeb3b&#8217;, // Highlight winner row<br />&#8216;winner_text&#8217; =&gt; &#8216;#000000&#8217;<br />]);</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;teams&#8217;],<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />],<br />&#8216;orderby&#8217; =&gt; &#8216;date&#8217;,<br />&#8216;order&#8217; =&gt; &#8216;DESC&#8217; // latest tournament first<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished team tournaments found.&#8217;;</p>
<p>$records = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$tournament_id = get_the_ID();<br />$tournament_name = get_the_title();<br />$tournament_link = get_permalink($tournament_id);</p>
<p>$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games) || empty($games)) continue;</p>
<p>// Split players into teams (A/B)<br />$teams = [&#8216;A&#8217;=&gt;[], &#8216;B&#8217;=&gt;[]];<br />foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;<br />$teams[($i % 2 === 0) ? &#8216;A&#8217; : &#8216;B&#8217;][] = $i;<br />}</p>
<p>// Calculate points and wins for each team<br />$team_stats = [];<br />foreach ([&#8216;A&#8217;,&#8217;B&#8217;] as $team_name) {<br />$indexes = $teams[$team_name];<br />$wins = 0;<br />$points = 0;</p>
<p>foreach ($games as $game) {<br />$score = 0;<br />foreach ($indexes as $i) {<br />$score += intval($game[$i] ?? 0);<br />}<br />$points += $score;</p>
<p>$other_team = $team_name === &#8216;A&#8217; ? &#8216;B&#8217; : &#8216;A&#8217;;<br />$other_score = 0;<br />foreach ($teams[$other_team] as $i) {<br />$other_score += intval($game[$i] ?? 0);<br />}<br />if ($score &gt; $other_score) $wins++;<br />}</p>
<p>$team_stats[$team_name] = [<br />&#8216;team&#8217; =&gt; $team_name,<br />&#8216;players&#8217; =&gt; array_map(fn($i)=&gt;$players[$i], $indexes),<br />&#8216;wins&#8217; =&gt; $wins,<br />&#8216;points&#8217; =&gt; $points<br />];<br />}</p>
<p>// Determine winner (higher points)<br />$winner_team = $team_stats[&#8216;A&#8217;][&#8216;points&#8217;] &gt;= $team_stats[&#8216;B&#8217;][&#8216;points&#8217;] ? &#8216;A&#8217; : &#8216;B&#8217;;</p>
<p>// Add to records<br />foreach ([&#8216;A&#8217;,&#8217;B&#8217;] as $team_name) {<br />$team = $team_stats[$team_name];<br />$team[&#8216;winner&#8217;] = ($team_name === $winner_team);<br />$team[&#8216;tournament&#8217;] = $tournament_name;<br />$team[&#8216;tournament_link&#8217;] = $tournament_link;<br />$records[] = $team;<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($records)) return &#8216;No team records found.&#8217;;</p>
<p>// Build table<br />$out = &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;thead&gt;&#8217;;<br />$out .= &#8216;&lt;tr style=&#8221;background:&#8217;.$s[&#8216;header_bg&#8217;].&#8217;;color:&#8217;.$s[&#8216;header_text&#8217;].&#8217;;&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;th&gt;Tournament&lt;/th&gt;&lt;th&gt;Team&lt;/th&gt;&lt;th&gt;Players&lt;/th&gt;&lt;th&gt;Wins&lt;/th&gt;&lt;th&gt;Total Points&lt;/th&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;<br />$out .= &#8216;&lt;/thead&gt;&lt;tbody&gt;&#8217;;</p>
<p>$row = 0;<br />foreach ($records as $r) {<br />// Highlight winner row<br />$row_bg = $r[&#8216;winner&#8217;] ? $s[&#8216;winner_bg&#8217;] : (($row % 2 === 0) ? $s[&#8216;row_even&#8217;] : $s[&#8216;row_odd&#8217;]);<br />$row_color = $r[&#8216;winner&#8217;] ? $s[&#8216;winner_text&#8217;] : $s[&#8216;table_text&#8217;];</p>
<p>$team_display = &#8216;Team &#8216;.$r[&#8216;team&#8217;];<br />if ($r[&#8216;winner&#8217;]) $team_display .= &#8216; <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217;; // Trophy for winner</p>
<p>$out .= &#8216;&lt;tr style=&#8221;background:&#8217;.$row_bg.&#8217;;color:&#8217;.$row_color.'&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&lt;a href=&#8221;&#8216;.esc_url($r[&#8216;tournament_link&#8217;]).'&#8221;&gt;&#8217;.esc_html($r[&#8216;tournament&#8217;]).'&lt;/a&gt;&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.esc_html($team_display).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.esc_html(implode(&#8216;, &#8216;,$r[&#8216;players&#8217;])).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.$r[&#8216;wins&#8217;].'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.$r[&#8216;points&#8217;].'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;</p>
<p>$row++;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CURRENT HIGHEST SCORE HOLDER (ALL MODES)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_highest_overall&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;,<br />&#8216;value&#8217; =&gt; 1<br />]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) {<br />return &#8216;No finished tournaments found.&#8217;;<br />}</p>
<p>$highest_score = 0;<br />$holder = [<br />&#8216;player&#8217; =&gt; &#8221;,<br />&#8216;score&#8217; =&gt; 0,<br />&#8216;tournament&#8217; =&gt; &#8221;,<br />&#8216;tournament_url&#8217; =&gt; &#8221;,<br />&#8216;game&#8217; =&gt; 0,<br />&#8216;mode&#8217; =&gt; &#8221;<br />];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$tournament_id = get_the_ID();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);<br />$mode = get_post_meta($tournament_id, &#8216;ts_mode&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />if (!is_array($game)) continue;</p>
<p>foreach ($game as $p =&gt; $score) {<br />$score = intval($score);<br />if ($score &lt;= 0) continue;</p>
<p>$player_name = $players[$p] ?? &#8216;Unknown&#8217;;</p>
<p>if ($score &gt; $highest_score) {<br />$highest_score = $score;<br />$holder = [<br />&#8216;player&#8217; =&gt; $player_name,<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; get_the_title(),<br />&#8216;tournament_url&#8217; =&gt; get_permalink(),<br />&#8216;game&#8217; =&gt; $g + 1,<br />&#8216;mode&#8217; =&gt; ucfirst($mode)<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if ($highest_score === 0) {<br />return &#8216;No game scores found yet.&#8217;;<br />}</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />border:1px solid #4CAF50;<br />padding:14px;<br />background:#d4edda;<br />border-radius:10px;<br />max-width:420px;<br />margin:20px auto;<br />text-align:center;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:36px; margin-bottom:10px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;strong&gt;Highest Score (All Modes)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;</p>
<p>&lt;div style=&#8221;font-size:18px; font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;player&#8217;]).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Score: &lt;strong&gt;&#8217;.intval($holder[&#8216;score&#8217;]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Game: &#8216;.$holder[&#8216;game&#8217;].'&lt;br&gt;<br />Mode: &#8216;.$holder[&#8216;mode&#8217;].&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:8px;&#8221;&gt;<br />Tournament:&lt;br&gt;<br />&lt;a href=&#8221;&#8216;.esc_url($holder[&#8216;tournament_url&#8217;]).'&#8221; style=&#8221;font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;tournament&#8217;]).&#8217;<br />&lt;/a&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CURRENT LOWEST SCORE HOLDER (ALL MODES, INCLUDING NEGATIVES)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_lowest_overall&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[<br />&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;,<br />&#8216;value&#8217; =&gt; 1<br />]<br />]<br />]);</p>
<p>if (!$query-&gt;have_posts()) {<br />return &#8216;No finished tournaments found.&#8217;;<br />}</p>
<p>$lowest_score = null;<br />$holder = [<br />&#8216;player&#8217; =&gt; &#8221;,<br />&#8216;score&#8217; =&gt; 0,<br />&#8216;tournament&#8217; =&gt; &#8221;,<br />&#8216;tournament_url&#8217; =&gt; &#8221;,<br />&#8216;game&#8217; =&gt; 0,<br />&#8216;mode&#8217; =&gt; &#8221;<br />];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$tournament_id = get_the_ID();<br />$players = get_post_meta($tournament_id, &#8216;ts_players&#8217;, true);<br />$games = get_post_meta($tournament_id, &#8216;ts_games&#8217;, true);<br />$mode = get_post_meta($tournament_id, &#8216;ts_mode&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $g =&gt; $game) {<br />if (!is_array($game)) continue;</p>
<p>foreach ($game as $p =&gt; $raw_score) {</p>
<p>// Skip empty/missing scores<br />if ($raw_score === null || $raw_score === &#8221;) continue;</p>
<p>$score = intval($raw_score);<br />$player_name = $players[$p] ?? &#8216;Unknown&#8217;;</p>
<p>// Update lowest score if this score is smaller<br />if ($lowest_score === null || $score &lt; $lowest_score) {<br />$lowest_score = $score;<br />$holder = [<br />&#8216;player&#8217; =&gt; $player_name,<br />&#8216;score&#8217; =&gt; $score,<br />&#8216;tournament&#8217; =&gt; get_the_title(),<br />&#8216;tournament_url&#8217; =&gt; get_permalink(),<br />&#8216;game&#8217; =&gt; $g + 1,<br />&#8216;mode&#8217; =&gt; ucfirst($mode)<br />];<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if ($lowest_score === null) {<br />return &#8216;No valid game scores found yet.&#8217;;<br />}</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />border:1px solid #f44336;<br />padding:14px;<br />background:#fdecea;<br />border-radius:10px;<br />max-width:420px;<br />margin:20px auto;<br />text-align:center;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:36px; margin-bottom:10px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f7e5.png" alt="🟥" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;strong&gt;Lowest Score (All Modes)&lt;/strong&gt;&lt;br&gt;&lt;br&gt;</p>
<p>&lt;div style=&#8221;font-size:18px; font-weight:bold;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;player&#8217;]).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Score: &lt;strong&gt;&#8217;.intval($holder[&#8216;score&#8217;]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:6px;&#8221;&gt;<br />Game: &#8216;.$holder[&#8216;game&#8217;].'&lt;br&gt;<br />Mode: &#8216;.$holder[&#8216;mode&#8217;].&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;margin-top:8px;&#8221;&gt;<br />Tournament:&lt;br&gt;<br />&lt;a href=&#8221;&#8216;.esc_url($holder[&#8216;tournament_url&#8217;]).'&#8221; style=&#8221;font-weight:bold; color:#c62828;&#8221;&gt;<br />&#8216;.esc_html($holder[&#8216;tournament&#8217;]).&#8217;<br />&lt;/a&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />LIFETIME HIGHEST POINTS HOLDER (ALL MODES)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_lifetime_points_holder_overall&#8217;, function () {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />// Removed ts_mode filter to include all modes<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No lifetime scores found.&#8217;;</p>
<p>$totals = [];<br />$games_played = [];<br />$games_won = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>foreach ($games as $game_index =&gt; $game) {<br />if (!is_array($game)) continue;</p>
<p>// Determine winner(s) of this game (allow ties)<br />$max_score = max(array_map(&#8216;intval&#8217;, $game));<br />$winner_indices = [];<br />foreach ($game as $p =&gt; $score) {<br />if (intval($score) === $max_score) $winner_indices[] = $p;<br />}</p>
<p>foreach ($players as $p =&gt; $name) {<br />if (!$name) continue;</p>
<p>if (!isset($totals[$name])) {<br />$totals[$name] = 0;<br />$games_played[$name] = 0;<br />$games_won[$name] = 0;<br />}</p>
<p>$score = intval($game[$p] ?? 0);</p>
<p>// Lifetime points<br />$totals[$name] += $score;</p>
<p>// Games played<br />$games_played[$name]++;</p>
<p>// Games won (handle ties)<br />if (in_array($p, $winner_indices, true)) {<br />$games_won[$name]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($totals)) return &#8216;No lifetime scores found.&#8217;;</p>
<p>// Top overall scorer<br />arsort($totals);<br />$top_player = key($totals);<br />$top_score = current($totals);</p>
<p>return &#8216;<br />&lt;div style=&#8221;<br />max-width:420px;<br />margin:30px auto;<br />padding:20px;<br />border-radius:14px;<br />background:linear-gradient(135deg,#e8f5e9,#d4edda);<br />border:1px solid #4CAF50;<br />text-align:center;<br />box-shadow:0 6px 14px rgba(0,0,0,0.12);<br />font-family:inherit;<br />&#8220;&gt;<br />&lt;div style=&#8221;font-size:42px; line-height:1; margin-bottom:12px;&#8221;&gt;<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:20px; font-weight:bold; margin-bottom:18px;&#8221;&gt;<br />Total Overall Points<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;<br />font-size:18px;<br />font-weight:bold;<br />margin-bottom:12px;<br />border-bottom:1px solid #c8e6c9;<br />padding-bottom:6px;<br />&#8220;&gt;<br />&#8216;.esc_html($top_player).&#8217;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:16px; margin-bottom:6px;&#8221;&gt;<br />Total Points: &lt;strong&gt;&#8217;.intval($top_score).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px; margin-bottom:4px;&#8221;&gt;<br />Games Played: &lt;strong&gt;&#8217;.intval($games_played[$top_player]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:14px;&#8221;&gt;<br />Games Won: &lt;strong&gt;&#8217;.intval($games_won[$top_player]).'&lt;/strong&gt;<br />&lt;/div&gt;</p>
<p>&lt;div style=&#8221;font-size:12px; color:#000; margin-top:8px;&#8221;&gt;<br />&lt;b&gt;All Tournament Modes Included&lt;/b&gt;<br />&lt;/div&gt;<br />&lt;/div&gt;&#8217;;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />ALL TOURNAMENTS SLIDER &#8211; SAME HEIGHT CARDS<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;all_tournaments_slider&#8217;, function () {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;orderby&#8217; =&gt; &#8216;date&#8217;,<br />&#8216;order&#8217; =&gt; &#8216;DESC&#8217;,<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No tournaments found.&#8217;;</p>
<p>ob_start();<br />?&gt;</p>
<p>&lt;div class=&#8221;swiper all-tournaments-slider&#8221;&gt;<br />&lt;div class=&#8221;swiper-wrapper&#8221;&gt;</p>
<p>&lt;?php while ($query-&gt;have_posts()) : $query-&gt;the_post();</p>
<p>$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true) ?: [];<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true) ?: [];</p>
<p>/* &#8212;&#8212;&#8211; TOTAL POINTS &#8212;&#8212;&#8211; */<br />$totals = array_fill(0, count($players), 0);<br />foreach ($games as $game) {<br />foreach ($game as $p =&gt; $score) {<br />$totals[$p] += intval($score);<br />}<br />}<br />$max_score = !empty($totals) ? max($totals) : 0;</p>
<p>/* &#8212;&#8212;&#8211; TOTAL GAMES &#8212;&#8212;&#8211; */<br />$total_games = is_array($games) ? count($games) : 0;</p>
<p>/* &#8212;&#8212;&#8211; TOTAL TIME &#8212;&#8212;&#8211; */<br />$game_starts = get_post_meta(get_the_ID(), &#8216;ts_game_starts&#8217;, true) ?: [];<br />$game_ends = get_post_meta(get_the_ID(), &#8216;ts_game_ends&#8217;, true) ?: [];<br />$current_start = get_post_meta(get_the_ID(), &#8216;ts_current_game_start&#8217;, true);</p>
<p>$total_seconds = 0;<br />foreach ($game_starts as $i =&gt; $start) {<br />$end = $game_ends[$i] ?? $start;<br />if ($end &gt; $start) $total_seconds += ($end &#8211; $start);<br />}<br />if ($current_start) {<br />$total_seconds += (current_time(&#8216;timestamp&#8217;, true) &#8211; $current_start);<br />}</p>
<p>$hours = floor($total_seconds / 3600);<br />$minutes = floor(($total_seconds % 3600) / 60);<br />$seconds = $total_seconds % 60;<br />$duration = sprintf(&#8216;%02dh %02dm %02ds&#8217;, $hours, $minutes, $seconds);</p>
<p>$is_finished = get_post_meta(get_the_ID(), &#8216;ts_finished&#8217;, true);<br />?&gt;</p>
<p>&lt;div class=&#8221;swiper-slide&#8221;&gt;<br />&lt;div class=&#8221;tournament-card&#8221;&gt;</p>
<p>&lt;div class=&#8221;card-header&#8221;&gt;<br />&lt;?php if ($is_finished): ?&gt;<br />&lt;span class=&#8221;badge finished-badge&#8221;&gt;Finished&lt;/span&gt;<br />&lt;?php endif; ?&gt;<br />&lt;h3&gt;<br />&lt;a href=&#8221;&lt;?php the_permalink(); ?&gt;&#8221;&gt;&lt;?php the_title(); ?&gt;&lt;/a&gt;<br />&lt;/h3&gt;<br />&lt;/div&gt;</p>
<p>&lt;?php if (!empty($players)): ?&gt;<br />&lt;table class=&#8221;score-table&#8221;&gt;<br />&lt;?php foreach ($players as $p =&gt; $name):<br />if (!$name) continue;<br />$highlight = ($totals[$p] === $max_score &amp;&amp; $max_score &gt; 0) ? &#8216;top-scorer&#8217; : &#8221;;<br />?&gt;<br />&lt;tr class=&#8221;&lt;?php echo esc_attr($highlight); ?&gt;&#8221;&gt;<br />&lt;td&gt;&lt;?php echo esc_html($name); ?&gt;&lt;/td&gt;<br />&lt;td class=&#8221;points&#8221;&gt;&lt;?php echo intval($totals[$p]); ?&gt;&lt;/td&gt;<br />&lt;/tr&gt;<br />&lt;?php endforeach; ?&gt;<br />&lt;/table&gt;<br />&lt;?php endif; ?&gt;</p>
<p>&lt;div class=&#8221;tournament-meta&#8221;&gt;<br />&lt;div&gt;&lt;strong&gt;Games Played:&lt;/strong&gt; &lt;?php echo intval($total_games); ?&gt;&lt;/div&gt;<br />&lt;div&gt;&lt;strong&gt;Total Time:&lt;/strong&gt; &lt;?php echo esc_html($duration); ?&gt;&lt;/div&gt;<br />&lt;/div&gt;</p>
<p>&lt;a href=&#8221;&lt;?php the_permalink(); ?&gt;&#8221; class=&#8221;view-tournament-btn&#8221;&gt;<br />View Tournament<br />&lt;/a&gt;</p>
<p>&lt;/div&gt;<br />&lt;/div&gt;</p>
<p>&lt;?php endwhile; wp_reset_postdata(); ?&gt;</p>
<p>&lt;/div&gt;<br />&lt;/div&gt;</p>
<p>&lt;style&gt;<br />.all-tournaments-slider { width: 100%; }</p>
<p>.swiper-slide { display: flex; height: auto; }<br />.tournament-card {<br />flex: 1; /* Equal width + height */<br />display: flex;<br />flex-direction: column;<br />align-items: center;<br />text-align: center;<br />padding: 16px;<br />background: #fff;<br />border-radius: 12px;<br />border: 1px solid #ddd;<br />box-shadow: 0 4px 8px rgba(0,0,0,0.08);<br />}</p>
<p>.card-header { margin-bottom: 10px; }<br />.card-header h3 { margin: 6px 0 0; font-size: 16px; }</p>
<p>.score-table {<br />width: 100%;<br />border-collapse: collapse;<br />margin: 8px 0;<br />text-align: center;<br />}</p>
<p>.score-table td { padding: 4px 0; }<br />.score-table .points { text-align: center; }</p>
<p>.top-scorer { font-weight: bold; color: #e53935; }</p>
<p>.tournament-meta {<br />margin-top: auto;<br />font-size: 13px;<br />color: #444;<br />padding-top: 8px;<br />}<br />.tournament-meta div { line-height: 1.4; }</p>
<p>.badge {<br />display: inline-block;<br />font-size: 11px;<br />padding: 3px 6px;<br />border-radius: 4px;<br />color: #fff;<br />}<br />.finished-badge { background: #4CAF50; }</p>
<p>.view-tournament-btn {<br />margin-top: 10px;<br />text-align: center;<br />padding: 8px;<br />background: #4CAF50;<br />color: #fff;<br />border-radius: 6px;<br />text-decoration: none;<br />font-weight: bold;<br />}<br />&lt;/style&gt;</p>
<p>&lt;link rel=&#8221;stylesheet&#8221; href=&#8221;https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css&#8221;&gt;<br />&lt;script src=&#8221;https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js&#8221;&gt;&lt;/script&gt;</p>
<p>&lt;script&gt;<br />document.addEventListener(&#8220;DOMContentLoaded&#8221;, function () {<br />new Swiper(&#8220;.all-tournaments-slider&#8221;, {<br />slidesPerView: 1,<br />slidesPerGroup: 1,<br />spaceBetween: 16,<br />loop: false,<br />observer: true,<br />observeParents: true,<br />breakpoints: {<br />768: { slidesPerView: 2 },<br />1024: { slidesPerView: 3 },<br />1200: { slidesPerView: 4 }<br />}<br />});<br />});<br />&lt;/script&gt;</p>
<p>&lt;?php<br />return ob_get_clean();<br />});</p>
<p>&nbsp;</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />CATEGORY TOURNAMENTS SLIDER &#8211; SAME HEIGHT CARDS<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;category_tournaments_slider&#8217;, function ($atts) {</p>
<p>if (empty($atts[&#8216;category&#8217;])) {<br />return &#8216;Please provide a category slug using category=&#8221;slug&#8221;.&#8217;;<br />}<br />$category_slug = sanitize_text_field($atts[&#8216;category&#8217;]);</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;orderby&#8217; =&gt; &#8216;date&#8217;,<br />&#8216;order&#8217; =&gt; &#8216;DESC&#8217;,<br />&#8216;tax_query&#8217; =&gt; [<br />[<br />&#8216;taxonomy&#8217; =&gt; &#8216;tournament_category&#8217;,<br />&#8216;field&#8217; =&gt; &#8216;slug&#8217;,<br />&#8216;terms&#8217; =&gt; $category_slug,<br />]<br />],<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No tournaments found in this category.&#8217;;</p>
<p>ob_start();<br />?&gt;</p>
<p>&lt;div class=&#8221;swiper category-tournaments-slider&#8221;&gt;<br />&lt;div class=&#8221;swiper-wrapper&#8221;&gt;</p>
<p>&lt;?php while ($query-&gt;have_posts()) : $query-&gt;the_post();</p>
<p>$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true) ?: [];<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true) ?: [];</p>
<p>/* &#8212;&#8212;&#8211; TOTAL POINTS &#8212;&#8212;&#8211; */<br />$totals = array_fill(0, count($players), 0);<br />foreach ($games as $game) {<br />foreach ($game as $p =&gt; $score) {<br />$totals[$p] += intval($score);<br />}<br />}<br />$max_score = !empty($totals) ? max($totals) : 0;</p>
<p>/* &#8212;&#8212;&#8211; TOTAL GAMES &#8212;&#8212;&#8211; */<br />$total_games = is_array($games) ? count($games) : 0;</p>
<p>/* &#8212;&#8212;&#8211; TOTAL TIME &#8212;&#8212;&#8211; */<br />$game_starts = get_post_meta(get_the_ID(), &#8216;ts_game_starts&#8217;, true) ?: [];<br />$game_ends = get_post_meta(get_the_ID(), &#8216;ts_game_ends&#8217;, true) ?: [];<br />$current_start = get_post_meta(get_the_ID(), &#8216;ts_current_game_start&#8217;, true);</p>
<p>$total_seconds = 0;<br />foreach ($game_starts as $i =&gt; $start) {<br />$end = $game_ends[$i] ?? $start;<br />if ($end &gt; $start) $total_seconds += ($end &#8211; $start);<br />}<br />if ($current_start) {<br />$total_seconds += (current_time(&#8216;timestamp&#8217;, true) &#8211; $current_start);<br />}</p>
<p>$hours = floor($total_seconds / 3600);<br />$minutes = floor(($total_seconds % 3600) / 60);<br />$seconds = $total_seconds % 60;<br />$duration = sprintf(&#8216;%02dh %02dm %02ds&#8217;, $hours, $minutes, $seconds);</p>
<p>$is_finished = get_post_meta(get_the_ID(), &#8216;ts_finished&#8217;, true);<br />?&gt;</p>
<p>&lt;div class=&#8221;swiper-slide&#8221;&gt;<br />&lt;div class=&#8221;tournament-card&#8221;&gt;</p>
<p>&lt;div class=&#8221;card-header&#8221;&gt;<br />&lt;?php if ($is_finished): ?&gt;<br />&lt;span class=&#8221;badge finished-badge&#8221;&gt;Finished&lt;/span&gt;<br />&lt;?php endif; ?&gt;<br />&lt;h3&gt;<br />&lt;a href=&#8221;&lt;?php the_permalink(); ?&gt;&#8221;&gt;&lt;?php the_title(); ?&gt;&lt;/a&gt;<br />&lt;/h3&gt;<br />&lt;/div&gt;</p>
<p>&lt;?php if (!empty($players)): ?&gt;<br />&lt;table class=&#8221;score-table&#8221;&gt;<br />&lt;?php foreach ($players as $p =&gt; $name):<br />if (!$name) continue;<br />$highlight = ($totals[$p] === $max_score &amp;&amp; $max_score &gt; 0) ? &#8216;top-scorer&#8217; : &#8221;;<br />?&gt;<br />&lt;tr class=&#8221;&lt;?php echo esc_attr($highlight); ?&gt;&#8221;&gt;<br />&lt;td&gt;&lt;?php echo esc_html($name); ?&gt;&lt;/td&gt;<br />&lt;td class=&#8221;points&#8221;&gt;&lt;?php echo intval($totals[$p]); ?&gt;&lt;/td&gt;<br />&lt;/tr&gt;<br />&lt;?php endforeach; ?&gt;<br />&lt;/table&gt;<br />&lt;?php endif; ?&gt;</p>
<p>&lt;div class=&#8221;tournament-meta&#8221;&gt;<br />&lt;div&gt;&lt;strong&gt;Games Played:&lt;/strong&gt; &lt;?php echo intval($total_games); ?&gt;&lt;/div&gt;<br />&lt;div&gt;&lt;strong&gt;Total Time:&lt;/strong&gt; &lt;?php echo esc_html($duration); ?&gt;&lt;/div&gt;<br />&lt;/div&gt;</p>
<p>&lt;a href=&#8221;&lt;?php the_permalink(); ?&gt;&#8221; class=&#8221;view-tournament-btn&#8221;&gt;<br />View Tournament<br />&lt;/a&gt;</p>
<p>&lt;/div&gt;<br />&lt;/div&gt;</p>
<p>&lt;?php endwhile; wp_reset_postdata(); ?&gt;</p>
<p>&lt;/div&gt;<br />&lt;/div&gt;</p>
<p>&lt;style&gt;<br />.category-tournaments-slider { width: 100%; }</p>
<p>.swiper-slide { display: flex; height: auto; }<br />.tournament-card {<br />flex: 1; <br />display: flex;<br />flex-direction: column;<br />align-items: center;<br />text-align: center;<br />padding: 16px;<br />background: #fff;<br />border-radius: 12px;<br />border: 1px solid #ddd;<br />box-shadow: 0 4px 8px rgba(0,0,0,0.08);<br />}</p>
<p>.card-header { margin-bottom: 10px; }<br />.card-header h3 { margin: 6px 0 0; font-size: 16px; }</p>
<p>.score-table {<br />width: 100%;<br />border-collapse: collapse;<br />margin: 8px 0;<br />text-align: center;<br />}</p>
<p>.score-table td { padding: 4px 0; }<br />.score-table .points { text-align: center; }</p>
<p>.top-scorer { font-weight: bold; color: #e53935; }</p>
<p>.tournament-meta {<br />margin-top: auto;<br />font-size: 13px;<br />color: #444;<br />padding-top: 8px;<br />}<br />.tournament-meta div { line-height: 1.4; }</p>
<p>.badge {<br />display: inline-block;<br />font-size: 11px;<br />padding: 3px 6px;<br />border-radius: 4px;<br />color: #fff;<br />}<br />.finished-badge { background: #4CAF50; }</p>
<p>.view-tournament-btn {<br />margin-top: 10px;<br />text-align: center;<br />padding: 8px;<br />background: #4CAF50;<br />color: #fff;<br />border-radius: 6px;<br />text-decoration: none;<br />font-weight: bold;<br />}<br />&lt;/style&gt;</p>
<p>&lt;link rel=&#8221;stylesheet&#8221; href=&#8221;https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.css&#8221;&gt;<br />&lt;script src=&#8221;https://cdn.jsdelivr.net/npm/swiper@10/swiper-bundle.min.js&#8221;&gt;&lt;/script&gt;</p>
<p>&lt;script&gt;<br />document.addEventListener(&#8220;DOMContentLoaded&#8221;, function () {<br />new Swiper(&#8220;.category-tournaments-slider&#8221;, {<br />slidesPerView: 1,<br />slidesPerGroup: 1,<br />spaceBetween: 16,<br />loop: false,<br />observer: true,<br />observeParents: true,<br />breakpoints: {<br />768: { slidesPerView: 2 },<br />1024: { slidesPerView: 3 },<br />1200: { slidesPerView: 4 }<br />}<br />});<br />});<br />&lt;/script&gt;</p>
<p>&lt;?php<br />return ob_get_clean();<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />Teams Overall Stats (Wins / Points / Games Played)<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_teams_stats&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;teams&#8217;],<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />],<br />&#8216;orderby&#8217; =&gt; &#8216;date&#8217;,<br />&#8216;order&#8217; =&gt; &#8216;ASC&#8217;<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished team tournaments found.&#8217;;</p>
<p>$teams = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$players = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($players) || !is_array($games)) continue;</p>
<p>// Split into Team A / Team B<br />$team_indexes = [&#8216;A&#8217;=&gt;[], &#8216;B&#8217;=&gt;[]];<br />foreach ($players as $i =&gt; $name) {<br />if (!$name) continue;<br />$team_indexes[($i % 2 === 0) ? &#8216;A&#8217; : &#8216;B&#8217;][] = $i;<br />}</p>
<p>foreach ($games as $game) {</p>
<p>$scores = [];</p>
<p>foreach ($team_indexes as $team =&gt; $indexes) {</p>
<p>if (!isset($teams[$team])) {<br />$teams[$team] = [<br />&#8216;games&#8217; =&gt; 0,<br />&#8216;wins&#8217; =&gt; 0,<br />&#8216;points&#8217; =&gt; 0<br />];<br />}</p>
<p>$score = 0;<br />foreach ($indexes as $i) {<br />$score += intval($game[$i] ?? 0);<br />}</p>
<p>$teams[$team][&#8216;games&#8217;]++;<br />$teams[$team][&#8216;points&#8217;] += $score;<br />$scores[$team] = $score;<br />}</p>
<p>// Assign win<br />$max = max($scores);<br />if ($max &gt; 0) {<br />foreach ($scores as $team =&gt; $score) {<br />if ($score === $max) {<br />$teams[$team][&#8216;wins&#8217;]++;<br />}<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($teams)) return &#8216;No team stats found.&#8217;;</p>
<p>// Sort by wins, then points<br />uasort($teams, function($a, $b) {<br />return [$b[&#8216;wins&#8217;], $b[&#8216;points&#8217;]] &lt;=&gt; [$a[&#8216;wins&#8217;], $a[&#8216;points&#8217;]];<br />});</p>
<p>// Output table<br />$out = &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;thead&gt;&lt;tr&gt;&#8217;;<br />$out .= &#8216;&lt;th&gt;Team&lt;/th&gt;&#8217;;<br />$out .= &#8216;&lt;th&gt;Games Played&lt;/th&gt;&#8217;;<br />$out .= &#8216;&lt;th&gt;Wins&lt;/th&gt;&#8217;;<br />$out .= &#8216;&lt;th&gt;Total Points&lt;/th&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&#8217;;</p>
<p>foreach ($teams as $team =&gt; $data) {<br />$out .= &#8216;&lt;tr&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;Team &#8216;.esc_html($team).'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.$data[&#8216;games&#8217;].'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.$data[&#8216;wins&#8217;].'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.$data[&#8216;points&#8217;].'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
<p>/* &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />Individual Player Stats (Teams Mode Only)<br />&#8211; Trophy + Highlight for Top Player<br />&#8211; NO LINKS<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212; */<br />add_shortcode(&#8216;tournament_team_player_stats&#8217;, function() {</p>
<p>$query = new WP_Query([<br />&#8216;post_type&#8217; =&gt; &#8216;tournament&#8217;,<br />&#8216;posts_per_page&#8217; =&gt; -1,<br />&#8216;post_status&#8217; =&gt; &#8216;publish&#8217;,<br />&#8216;meta_query&#8217; =&gt; [<br />[&#8216;key&#8217; =&gt; &#8216;ts_mode&#8217;, &#8216;value&#8217; =&gt; &#8216;teams&#8217;],<br />[&#8216;key&#8217; =&gt; &#8216;ts_finished&#8217;, &#8216;value&#8217; =&gt; 1]<br />],<br />&#8216;orderby&#8217; =&gt; &#8216;date&#8217;,<br />&#8216;order&#8217; =&gt; &#8216;ASC&#8217;<br />]);</p>
<p>if (!$query-&gt;have_posts()) return &#8216;No finished team tournaments found.&#8217;;</p>
<p>$players = [];</p>
<p>while ($query-&gt;have_posts()) {<br />$query-&gt;the_post();</p>
<p>$player_names = get_post_meta(get_the_ID(), &#8216;ts_players&#8217;, true);<br />$games = get_post_meta(get_the_ID(), &#8216;ts_games&#8217;, true);</p>
<p>if (!is_array($player_names) || !is_array($games)) continue;</p>
<p>// Assign players to teams<br />$player_team = [];<br />foreach ($player_names as $i =&gt; $name) {<br />if (!$name) continue;</p>
<p>$player_team[$i] = ($i % 2 === 0) ? &#8216;A&#8217; : &#8216;B&#8217;;</p>
<p>if (!isset($players[$name])) {<br />$players[$name] = [<br />&#8216;games&#8217; =&gt; 0,<br />&#8216;wins&#8217; =&gt; 0,<br />&#8216;points&#8217; =&gt; 0<br />];<br />}<br />}</p>
<p>foreach ($games as $game) {</p>
<p>$team_scores = [&#8216;A&#8217; =&gt; 0, &#8216;B&#8217; =&gt; 0];</p>
<p>foreach ($player_team as $i =&gt; $team) {<br />$team_scores[$team] += intval($game[$i] ?? 0);<br />}</p>
<p>$winning_team = null;<br />if ($team_scores[&#8216;A&#8217;] !== $team_scores[&#8216;B&#8217;]) {<br />$winning_team = ($team_scores[&#8216;A&#8217;] &gt; $team_scores[&#8216;B&#8217;]) ? &#8216;A&#8217; : &#8216;B&#8217;;<br />}</p>
<p>foreach ($player_team as $i =&gt; $team) {<br />$name = $player_names[$i];<br />$score = intval($game[$i] ?? 0);</p>
<p>$players[$name][&#8216;games&#8217;]++;<br />$players[$name][&#8216;points&#8217;] += $score;</p>
<p>if ($winning_team &amp;&amp; $team === $winning_team) {<br />$players[$name][&#8216;wins&#8217;]++;<br />}<br />}<br />}<br />}</p>
<p>wp_reset_postdata();</p>
<p>if (empty($players)) return &#8216;No player stats found.&#8217;;</p>
<p>// Sort by wins, then points<br />uasort($players, fn($a, $b) =&gt; [$b[&#8216;wins&#8217;], $b[&#8216;points&#8217;]] &lt;=&gt; [$a[&#8216;wins&#8217;], $a[&#8216;points&#8217;]]);</p>
<p>// Top player<br />$top_player = array_key_first($players);</p>
<p>// Output table<br />$out = &#8216;&lt;table class=&#8221;tournament-table&#8221;&gt;&#8217;;<br />$out .= &#8216;&lt;thead&gt;&lt;tr&gt;&#8217;;<br />$out .= &#8216;&lt;th&gt;Player&lt;/th&gt;&#8217;;<br />$out .= &#8216;&lt;th&gt;Games Played&lt;/th&gt;&#8217;;<br />$out .= &#8216;&lt;th&gt;Wins&lt;/th&gt;&#8217;;<br />$out .= &#8216;&lt;th&gt;Total Points&lt;/th&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&#8217;;</p>
<p>foreach ($players as $name =&gt; $data) {</p>
<p>$is_top = ($name === $top_player);</p>
<p>$row_style = $is_top<br />? &#8216; style=&#8221;background:#fff3cd;font-weight:bold;&#8221;&#8216;<br />: &#8221;;</p>
<p>$trophy = $is_top ? &#8216; <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3c6.png" alt="🏆" class="wp-smiley" style="height: 1em; max-height: 1em;" />&#8217; : &#8221;;</p>
<p>$out .= &#8216;&lt;tr&#8217;.$row_style.&#8217;&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.esc_html($name).$trophy.'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.$data[&#8216;games&#8217;].'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.$data[&#8216;wins&#8217;].'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;td&gt;&#8217;.$data[&#8216;points&#8217;].'&lt;/td&gt;&#8217;;<br />$out .= &#8216;&lt;/tr&gt;&#8217;;<br />}</p>
<p>$out .= &#8216;&lt;/tbody&gt;&lt;/table&gt;&#8217;;</p>
<p>return $out;<br />});</p>
]]></content:encoded>
					
					<wfw:commentRss>https://rummygin.co.uk/hello-world/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
