19 Commits
Author SHA1 Message Date
nikola c6a210f281 todo update 2026-08-02 17:51:12 +02:00
nikola ad1ed7e45a Fix MacMahon output and rename 2026-08-02 17:50:30 +02:00
nikola 6aeee287f8 remove all contrys from help 2026-08-02 16:55:32 +02:00
nikola 4925b345bc bump version 2026-08-01 21:25:41 +02:00
nikola c36f409484 Display egd in edit files 2026-08-01 21:24:41 +02:00
nikola 2139a31e7c Added display contry and club 2026-08-01 21:10:36 +02:00
nikola 17998dc7b2 Move to compose file 2026-08-01 20:07:03 +02:00
nikola d5e0feb4f2 country 2026-07-05 21:02:25 +02:00
nikola f9555e4547 move ranks to helper file 2026-07-05 20:50:42 +02:00
nikola 1b0d00f380 t 2026-07-05 20:28:57 +02:00
nikola 2f06a8a4f1 Add notification email 2026-07-05 20:26:56 +02:00
nikola 08ae633d01 settings 2026-07-05 19:17:14 +02:00
nikola 6cebf05e32 Alling buttons 2026-07-05 19:05:29 +02:00
nikola f5b5af5372 Fix pairgoth export 2026-07-05 18:44:30 +02:00
nikola 1d5fed6e1f add email send 2026-06-26 14:11:49 +02:00
nikola d75997fbb5 Add side schrool 2026-06-07 14:40:30 +02:00
nikola ffaa624f65 Version bump 2026-06-01 17:44:09 +02:00
nikola 6e1bc4ac1b Fix make signup work for guests 2026-06-01 17:42:43 +02:00
nikola ad1a535795 Smal changes for Go-zveza 2026-05-31 19:03:54 +02:00
20 changed files with 823 additions and 2655 deletions
-182
View File
@@ -2,193 +2,11 @@
A WordPress plugin for managing Go (Baduk/Weiqi) tournament registrations. Collect player information through frontend forms and export entries to popular tournament management systems.
**Version:** 0.05
## Features
- **Frontend Registration Form** with shortcode support
- **EGD Database Integration** - Search and auto-fill player data from the European Go Database
- **Rank Selection** - Dropdown with ranks from 30k to 9p
- **Automatic Rating Calculation** - Auto-computes rating from rank when needed
- **Multiple Export Formats** - CSV, Pairgoth (JSON), OpenGotha (XML), McMahon (XML)
- **Multi-Form Support** - Create and manage multiple registration forms
- **Admin Dashboard** - View, delete, export entries, and manage forms
- **Custom Fields** - Add unlimited custom fields (text, email, textarea, select, checkbox) to forms
- **Entry Editing** - Edit existing registrations from admin panel
- **EGD Data Sync** - Batch update rank and rating from EGD for all entries with EGD numbers
- **Responsive Design** - Frontend form with grid layout
## Installation
1. Upload the `go-form-plugin` folder to your `/wp-content/plugins/` directory
2. Activate the plugin through the 'Plugins' menu in WordPress
3. A default form is automatically created on activation
## Usage
### Displaying a Form
Use the shortcode to display a registration form on any page or post:
```
[go_form id=1]
```
Replace `1` with your form ID. Find form IDs in the admin settings page.
### Admin Settings
Navigate to **Go Form** in the WordPress admin menu to:
- **Create Forms** - Add new registration forms with names
- **Manage Forms** - View all forms with their shortcodes and IDs
- **View Entries** - See all submissions for a form in a sortable table
- **Edit Entries** - Modify existing player registrations
- **Delete Entries** - Remove individual registrations
- **Delete Forms** - Remove a form and all its entries (cascading delete)
- **Export Data** - Download entries in various tournament formats
- **Manage Custom Fields** - Add, edit, and delete custom fields per form
- **EGD Data Sync** - Update rank and rating from EGD for all entries with EGD numbers
### EGD Search
Players can click the "Search EGD" button on the frontend form to look up their information in the European Go Database. This auto-fills:
- First Name
- Last Name
- Country
- Club
- Rank
- EGD Number
- Rating
## Export Formats
| Format | File Extension | Description |
|--------|---------------|-------------|
| CSV | `.csv` | Standard spreadsheet format |
| Pairgoth | `.tour` | JSON format for Pairgoth pairing system |
| OpenGotha | `.xml` | XML format for OpenGotha tournament manager |
| McMahon | `.xml` | XML format for McMahon tournament system |
## Database
The plugin creates four tables:
- `wp_go_form_forms` - Stores form definitions (id, name, created_at)
- `wp_go_form_entries` - Stores all player registrations with Go-specific fields
- `wp_go_form_custom_fields` - Stores custom field definitions per form
- `wp_go_form_entry_custom_values` - Stores custom field values for each entry
All tables use foreign keys with CASCADE delete and are automatically removed when the plugin is uninstalled.
### Rank System
Ranks are stored as integers (0-47) mapping to:
- 0-29: 30k to 1k
- 30-38: 1d to 9d
- 39-47: 1p to 9p
Rating auto-calculation: `rating = (rank * 100) - 900`
## Requirements
- WordPress 5.0 or higher
- PHP 7.4 or higher
- MySQL 5.6 or higher
## Fields Collected
| Field | Required | Description |
|-------|----------|-------------|
| First Name | Yes | Player's first name |
| Last Name | Yes | Player's last name |
| Country | Yes | Country code (2-3 letters) |
| Club | Yes | Club name |
| Rank | Yes | Go rank (30k to 9p) |
| Rating | No | EGD rating (auto-calculated from rank if missing) |
| EGD Number | No | European Go Database PIN |
## Hooks
### Actions
**Form Handling:**
- `admin_post_go_form_handle_submission` - Frontend form submission handler
- `admin_post_go_form_update_entry` - Update entry from admin panel
**Form Management:**
- `admin_post_go_form_create_form` - Create new form
- `admin_post_go_form_delete_form` - Delete form and all its entries
**Entry Management:**
- `admin_post_go_form_delete_entry` - Delete single entry
**Custom Fields:**
- `admin_post_go_form_create_custom_field` - Create custom field
- `admin_post_go_form_update_custom_field` - Update custom field
- `admin_post_go_form_delete_custom_field` - Delete custom field
**EGD Integration:**
- `admin_post_go_form_update_egd_data` - Batch update entries from EGD database
**Export:**
- `admin_post_go_form_export_csv` - CSV export handler
- `admin_post_go_form_export_pairgoth` - Pairgoth JSON export handler
- `admin_post_go_form_export_opengotha` - OpenGotha XML export handler
- `admin_post_go_form_export_mcmahon` - McMahon XML export handler
### Filters
None currently available.
## Custom Fields
Each form can have unlimited custom fields with the following types:
| Type | Description | Options |
|------|-------------|---------|
| `text` | Single line text input | - |
| `email` | Email address input with validation | - |
| `textarea` | Multi-line text input | - |
| `select` | Dropdown selection | Comma-separated options |
| `checkbox` | Checkbox (yes/no) | - |
### Custom Field Settings
- **Public** - Display on frontend form
- **Required** - Mandatory field
- **Full Width** - Display outside the grid layout
## Security
- All forms use WordPress nonces for CSRF protection
- Admin actions require `manage_options` capability
- All input is sanitized using WordPress sanitization functions (`sanitize_text_field`, `sanitize_textarea_field`, `intval`)
- Direct file access is blocked with `ABSPATH` check
- Database operations use `$wpdb->prepare()` for SQL injection prevention
## API Integration
### European Go Database (EGD)
The plugin integrates with the European Go Database for player data:
- **Search API**: `https://europeangodatabase.eu/EGD/GetPlayerDataByData.php?lastname=X&name=Y`
- **Player Data API**: `https://europeangodatabase.eu/EGD/GetPlayerDataByPIN.php?pin=XXXX`
Fields retrieved from EGD:
- Name, Last Name
- Country Code
- Club
- Grade (rank text)
- Grade_n (rank numeric)
- Gor (rating)
- Pin_Player (EGD PIN)
## Author
Nikola Petrov - nikola@petrovv.com
## License
MIT License - See LICENSE file for details.
+18
View File
@@ -0,0 +1,18 @@
Remove update egd data
https://stackoverflow.com/questions/18796221/creating-a-select-box-with-a-search-option
<input list="brow">
<datalist id="brow">
<option value="Internet Explorer">
<option value="Firefox">
<option value="Chrome">
<option value="Opera">
<option value="Safari">
</datalist>
```json
{"retcode":"Ok","Pin_Player":"12098053","AGAID":"0","Last_Name":"Podavini","Name":"Aldo","Country_Code":"IT","Club":"Mila","Grade":"5k","Grade_n":"25","EGF_Placement":"0","Gor":"1576","DGor":"0","Proposed_Grade":"","Tot_Tournaments":"36","Last_Appearance":"T101212A","Elab_Date":"2009-04-03","Hidden_History":"0","Real_Last_Name":"Podavini","Real_Name":"Aldo"}
```
+257
View File
@@ -0,0 +1,257 @@
<?php
/**
* Country codes and names extracted from go-form.xml
* Generated automatically - do not edit manually
*/
$countries = array(
'AC' => 'Ascension Island',
'AD' => 'Andorra',
'AE' => 'United Arab Emirates',
'AF' => 'Afghanistan',
'AG' => 'Antigua and Barbuda',
'AI' => 'Anguilla',
'AL' => 'Albania',
'AM' => 'Armenia',
'AN' => 'Netherlands Antilles',
'AO' => 'Angola',
'AQ' => 'Antarctica',
'AR' => 'Argentina',
'AS' => 'American Samoa',
'AT' => 'Austria',
'AU' => 'Australia',
'AW' => 'Aruba',
'AX' => 'Åland',
'AZ' => 'Azerbaijan',
'BA' => 'Bosnia and Herzegovina',
'BB' => 'Barbados',
'BD' => 'Bangladesh',
'BE' => 'Belgium',
'BF' => 'Burkina Faso',
'BG' => 'Bulgaria',
'BH' => 'Bahrain',
'BI' => 'Burundi',
'BJ' => 'Benin',
'BM' => 'Bermuda',
'BN' => 'Brunei Darussalam',
'BO' => 'Bolivia',
'BR' => 'Brazil',
'BS' => 'Bahamas',
'BT' => 'Bhutan',
'BV' => 'Bouvet Island',
'BW' => 'Botswana',
'BY' => 'Belarus',
'BZ' => 'Belize',
'CA' => 'Canada',
'CC' => 'Cocos (Keeling) Islands',
'CD' => 'Democratic Republic of the Congo',
'CF' => 'Central African Republic',
'CG' => 'Republic of the Congo',
'CH' => 'Switzerland',
'CI' => 'Côte d\'Ivoire',
'CK' => 'Cook Islands',
'CL' => 'Chile',
'CM' => 'Cameroon',
'CN' => 'People\'s Republic of China',
'CO' => 'Colombia',
'CR' => 'Costa Rica',
'CS' => 'Czechoslovakia',
'CU' => 'Cuba',
'CV' => 'Cape Verde',
'CX' => 'Christmas Island',
'CY' => 'Cyprus',
'CZ' => 'Czech Republic',
'DE' => 'Germany',
'DJ' => 'Djibouti',
'DK' => 'Denmark',
'DM' => 'Dominica',
'DO' => 'Dominican Republic',
'DZ' => 'Algeria',
'EC' => 'Ecuador',
'EE' => 'Estonia',
'EG' => 'Egypt',
'ER' => 'Eritrea',
'ES' => 'Spain',
'ET' => 'Ethiopia',
'EU' => 'European Union',
'FI' => 'Finland',
'FJ' => 'Fiji',
'FK' => 'Falkland Islands',
'FM' => 'Federated States of Micronesia',
'FO' => 'Faroe Islands',
'FR' => 'France',
'GA' => 'Gabon',
'GB' => 'United Kingdom',
'GD' => 'Grenada',
'GE' => 'Georgia',
'GF' => 'French Guiana',
'GG' => 'Guernsey',
'GH' => 'Ghana',
'GI' => 'Gibraltar',
'GL' => 'Greenland',
'GM' => 'The Gambia',
'GN' => 'Guinea',
'GP' => 'Guadeloupe',
'GQ' => 'Equatorial Guinea',
'GR' => 'Greece',
'GS' => 'South Georgia and the South Sandwich Islands',
'GT' => 'Guatemala',
'GU' => 'Guam',
'GW' => 'Guinea-Bissau',
'GY' => 'Guyana',
'HK' => 'Hong Kong',
'HM' => 'Heard Island and McDonald Islands',
'HN' => 'Honduras',
'HR' => 'Croatia',
'HT' => 'Haiti',
'HU' => 'Hungary',
'ID' => 'Indonesia',
'IE' => 'Ireland',
'IL' => 'Israel',
'IM' => 'Isle of Man',
'IN' => 'India',
'IO' => 'British Indian Ocean Territory',
'IQ' => 'Iraq',
'IR' => 'Iran',
'IS' => 'Iceland',
'IT' => 'Italy',
'JE' => 'Jersey',
'JM' => 'Jamaica',
'JO' => 'Jordan',
'JP' => 'Japan',
'KE' => 'Kenya',
'KG' => 'Kyrgyzstan',
'KH' => 'Cambodia',
'KI' => 'Kiribati',
'KM' => 'Comoros',
'KN' => 'Saint Kitts and Nevis',
'KP' => 'Democratic People\'s Republic of Korea',
'KR' => 'Republic of Korea',
'KW' => 'Kuwait',
'KY' => 'Cayman Islands',
'KZ' => 'Kazakhstan',
'LA' => 'Laos',
'LB' => 'Lebanon',
'LC' => 'Saint Lucia',
'LI' => 'Liechtenstein',
'LK' => 'Sri Lanka',
'LR' => 'Liberia',
'LS' => 'Lesotho',
'LT' => 'Lithuania',
'LU' => 'Luxembourg',
'LV' => 'Latvia',
'LY' => 'Libya',
'MA' => 'Morocco',
'MC' => 'Monaco',
'MD' => 'Moldova',
'ME' => 'Montenegro',
'MG' => 'Madagascar',
'MH' => 'Marshall Islands',
'MK' => 'Republic of Macedonia',
'ML' => 'Mali',
'MM' => 'Myanmar',
'MN' => 'Mongolia',
'MO' => 'Macau',
'MP' => 'Northern Mariana Islands',
'MQ' => 'Martinique',
'MR' => 'Mauritania',
'MS' => 'Montserrat',
'MT' => 'Malta',
'MU' => 'Mauritius',
'MV' => 'Maldives',
'MW' => 'Malawi',
'MX' => 'Mexico',
'MY' => 'Malaysia',
'MZ' => 'Mozambique',
'NA' => 'Namibia',
'NC' => 'New Caledonia',
'NE' => 'Niger',
'NF' => 'Norfolk Island',
'NG' => 'Nigeria',
'NI' => 'Nicaragua',
'NL' => 'Netherlands',
'NO' => 'Norway',
'NP' => 'Nepal',
'NR' => 'Nauru',
'NU' => 'Niue',
'NZ' => 'New Zealand',
'OM' => 'Oman',
'PA' => 'Panama',
'PE' => 'Peru',
'PF' => 'French Polynesia',
'PG' => 'Papua New Guinea',
'PH' => 'Philippines',
'PK' => 'Pakistan',
'PL' => 'Poland',
'PM' => 'Saint-Pierre and Miquelon',
'PN' => 'Pitcairn Islands',
'PR' => 'Puerto Rico',
'PS' => 'Palestinian territories',
'PT' => 'Portugal',
'PW' => 'Palau',
'PY' => 'Paraguay',
'QA' => 'Qatar',
'RE' => 'Réunion',
'RO' => 'Romania',
'RS' => 'Serbia',
'RU' => 'Russia',
'RW' => 'Rwanda',
'SA' => 'Saudi Arabia',
'SB' => 'Solomon Islands',
'SC' => 'Seychelles',
'SD' => 'Sudan',
'SE' => 'Sweden',
'SG' => 'Singapore',
'SH' => 'Saint Helena',
'SI' => 'Slovenia',
'SJ' => 'Svalbard and Jan Mayen Islands',
'SK' => 'Slovakia',
'SL' => 'Sierra Leone',
'SM' => 'San Marino',
'SN' => 'Senegal',
'SO' => 'Somalia',
'SR' => 'Suriname',
'ST' => 'São Tomé and Príncipe',
'SU' => 'Soviet Union',
'SV' => 'El Salvador',
'SY' => 'Syria',
'SZ' => 'Swaziland',
'TC' => 'Turks and Caicos Islands',
'TD' => 'Chad',
'TF' => 'French Southern and Antarctic Lands',
'TG' => 'Togo',
'TH' => 'Thailand',
'TJ' => 'Tajikistan',
'TK' => 'Tokelau',
'TL' => 'East Timor',
'TM' => 'Turkmenistan',
'TN' => 'Tunisia',
'TO' => 'Tonga',
'TP' => 'East Timor',
'TR' => 'Turkey',
'TT' => 'Trinidad and Tobago',
'TV' => 'Tuvalu',
'TW' => 'Republic of China (Taiwan)',
'TZ' => 'Tanzania',
'UA' => 'Ukraine',
'UG' => 'Uganda',
'UK' => 'United Kingdom',
'US' => 'United States of America',
'UY' => 'Uruguay',
'UZ' => 'Uzbekistan',
'VA' => 'Vatican City',
'VC' => 'Saint Vincent and the Grenadines',
'VE' => 'Venezuela',
'VG' => 'British Virgin Islands',
'VI' => 'US Virgin Islands',
'VN' => 'Vietnam',
'VU' => 'Vanuatu',
'WF' => 'Wallis and Futuna',
'WS' => 'Samoa',
'YE' => 'Yemen',
'YT' => 'Mayotte',
'ZA' => 'South Africa',
'ZM' => 'Zambia',
'ZW' => 'Zimbabwe',
);
+3
View File
@@ -3,6 +3,7 @@
CREATE TABLE wp_go_form_forms (
id int NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
email varchar(255) DEFAULT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (id)
);
@@ -14,6 +15,8 @@ CREATE TABLE wp_go_form_entries (
last_name varchar(100) NOT NULL,
country varchar(100) DEFAULT NULL,
club varchar(100) DEFAULT NULL,
display_country varchar(150) DEFAULT NULL,
display_club varchar(100) DEFAULT NULL,
rank tinyint(2) DEFAULT 0,
rating smallint(5) DEFAULT 0,
egd_number varchar(20) DEFAULT NULL,
+137
View File
@@ -0,0 +1,137 @@
<?php
$macmahonfirst = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Tournament typeversion="9">
<NumberOfRounds>5</NumberOfRounds>
<CurrentRoundNumber>1</CurrentRoundNumber>
<TakeCurrentRoundInAccount>true</TakeCurrentRoundInAccount>
<DefaultAsianName>false</DefaultAsianName>
<RatingAllowed>false</RatingAllowed>
<RatingLowestOneDanRating>2050</RatingLowestOneDanRating>
<RatingDeterminesRank>false</RatingDeterminesRank>
<RatingDeterminesStartScore>false</RatingDeterminesStartScore>
<LowerMacMahonBar>true</LowerMacMahonBar>
<LowerMacMahonBarLevel>10k</LowerMacMahonBarLevel>
<UpperMacMahonBar>true</UpperMacMahonBar>
<UpperMacMahonBarLevel>2k</UpperMacMahonBarLevel>
<UpperMacMahonBarRating>0</UpperMacMahonBarRating>
<ByeShouldResultInZeroSOSetc>false</ByeShouldResultInZeroSOSetc>
<HalfScoreGroupsRoundDown>false</HalfScoreGroupsRoundDown>
<HalfScoreGroupsRoundDownNotJigo>true</HalfScoreGroupsRoundDownNotJigo>
<PreliminaryDefaultRegistration>false</PreliminaryDefaultRegistration>
<OnlineEgdSupport>true</OnlineEgdSupport>
<OnlineEgdSupportByPin>false</OnlineEgdSupportByPin>
<HandicapUsed>true</HandicapUsed>
<HandicapBelow>false</HandicapBelow>
<HandicapBelowLevel>1d</HandicapBelowLevel>
<HandicapByLevel>true</HandicapByLevel>
<HandicapAdjustment>true</HandicapAdjustment>
<HandicapAdjustmentValue>-2</HandicapAdjustmentValue>
<HandicapLimit>true</HandicapLimit>
<HandicapLimitValue>9</HandicapLimitValue>
<HandicapIncludeInTieBreakers>true</HandicapIncludeInTieBreakers>
<AllowJigo>false</AllowJigo>
<Boardsize>19</Boardsize>
<PairingsMarkFixedBoardnumbers>true</PairingsMarkFixedBoardnumbers>
<PairingsMarkMissingResults>true</PairingsMarkMissingResults>
<PairingsMarkWinner>true</PairingsMarkWinner>
<PairingsMarkUnwantedPairings>true</PairingsMarkUnwantedPairings>
<PairingsShowLevels>true</PairingsShowLevels>
<PairingsShortNotationForLevel>false</PairingsShortNotationForLevel>
<PairingsShowScores>false</PairingsShowScores>
<PairingsShowHandicaps>true</PairingsShowHandicaps>
<PairingsFontsize>18</PairingsFontsize>
<PairingsBlackColumnWidth>283</PairingsBlackColumnWidth>
<PairingsWhiteColumnWidth>301</PairingsWhiteColumnWidth>
<ImportEncoding>UTF-8</ImportEncoding>
<ExportColumnDelimiter><![CDATA[f]]></ExportColumnDelimiter>
<ExportWalllistShowTournamentTitle>true</ExportWalllistShowTournamentTitle>
<ExportEncoding>UTF-8</ExportEncoding>
<VersionCreated>MacMahon 3.10</VersionCreated>
<VersionSaved>MacMahon 3.10</VersionSaved>
<MakePairingTopGroup>true</MakePairingTopGroup>
<MakePairingTopGroupEverywhere>false</MakePairingTopGroupEverywhere>
<MakePairingTopGroupStrictlyByTopBar>false</MakePairingTopGroupStrictlyByTopBar>
<MakePairingTopGroupByNumberOfPlayersAuto>true</MakePairingTopGroupByNumberOfPlayersAuto>
<MakePairingTopGroupByNumberOfPlayers>0</MakePairingTopGroupByNumberOfPlayers>
<MakePairingTopGroupSeeding>true</MakePairingTopGroupSeeding>
<MakePairingSeedingPlacementCriterion typeversion="2">
<ShortName>SOS</ShortName>
</MakePairingSeedingPlacementCriterion>
<MakePairingTopGroupSeedingByRating>false</MakePairingTopGroupSeedingByRating>
<MakePairingTopGroupSeedingByRatingRound>2</MakePairingTopGroupSeedingByRatingRound>
<MakePairingOutsideTopGroupSameCountry>true</MakePairingOutsideTopGroupSameCountry>
<MakePairingOutsideTopGroupSameClub>true</MakePairingOutsideTopGroupSameClub>
<MakePairingOutsideTopGroupSameNationality>false</MakePairingOutsideTopGroupSameNationality>
<MakePairingOutsideTopGroupStrengthDifference>true</MakePairingOutsideTopGroupStrengthDifference>
<MakePairingOutsideTopGroupStrengthDifferenceValue>3</MakePairingOutsideTopGroupStrengthDifferenceValue>
<MakePairingOutsideTopGroupColorBalance>true</MakePairingOutsideTopGroupColorBalance>
<MakePairingOutsideTopGroupWeakOddMan>true</MakePairingOutsideTopGroupWeakOddMan>
<MakePairingOutsideTopGroupSeeding>false</MakePairingOutsideTopGroupSeeding>
<PrintWalllistFont>SansSerif</PrintWalllistFont>
<PrintWalllistFontsize>9</PrintWalllistFontsize>
<PrintWalllistIndentationTop>0</PrintWalllistIndentationTop>
<PrintWalllistIndentationLeft>0</PrintWalllistIndentationLeft>
<PrintWalllistColumnDistance>2</PrintWalllistColumnDistance>
<PrintWalllistAbbreviateName>true</PrintWalllistAbbreviateName>
<PrintWalllistAbbreviateNameLength>28</PrintWalllistAbbreviateNameLength>
<PrintPairingsFont>SansSerif</PrintPairingsFont>
<PrintPairingsFontsize>10</PrintPairingsFontsize>
<PrintPairingsIndentationTop>0</PrintPairingsIndentationTop>
<PrintPairingsIndentationLeft>0</PrintPairingsIndentationLeft>
<PrintPairingsColumnDistance>3</PrintPairingsColumnDistance>
<PrintPairingsAbbreviateName>true</PrintPairingsAbbreviateName>
<PrintPairingsAbbreviateNameLength>35</PrintPairingsAbbreviateNameLength>
<Walllist typeversion="3">
<ShowCountry>true</ShowCountry>
<ShowClub>true</ShowClub>
<ShowClubEgdName>false</ShowClubEgdName>
<ShowClubAbbreviateName>true</ShowClubAbbreviateName>
<ShowLevels>true</ShowLevels>
<ShortNotationForLevel>false</ShortNotationForLevel>
<ShowBarMembership>true</ShowBarMembership>
<ShowRatings>true</ShowRatings>
<MarkPreliminaryRegisteredParticipants>true</MarkPreliminaryRegisteredParticipants>
<MarkResultsByReferree>true</MarkResultsByReferree>
<ShowColors>false</ShowColors>
<ShowHandicap>true</ShowHandicap>
<ShowWarningMissingPairing>true</ShowWarningMissingPairing>
<Fontsize>18</Fontsize>
<NameColumnWidth>221</NameColumnWidth>
<ClubColumnWidth>0</ClubColumnWidth>
<ClubColumnAlignmentCenter>true</ClubColumnAlignmentCenter>
<WeakSortCriteria>1</WeakSortCriteria>
<SortCriterionDescriptor typeversion="2">
<ShortName>Score</ShortName>
</SortCriterionDescriptor>
<SortCriterionDescriptor typeversion="2">
<ShortName>SOS</ShortName>
</SortCriterionDescriptor>
<SortCriterionDescriptor typeversion="2">
<ShortName>SOSOS</ShortName>
</SortCriterionDescriptor>
<SortCriterionDescriptor typeversion="2">
<ShortName>ScoreX</ShortName>
</SortCriterionDescriptor>
</Walllist>';
$macmahonlast = '<TournamentRound typeversion="2">
<RoundNumber>1</RoundNumber>
<LastUpdated>2026-05-13 21:30:31</LastUpdated>
</TournamentRound>
<TournamentRound typeversion="2">
<RoundNumber>2</RoundNumber>
<LastUpdated>2026-05-13 21:30:21</LastUpdated>
</TournamentRound>
<TournamentRound typeversion="2">
<RoundNumber>3</RoundNumber>
<LastUpdated>2026-05-13 21:30:10</LastUpdated>
</TournamentRound>
<TournamentRound typeversion="2">
<RoundNumber>4</RoundNumber>
<LastUpdated>2026-05-13 21:29:20</LastUpdated>
</TournamentRound>
<TournamentRound typeversion="2">
<RoundNumber>5</RoundNumber>
<LastUpdated>2026-05-13 21:29:04</LastUpdated>
</TournamentRound>
</Tournament>';
@@ -1,6 +1,6 @@
<?php
go_form_admin_action('export_mcmahon');
go_form_admin_action('export_macmahon');
if (!isset($_POST['value_one'])) {
wp_redirect(admin_url('admin.php?page=go-form-settings'));
exit;
@@ -15,9 +15,43 @@ header('Content-Type: text/xml; charset=utf-8');
header('Content-Disposition: attachment; filename="go-form-' . sanitize_title($form_name) . '-export-macmahon.xml"');
$output = fopen('php://output', 'w');
include_once 'mcmahon-help.php';
include_once 'macmahon-help.php';
fwrite($output, $mcmahonfirst);
fwrite($output, $macmahonfirst);
// Gather the distinct clubs used per country among the actual participants
$clubs_by_country = [];
foreach ($entries as $e) {
$country_code = strtoupper(trim($e->country));
$club = trim($e->club);
if ($country_code === '' || $club === '') {
continue;
}
if (!isset($clubs_by_country[$country_code])) {
$clubs_by_country[$country_code] = [];
}
if (!in_array($club, $clubs_by_country[$country_code], true)) {
$clubs_by_country[$country_code][] = $club;
}
}
foreach ($countries as $code => $name) {
$out = ' <Country typeversion="1">
<InternetCode>' . esc_html(strtolower($code)) . '</InternetCode>
<Name>' . esc_html($name) . '</Name>';
if (!empty($clubs_by_country[$code])) {
foreach ($clubs_by_country[$code] as $club) {
$out .= '
<Club typeversion="1">
<Name>' . esc_html($club) . '</Name>
<EGDName>' . esc_html($club) . '</EGDName>
</Club>';
}
}
$out .= '
</Country>';
fwrite($output, $out);
}
foreach ($entries as $i => $e) {
$rank = $ranks[$e->rank];
@@ -44,6 +78,6 @@ foreach ($entries as $i => $e) {
fwrite($output, $out);
}
fwrite($output, $mcmahonlast);
fwrite($output, $macmahonlast);
fclose($output);
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -22,7 +22,7 @@ $count = count($entries);
foreach ($entries as $i => $e) {
$rank = $e->rank - 30;
$id = ($i + 1) * 2;
$out = "{\"id\":$id,\"name\":\"$e->first_name\",\"firstname\":\"$e->last_name\",\"rating\":$e->rating,\"rank\":$rank,\"country\":\"$e->country\",\"club\":\"$e->club\",\"final\":false,\"egf\":\"$e->egd_number\"}";
$out = "{\"id\":$id,\"name\":\"$e->last_name\",\"firstname\":\"$e->first_name\",\"rating\":$e->rating,\"rank\":$rank,\"country\":\"$e->country\",\"club\":\"$e->club\",\"final\":false,\"egf\":\"$e->egd_number\"}";
if ($i + 1 < $count) {
$out .= ",";
}
+106 -35
View File
@@ -3,7 +3,11 @@
if (!defined('ABSPATH'))
exit;
// ========== Database ==========
// Load helpers
require_once plugin_dir_path(__FILE__) . 'helpers.php';
require_once plugin_dir_path(__FILE__) . 'countries.php';
// ========== Database ===========
function go_form_activate()
{
global $wpdb;
@@ -17,6 +21,7 @@ function go_form_activate()
dbDelta("CREATE TABLE $forms (
id int NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
email varchar(255) DEFAULT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (id)
) $charset;");
@@ -28,6 +33,8 @@ function go_form_activate()
last_name varchar(100) NOT NULL,
country varchar(100) DEFAULT NULL,
club varchar(100) DEFAULT NULL,
display_country varchar(150) DEFAULT NULL,
display_club varchar(100) DEFAULT NULL,
rank tinyint(2) DEFAULT 0,
rating smallint(5) DEFAULT 0,
egd_number varchar(20) DEFAULT NULL,
@@ -74,19 +81,6 @@ function go_form_uninstall()
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}go_form_forms");
}
// ========== Helpers ==========
$ranks = [
0 => '30k', 1 => '29k', 2 => '28k', 3 => '27k', 4 => '26k',
5 => '25k', 6 => '24k', 7 => '23k', 8 => '22k', 9 => '21k',
10 => '20k', 11 => '19k', 12 => '18k', 13 => '17k', 14 => '16k',
15 => '15k', 16 => '14k', 17 => '13k', 18 => '12k', 19 => '11k',
20 => '10k', 21 => '9k', 22 => '8k', 23 => '7k', 24 => '6k',
25 => '5k', 26 => '4k', 27 => '3k', 28 => '2k', 29 => '1k',
30 => '1d', 31 => '2d', 32 => '3d', 33 => '4d', 34 => '5d',
35 => '6d', 36 => '7d', 37 => '8d', 38 => '9d', 39 => '1p',
40 => '2p', 41 => '3p', 42 => '4p', 43 => '5p', 44 => '6p',
45 => '7p', 46 => '8p', 47 => '9p'
];
function go_form_get_forms()
{
global $wpdb;
@@ -151,7 +145,8 @@ function go_form_get_custom_value($entry_id, $field_id)
return $wpdb->get_var($wpdb->prepare(
"SELECT value FROM {$wpdb->prefix}go_form_entry_custom_values
WHERE entry_id = %d AND field_id = %d",
$entry_id, $field_id
$entry_id,
$field_id
));
}
@@ -171,6 +166,7 @@ function go_form_handle_submission()
wp_die('Security check failed');
global $wpdb;
global $ranks;
if (isset($_POST['form_id'])) {
$form_id = intval($_POST['form_id']);
} else {
@@ -190,6 +186,8 @@ function go_form_handle_submission()
'last_name' => sanitize_text_field($_POST['last_name']),
'country' => sanitize_text_field($_POST['country'] ?? ''),
'club' => sanitize_text_field($_POST['club'] ?? ''),
'display_country' => sanitize_text_field($_POST['display_country'] ?? ''),
'display_club' => sanitize_text_field($_POST['display_club'] ?? ''),
'rank' => $rank,
'rating' => $rating,
'egd_number' => sanitize_text_field($_POST['egd_number'] ?? ''),
@@ -229,15 +227,36 @@ function go_form_handle_submission()
}
}
// Send notification email if form has an email configured
$form = go_form_get_form_by_id($form_id);
if (!empty($form->email)) {
$to = $form->email;
$subject = 'New Go Tournament Registration';
$message = "A new player has signed up:\n\n";
$message .= "Form: {$form->name}\n";
$message .= "Form ID: {$form_id}\n";
$message .= "Name: {$data['first_name']} {$data['last_name']}\n";
$message .= "Country: {$data['country']}\n";
$message .= "Club: {$data['club']}\n";
$message .= "Rank: {$ranks[$data['rank']]}\n";
$message .= "Rating: {$data['rating']}\n";
$message .= "EGD Number: {$data['egd_number']}\n";
$message .= "Date: " . date('Y-m-d H:i:s') . "\n";
wp_mail($to, $subject, $message);
}
wp_redirect($_SERVER['HTTP_REFERER']);
exit;
}
add_action('admin_post_go_form_handle_submission', 'go_form_handle_submission');
add_action('admin_post_nopriv_go_form_handle_submission', 'go_form_handle_submission');
// ========== Shortcode ==========
function go_form_shortcode($atts)
{
global $ranks;
global $ranks, $countries;
$form_id = intval($atts['id']);
$form = go_form_get_form_by_id($form_id);
@@ -286,7 +305,11 @@ function go_form_create_form()
go_form_admin_action('create_form');
if (isset($_POST['form_name']) && !empty($_POST['form_name'])) {
global $wpdb;
$wpdb->insert("{$wpdb->prefix}go_form_forms", ['name' => sanitize_text_field($_POST['form_name'])]);
$form_data = [
'name' => sanitize_text_field($_POST['form_name']),
'email' => isset($_POST['form_email']) ? sanitize_text_field($_POST['form_email']) : ''
];
$wpdb->insert("{$wpdb->prefix}go_form_forms", $form_data);
$new_form_id = $wpdb->insert_id;
$redirect_url = add_query_arg(array('page' => 'go-form-settings', 'form_id' => $new_form_id, 'created' => 1), admin_url('admin.php'));
wp_redirect($redirect_url);
@@ -298,6 +321,27 @@ function go_form_create_form()
}
add_action('admin_post_go_form_create_form', 'go_form_create_form');
function go_form_update_form()
{
go_form_admin_action('update_form');
if (isset($_POST['form_id']) && isset($_POST['form_name']) && !empty($_POST['form_name'])) {
global $wpdb;
$form_id = intval($_POST['form_id']);
$form_data = [
'name' => sanitize_text_field($_POST['form_name']),
'email' => isset($_POST['form_email']) ? sanitize_text_field($_POST['form_email']) : ''
];
$wpdb->update("{$wpdb->prefix}go_form_forms", $form_data, ['id' => $form_id]);
$redirect_url = add_query_arg(array('page' => 'go-form-settings', 'form_id' => $form_id, 'updated_form' => 1), admin_url('admin.php'));
wp_redirect($redirect_url);
exit;
}
$redirect_url = add_query_arg(array('page' => 'go-form-settings'), admin_url('admin.php'));
wp_redirect($redirect_url);
exit;
}
add_action('admin_post_go_form_update_form', 'go_form_update_form');
function go_form_delete_form()
{
go_form_admin_action('delete_form');
@@ -334,13 +378,13 @@ function go_form_export_opengotha()
}
add_action('admin_post_go_form_export_opengotha', 'go_form_export_opengotha');
function go_form_export_mcmahon()
function go_form_export_macmahon()
{
global $ranks;
include_once 'export/mcmahon.php';
global $ranks, $countries;
include_once 'export/macmahon.php';
exit;
}
add_action('admin_post_go_form_export_mcmahon', 'go_form_export_mcmahon');
add_action('admin_post_go_form_export_macmahon', 'go_form_export_macmahon');
// ========== Custom Field Admin Actions ==========
function go_form_create_custom_field()
@@ -420,6 +464,30 @@ function go_form_delete_custom_field()
add_action('admin_post_go_form_delete_custom_field', 'go_form_delete_custom_field');
// ========== Entry Edit Admin Action ==========
function go_form_fetch_egd_data($pin)
{
$pin = trim($pin);
if (empty($pin)) {
return null;
}
$url = 'https://europeangodatabase.eu/EGD/GetPlayerDataByPIN.php?pin=' . urlencode($pin);
$response = wp_remote_get($url, ['timeout' => 10]);
if (is_wp_error($response)) {
return null;
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if ($data && isset($data['retcode']) && $data['retcode'] === 'Ok') {
return $data;
}
return null;
}
function go_form_update_egd_data()
{
go_form_admin_action('update_egd_data');
@@ -429,7 +497,7 @@ function go_form_update_egd_data()
exit;
}
global $wpdb, $ranks;
global $wpdb;
$form_id = intval($_POST['value_one']);
$entries = go_form_get_entries($form_id);
$updated_count = 0;
@@ -439,19 +507,11 @@ function go_form_update_egd_data()
continue;
}
$pin = trim($entry->egd_number);
$url = 'https://europeangodatabase.eu/EGD/GetPlayerDataByPIN.php?pin=' . urlencode($pin);
$response = wp_remote_get($url, ['timeout' => 10]);
if (is_wp_error($response)) {
$data = go_form_fetch_egd_data($entry->egd_number);
if (!$data) {
continue;
}
$body = wp_remote_retrieve_body($response);
$data = json_decode($body, true);
if ($data && isset($data['retcode']) && $data['retcode'] === 'Ok') {
// Map EGD Grade_n to our rank system
// EGD Grade_n: 0=30k, 1=29k, ... 25=5k, 30=1d, ... 39=9d, 40=1p, ... 47=9p
// Our ranks array: 0=30k, 1=29k, ... 25=5k, 30=1d, ... 39=9d, 40=1p, ... 47=9p
@@ -469,7 +529,6 @@ function go_form_update_egd_data()
$updated_count++;
}
}
}
$redirect_url = add_query_arg(
array('page' => 'go-form-settings', 'form_id' => $form_id, 'egd_updated' => $updated_count),
@@ -503,6 +562,8 @@ function go_form_update_entry()
'last_name' => sanitize_text_field($_POST['last_name']),
'country' => sanitize_text_field($_POST['country'] ?? ''),
'club' => sanitize_text_field($_POST['club'] ?? ''),
'display_country' => sanitize_text_field($_POST['display_country'] ?? ''),
'display_club' => sanitize_text_field($_POST['display_club'] ?? ''),
'rank' => $rank,
'rating' => $rating,
'egd_number' => sanitize_text_field($_POST['egd_number'] ?? ''),
@@ -533,9 +594,11 @@ function go_form_update_entry()
// Check if custom value exists
$existing = go_form_get_custom_value($entry_id, $field->id);
if ($existing !== null) {
$wpdb->update("{$wpdb->prefix}go_form_entry_custom_values",
$wpdb->update(
"{$wpdb->prefix}go_form_entry_custom_values",
['value' => $value],
['entry_id' => $entry_id, 'field_id' => $field->id]);
['entry_id' => $entry_id, 'field_id' => $field->id]
);
} else {
$wpdb->insert("{$wpdb->prefix}go_form_entry_custom_values", [
'entry_id' => $entry_id,
@@ -579,3 +642,11 @@ function go_form_settings_page()
{
include_once 'templates/settings-page.php';
}
function go_form_egd_hint($value)
{
if ($value === null || $value === '') {
return '';
}
return ' <span style="color:#2271b1; font-style:italic;">(EGD: ' . esc_html($value) . ')</span>';
}
+59
View File
@@ -0,0 +1,59 @@
<?php
if (!defined('ABSPATH'))
exit;
// Go ranks array - maps numeric rank values to rank labels
// 0-29: 30k to 1k
// 30-39: 1d to 9d
// 40-47: 1p to 9p
$ranks = [
0 => '30k',
1 => '29k',
2 => '28k',
3 => '27k',
4 => '26k',
5 => '25k',
6 => '24k',
7 => '23k',
8 => '22k',
9 => '21k',
10 => '20k',
11 => '19k',
12 => '18k',
13 => '17k',
14 => '16k',
15 => '15k',
16 => '14k',
17 => '13k',
18 => '12k',
19 => '11k',
20 => '10k',
21 => '9k',
22 => '8k',
23 => '7k',
24 => '6k',
25 => '5k',
26 => '4k',
27 => '3k',
28 => '2k',
29 => '1k',
30 => '1d',
31 => '2d',
32 => '3d',
33 => '4d',
34 => '5d',
35 => '6d',
36 => '7d',
37 => '8d',
38 => '9d',
39 => '1p',
40 => '2p',
41 => '3p',
42 => '4p',
43 => '5p',
44 => '6p',
45 => '7p',
46 => '8p',
47 => '9p'
];
+30 -15
View File
@@ -54,6 +54,15 @@
grid-template-columns: auto auto;
column-gap: 16px;
}
.go-form-user-grid {
display: grid;
grid-template-columns: auto auto min-content;
column-gap: 16px;
}
.egd-search {
display: flex;
align-items: center;
}
</style>
<div id="form">
@@ -62,7 +71,10 @@
<input type="hidden" name="action" value="go_form_handle_submission">
<input type="hidden" name="form_id" value="<?php echo esc_attr($form_id); ?>">
<input type="hidden" name="rating" id="rating" value="-1000">
<div class="go-form-grid">
<input type="hidden" name="country" id="country">
<input type="hidden" name="club" id="club">
<div class="go-form-user-grid">
<div>
<label for="first_name">First Name*:</label><input type="text" name="first_name" id="first_name" required>
@@ -72,10 +84,13 @@
<label for="last_name">Last Name*:</label><input type="text" name="last_name" id="last_name" required>
</div>
<div>
<div class="egd-search">
<button type="button" id="egd-search" class="button">Search EGD</button>
</div>
</div>
<div class="go-form-grid">
<div>
<label for="rank">Rank*:</label>
<select name="rank" id="rank">
@@ -87,18 +102,18 @@
</select>
</div>
<div>
<label for="country">Country*:</label><input type="text" name="country" id="country" required>
</div>
<div>
<label for="club">Club*:</label><input type="text" name="club" id="club" required>
</div>
<div>
<label for="egd_number">EGD Number:</label><input type="text" name="egd_number" id="egd_number">
</div>
<div>
<label for="display_country">Country*:</label><input type="text" name="display_country" id="display_country" required>
</div>
<div>
<label for="display_club">Club:</label><input type="text" name="display_club" id="display_club">
</div>
<?php
// Display custom fields
$custom_fields = go_form_get_custom_fields($form_id);
@@ -184,7 +199,6 @@
endforeach;
?>
<p>* Required fields</p>
<input type="submit" name="go_form_submit" value="Submit">
</form>
@@ -197,10 +211,8 @@
</div>
<?php
$entries = go_form_get_entries($form_id);
$entries_count = count($entries);
$custom_fields = go_form_get_custom_fields($form_id);
?>
<h2>Sign-up players: <?= esc_html($entries_count); ?></h2>
<?php go_form_render_entries_table($entries, false, $custom_fields, $form_id); ?>
</div>
@@ -208,17 +220,18 @@
document.addEventListener('DOMContentLoaded', function () {
const contentDiv = document.getElementById('egd-results-content');
const egdOverlay = document.getElementById('egd-popup-overlay');
const countryMap = <?php echo wp_json_encode($countries); ?>;
function fetchPlayers() {
const firstName = document.getElementById('first_name').value.trim();
const lastName = document.getElementById('last_name').value.trim();
if (firstName.length < 2) {
alert('Please enter at least 2 characters in first or last name');
alert('Please enter at least 2 characters in first and last name');
return;
}
if (lastName.length < 2) {
alert('Please enter at least 2 characters in first or last name');
alert('Please enter at least 2 characters in first and last name');
return;
}
@@ -259,6 +272,8 @@
document.getElementById('last_name').value = player.Last_Name || player.Real_Last_Name || '';
document.getElementById('country').value = player.Country_Code || '';
document.getElementById('club').value = player.Club || '';
document.getElementById('display_country').value = countryMap[player.Country_Code] || player.Country_Code || '';
document.getElementById('display_club').value = player.Club || '';
document.getElementById('rank').value = player.Grade_n || 0;
document.getElementById('egd_number').value = player.Pin_Player || '';
document.getElementById('rating').value = player.Gor || 0;
+44 -12
View File
@@ -7,6 +7,8 @@ if (isset($_GET['deleted']))
echo '<div class="notice notice-success"><p>Deleted!</p></div>';
if (isset($_GET['created']))
echo '<div class="notice notice-success"><p>Form created!</p></div>';
if (isset($_GET['updated_form']))
echo '<div class="notice notice-success"><p>Form updated!</p></div>';
if (isset($_GET['created_field']))
echo '<div class="notice notice-success"><p>Custom field created!</p></div>';
if (isset($_GET['updated_field']))
@@ -37,14 +39,29 @@ if (isset($_GET['error']) && $_GET['error'] == 'egd_update_failed')
$form = go_form_get_form_by_id($selected_form_id);
$form_name = $form ? $form->name : 'Unknown Form';
echo "<h3> $form_name</h3>";
echo '<div style="margin-bottom:15px; display: flex; flex-wrap: wrap; gap: 10px;">';
// Form info and edit UI
if ($form) {
echo '<div style="margin-bottom:20px; padding:15px; background:#fff; border:1px solid #ddd; border-radius:4px;">';
echo '<form method="post" action="' . admin_url('admin-post.php') . '">';
echo wp_nonce_field('go_form_update_form_action', 'go_form_update_form_nonce', true, false);
echo '<input type="hidden" name="action" value="go_form_update_form">';
echo '<input type="hidden" name="form_id" value="' . esc_attr($selected_form_id) . '">';
echo '<table class="form-table">';
echo '<tr><th><label for="form_name">Form Name:</label></th><td><input type="text" name="form_name" id="form_name" value="' . esc_attr($form->name) . '" required></td></tr>';
echo '<tr><th><label for="form_email">Notification Email:</label></th><td><input type="email" name="form_email" id="form_email" value="' . esc_attr($form->email ?? '') . '" placeholder="Optional email for signup notifications"></td></tr>';
echo '</table>';
echo '<p class="submit"><input type="submit" class="button button-primary" value="Update Form"></p>';
echo '</form>';
echo '</div>';
}
echo '<div style="margin-bottom:15px; display: flex; flex-wrap: wrap; gap: 10px;">';
action_button('go_form_delete_form', 'Delete Form', 'Delete this form and ALL entries?', $selected_form_id);
action_button('go_form_export_csv', 'Export to CSV', 'Confirm Export', $selected_form_id);
action_button('go_form_export_pairgoth', 'Export to Pairgoth', 'Confirm Export', $selected_form_id);
action_button('go_form_export_opengotha', 'Export to Opengoth', 'Confirm Export', $selected_form_id);
action_button('go_form_export_mcmahon', 'Export to McMahon', 'Confirm Export', $selected_form_id);
action_button('go_form_export_macmahon', 'Export to MacMahon', 'Confirm Export', $selected_form_id);
action_button('go_form_update_egd_data', 'Update EGD Data', 'Update rank and rating from EGD for all entries with EGD numbers?', $selected_form_id);
echo '</div>';
@@ -92,10 +109,12 @@ if (isset($_GET['error']) && $_GET['error'] == 'egd_update_failed')
echo '<td>' . ($field->is_public ? 'Yes' : 'No') . '</td>';
echo '<td>' . ($field->is_required ? 'Yes' : 'No') . '</td>';
echo '<td>' . ($field->is_full_width ? 'Yes' : 'No') . '</td>';
echo '<td>';
echo '<td style="white-space: nowrap;">';
// Edit button (toggle to show edit form)
echo '<a href="' . add_query_arg(array('page' => 'go-form-settings', 'form_id' => $selected_form_id, 'edit_field' => $field->id), admin_url('admin.php')) . '" class="button button-small">Edit</a> ';
echo '<a href="' . add_query_arg(array('page' => 'go-form-settings', 'form_id' => $selected_form_id, 'edit_field' => $field->id), admin_url('admin.php')) . '" class="button" style="margin-right: 4px;">Edit</a> ';
echo '<span style="display: inline-block;">';
action_button('go_form_delete_custom_field', 'Delete', 'Delete this custom field?', $field->id);
echo '</span>';
echo '</td>';
echo '</tr>';
}
@@ -143,27 +162,35 @@ if (isset($_GET['error']) && $_GET['error'] == 'egd_update_failed')
$entry = go_form_get_entry_by_id($edit_entry_id);
if ($entry && $entry->form_id == $selected_form_id) {
$custom_fields = go_form_get_custom_fields($selected_form_id);
global $ranks;
$egd_data = !empty($entry->egd_number) ? go_form_fetch_egd_data($entry->egd_number) : null;
echo '<div style="margin-bottom:20px; padding:15px; background:#fff; border:1px solid #ddd; border-radius:4px;">';
echo '<h3>Edit Entry</h3>';
if (!empty($entry->egd_number) && !$egd_data) {
echo '<div class="notice notice-warning inline"><p>Could not fetch EGD data for PIN ' . esc_html($entry->egd_number) . '.</p></div>';
}
echo '<form method="post" action="' . admin_url('admin-post.php') . '">';
echo wp_nonce_field('go_form_update_entry_action', 'go_form_update_entry_nonce', true, false);
echo '<input type="hidden" name="action" value="go_form_update_entry">';
echo '<input type="hidden" name="entry_id" value="' . esc_attr($entry->id) . '">';
echo '<input type="hidden" name="form_id" value="' . esc_attr($selected_form_id) . '">';
echo '<table class="form-table">';
echo '<tr><th><label for="first_name">First Name*:</label></th><td><input type="text" name="first_name" id="first_name" value="' . esc_attr($entry->first_name) . '" required></td></tr>';
echo '<tr><th><label for="last_name">Last Name*:</label></th><td><input type="text" name="last_name" id="last_name" value="' . esc_attr($entry->last_name) . '" required></td></tr>';
echo '<tr><th><label for="country">Country:</label></th><td><input type="text" name="country" id="country" value="' . esc_attr($entry->country) . '"></td></tr>';
echo '<tr><th><label for="club">Club:</label></th><td><input type="text" name="club" id="club" value="' . esc_attr($entry->club) . '"></td></tr>';
echo '<tr><th><label for="first_name">First Name*:</label></th><td><input type="text" name="first_name" id="first_name" value="' . esc_attr($entry->first_name) . '" required>' . go_form_egd_hint($egd_data['Name'] ?? $egd_data['Real_Name'] ?? null) . '</td></tr>';
echo '<tr><th><label for="last_name">Last Name*:</label></th><td><input type="text" name="last_name" id="last_name" value="' . esc_attr($entry->last_name) . '" required>' . go_form_egd_hint($egd_data['Last_Name'] ?? $egd_data['Real_Last_Name'] ?? null) . '</td></tr>';
echo '<tr><th><label for="country">Country:</label></th><td><input type="text" name="country" id="country" value="' . esc_attr($entry->country) . '">' . go_form_egd_hint($egd_data['Country_Code'] ?? null) . '</td></tr>';
echo '<tr><th><label for="club">Club:</label></th><td><input type="text" name="club" id="club" value="' . esc_attr($entry->club) . '">' . go_form_egd_hint($egd_data['Club'] ?? null) . '</td></tr>';
echo '<tr><th><label for="display_country">Display Country:</label></th><td><input type="text" name="display_country" id="display_country" value="' . esc_attr($entry->display_country) . '"></td></tr>';
echo '<tr><th><label for="display_club">Display Club:</label></th><td><input type="text" name="display_club" id="display_club" value="' . esc_attr($entry->display_club) . '"></td></tr>';
echo '<tr><th><label for="rank">Rank:</label></th><td>';
echo '<select name="rank" id="rank">';
global $ranks;
foreach ($ranks as $value => $label) {
echo '<option value="' . esc_attr($value) . '" ' . selected($entry->rank, $value, false) . '>' . esc_html($label) . '</option>';
}
echo '</select>';
echo go_form_egd_hint(isset($egd_data['Grade_n']) ? ($ranks[intval($egd_data['Grade_n'])] ?? null) : null);
echo '</td></tr>';
echo '<tr><th><label for="rating">Rating:</label></th><td><input type="number" name="rating" id="rating" value="' . esc_attr($entry->rating) . '"></td></tr>';
echo '<tr><th><label for="rating">Rating:</label></th><td><input type="number" name="rating" id="rating" value="' . esc_attr($entry->rating) . '">' . go_form_egd_hint($egd_data['Gor'] ?? null) . '</td></tr>';
echo '<tr><th><label for="egd_number">EGD Number:</label></th><td><input type="text" name="egd_number" id="egd_number" value="' . esc_attr($entry->egd_number) . '"></td></tr>';
// Custom fields
@@ -223,6 +250,7 @@ if (isset($_GET['error']) && $_GET['error'] == 'egd_update_failed')
echo '<input type="hidden" name="action" value="go_form_create_form">';
echo '<table class="form-table">';
echo '<tr><th><label for="form_name">Form Name:</label></th><td><input type="text" name="form_name" id="form_name" required></td></tr>';
echo '<tr><th><label for="form_email">Notification Email:</label></th><td><input type="email" name="form_email" id="form_email" placeholder="Optional email for signup notifications"></td></tr>';
echo '</table>';
echo '<p class="submit"><input type="submit" class="button button-primary" value="Create Form"></p>';
echo '</form>';
@@ -232,7 +260,11 @@ if (isset($_GET['error']) && $_GET['error'] == 'egd_update_failed')
foreach ($forms as $f) {
$url = add_query_arg(array('page' => 'go-form-settings', 'form_id' => $f->id), admin_url('admin.php'));
echo '<li><a href="' . esc_url($url) . '">' . esc_html($f->name) . '</a> <span style="color:#888">(ID: ' . esc_html($f->id) . ')</span> - <small>Shortcode: <code>[go_form id=' . esc_html($f->id) . ']</code></small></li>';
echo '<li><a href="' . esc_url($url) . '">' . esc_html($f->name) . '</a> <span style="color:#888">(ID: ' . esc_html($f->id) . ')</span> - <small>Shortcode: <code>[go_form id=' . esc_html($f->id) . ']</code></small>';
if (!empty($f->email)) {
echo ' - <span style="color:#2271b1;">Email: ' . esc_html($f->email) . '</span>';
}
echo '</li>';
}
echo '</ul>';
+30 -14
View File
@@ -1,12 +1,20 @@
<div class="go-form-table-container" style="overflow-x: auto; -webkit-overflow-scrolling: touch;">
<table class="wp-list-table widefat striped">
<thead>
<tr>
<th>N</th>
<th></th>
<th>First Name</th>
<th>Last Name</th>
<th>Rank</th>
<?php if ($show_admin): ?>
<th>Rating</th>
<?php endif; ?>
<th>Country</th>
<th>Club</th>
<th>Rank</th>
<?php if ($show_admin): ?>
<th>Country (raw)</th>
<th>Club (raw)</th>
<?php endif; ?>
<th>EGD Number</th>
<th>Date Added</th>
<?php
@@ -16,11 +24,10 @@
echo '<th>' . esc_html($field->field_name) . '</th>';
endif;
endforeach;
?>
<?php if ($show_admin): ?>
<th>Rating</th>
<th>Action</th>
<?php endif; ?>
if ($show_admin):
echo '<th>Action</th>';
endif; ?>
</tr>
</thead>
<tbody>
@@ -31,10 +38,19 @@
<td> <?= $i + 1 ?> </td>
<td> <?= esc_html($e->first_name) ?> </td>
<td> <?= esc_html($e->last_name) ?> </td>
<td> <?= esc_html($ranks[$e->rank]) ?> </td>
<?php if ($show_admin): ?>
<td> <?= esc_html($e->rating) ?> </td>
<?php endif; ?>
<td> <?= esc_html($e->display_country) ?> </td>
<td> <?= esc_html($e->display_club) ?> </td>
<?php if ($show_admin): ?>
<td> <?= esc_html($e->country) ?> </td>
<td> <?= esc_html($e->club) ?> </td>
<td> <?= esc_html($ranks[$e->rank]) ?> </td>
<td><a href="https://europeangodatabase.eu/EGD/Player_Card.php?&key=<?= esc_html($e->egd_number) ?>"><?= esc_html($e->egd_number) ?> </a> </td>
<?php endif; ?>
<td><a
href="<?= esc_url('https://europeangodatabase.eu/EGD/Player_Card.php?&key=' . $e->egd_number) ?>"><?= esc_html($e->egd_number) ?>
</a> </td>
<td> <?= esc_html($e->created_at) ?> </td>
<?php
// Display custom field values
@@ -54,16 +70,16 @@
<?php if ($show_admin): ?>
<td> <?= esc_html($e->rating) ?> </td>
<td>
<a href="<?= add_query_arg(array('page' => 'go-form-settings', 'form_id' => $form_id ?? 0, 'edit_entry' => $e->id), admin_url('admin.php')) ?>" class="button button-small">Edit</a>
<?php action_button('go_form_delete_entry', 'Delete', 'Delete this entry?', $e->id); ?>
<td style="white-space: nowrap;">
<a href="<?= add_query_arg(array('page' => 'go-form-settings', 'form_id' => $form_id ?? 0, 'edit_entry' => $e->id), admin_url('admin.php')) ?>"
class="button" style="margin-right: 4px;">Edit</a>
<span style="display: inline-block;"><?php action_button('go_form_delete_entry', 'Delete', 'Delete this entry?', $e->id); ?></span>
</td>
<?php endif; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
+1 -1
View File
@@ -2,7 +2,7 @@
/**
* Plugin Name: Go Form Plugin
* Description: Form plugin for Go players
* Version: 0.05
* Version: 0.07
* Author: Nikola Petrov
*/
+32
View File
@@ -0,0 +1,32 @@
version: "3.8"
services:
db:
image: docker.io/mariadb:latest
container_name: wordpress_db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: mysupersecurepass
MYSQL_PASSWORD: mysupersecurepass
MYSQL_DATABASE: wordpress_db
MYSQL_USER: justbeauniqueuser
volumes:
- ./database:/var/lib/mysql
ports:
- "3306:3306"
wordpress:
image: docker.io/wordpress:latest
container_name: wordpress
restart: unless-stopped
depends_on:
- db
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress_db
WORDPRESS_DB_USER: justbeauniqueuser
WORDPRESS_DB_PASSWORD: mysupersecurepass
volumes:
- ./html:/var/www/html
ports:
- "8090:80"
-16
View File
@@ -1,16 +0,0 @@
#!/bin/bash
DB_NAME='wordpress_db'
DB_PASS='mysupersecurepass'
DB_USER='justbeauniqueuser'
POD_NAME='wordpress_with_mariadb'
CONTAINER_NAME_DB='wordpress_db'
CONTAINER_NAME_WP='wordpress'
# Stop and remove containers
podman stop $CONTAINER_NAME_DB $CONTAINER_NAME_WP || true
podman rm $CONTAINER_NAME_DB $CONTAINER_NAME_WP || true
# Remove pod
podman pod rm -f $POD_NAME || true
echo "removed pods"
-43
View File
@@ -1,43 +0,0 @@
#!/bin/bash
# restart_wp.sh - Fully restart WordPress pod and containers
DB_NAME='wordpress_db'
DB_PASS='mysupersecurepass'
DB_USER='justbeauniqueuser'
POD_NAME='wordpress_with_mariadb'
CONTAINER_NAME_DB='wordpress_db'
CONTAINER_NAME_WP='wordpress'
# Stop and remove containers
podman stop $CONTAINER_NAME_DB $CONTAINER_NAME_WP || true
podman rm $CONTAINER_NAME_DB $CONTAINER_NAME_WP || true
# Remove pod
podman pod rm -f $POD_NAME || true
echo "removed pods"
#exit 0
# Recreate pod
podman pod create -n $POD_NAME -p 8090:80 -p 3306:3306
# Start MariaDB
podman run --detach --pod $POD_NAME \
-e MYSQL_ROOT_PASSWORD=$DB_PASS \
-e MYSQL_PASSWORD=$DB_PASS \
-e MYSQL_DATABASE=$DB_NAME \
-e MYSQL_USER=$DB_USER \
--name $CONTAINER_NAME_DB -v "$PWD/database":/var/lib/mysql \
docker.io/mariadb:latest
# Start WordPress
podman run --detach --pod $POD_NAME \
-e WORDPRESS_DB_HOST=127.0.0.1:3306 \
-e WORDPRESS_DB_NAME=$DB_NAME \
-e WORDPRESS_DB_USER=$DB_USER \
-e WORDPRESS_DB_PASSWORD=$DB_PASS \
--name $CONTAINER_NAME_WP -v "$PWD/html":/var/www/html \
docker.io/wordpress
echo "WordPress restarted on http://localhost:8090"
-44
View File
@@ -1,44 +0,0 @@
# Source - https://stackoverflow.com/a/74956385
# Posted by tiemco
# Retrieved 2026-05-04, License - CC BY-SA 4.0
#!/bin/bash
# https://stackoverflow.com/questions/74054932/how-to-install-and-setup-wordpress-using-podman
# Set environment variables:
DB_NAME='wordpress_db'
DB_PASS='mysupersecurepass'
DB_USER='justbeauniqueuser'
POD_NAME='wordpress_with_mariadb'
CONTAINER_NAME_DB='wordpress_db'
CONTAINER_NAME_WP='wordpress'
mkdir -p html
mkdir -p database
# Remove previous attempts
podman pod rm -f $POD_NAME
# Pull before run, bc: invalid reference format error
podman pull docker.io/mariadb:latest
podman pull docker.io/wordpress
# Create a pod instead of --link.
# So both containers are able to reach each others.
podman pod create -n $POD_NAME -p 8090:80 -p 3306:3306
podman run --detach --pod $POD_NAME \
-e MYSQL_ROOT_PASSWORD=$DB_PASS \
-e MYSQL_PASSWORD=$DB_PASS \
-e MYSQL_DATABASE=$DB_NAME \
-e MYSQL_USER=$DB_USER \
--name $CONTAINER_NAME_DB -v "$PWD/database":/var/lib/mysql \
docker.io/mariadb:latest
podman run --detach --pod $POD_NAME \
-e WORDPRESS_DB_HOST=127.0.0.1:3306 \
-e WORDPRESS_DB_NAME=$DB_NAME \
-e WORDPRESS_DB_USER=$DB_USER \
-e WORDPRESS_DB_PASSWORD=$DB_PASS \
--name $CONTAINER_NAME_WP -v "$PWD/html":/var/www/html \
docker.io/wordpress
-4
View File
@@ -1,4 +0,0 @@
#!/bin/bash
POD_NAME='wordpress_with_mariadb'
podman pod start $POD_NAME
-4
View File
@@ -1,4 +0,0 @@
#!/bin/bash
POD_NAME='wordpress_with_mariadb'
podman pod stop $POD_NAME