Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7c6eaa895d | |||
| f5a48a62db | |||
| 529dd442b5 | |||
| 13a4ee0ae7 | |||
| 9ef421eeb5 | |||
| 38a3a2153b | |||
| 851c9d3674 | |||
| ed67849629 | |||
| cdda18f6de | |||
| 5c287eceba | |||
| 2d537f07dd | |||
| bd7b9e1731 | |||
| 8b54aff9ac |
121
README.md
121
README.md
@@ -2,6 +2,8 @@
|
||||
|
||||
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
|
||||
@@ -10,7 +12,11 @@ A WordPress plugin for managing Go (Baduk/Weiqi) tournament registrations. Colle
|
||||
- **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, and export entries
|
||||
- **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
|
||||
|
||||
@@ -34,12 +40,15 @@ Replace `1` with your form ID. Find form IDs in the admin settings page.
|
||||
|
||||
Navigate to **Go Form** in the WordPress admin menu to:
|
||||
|
||||
- **Create Forms** - Add new registration forms
|
||||
- **Manage Forms** - View all forms with their shortcodes
|
||||
- **View Entries** - See all submissions for a form
|
||||
- **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 (cannot delete default form)
|
||||
- **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
|
||||
|
||||
@@ -63,12 +72,23 @@ Players can click the "Search EGD" button on the frontend form to look up their
|
||||
|
||||
## Database
|
||||
|
||||
The plugin creates two tables:
|
||||
The plugin creates four tables:
|
||||
|
||||
- `wp_go_form_forms` - Stores form definitions
|
||||
- `wp_go_form_entries` - Stores all player registrations
|
||||
- `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
|
||||
|
||||
Both tables are automatically removed when the plugin is uninstalled.
|
||||
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
|
||||
|
||||
@@ -86,30 +106,89 @@ Both tables are automatically removed when the plugin is uninstalled.
|
||||
| Club | Yes | Club name |
|
||||
| Rank | Yes | Go rank (30k to 9p) |
|
||||
| Rating | No | EGD rating (auto-calculated from rank if missing) |
|
||||
| Email | No | Email address |
|
||||
| EGD Number | No | European Go Database PIN |
|
||||
| Comment | No | Additional notes |
|
||||
|
||||
## Hooks
|
||||
|
||||
### Actions
|
||||
|
||||
- `admin_post_go_form_handle_submission` - Form submission handler
|
||||
- `admin_post_go_form_delete_entry` - Delete entry handler
|
||||
- `admin_post_go_form_create_form` - Create form handler
|
||||
- `admin_post_go_form_delete_form` - Delete form handler
|
||||
**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 export handler
|
||||
- `admin_post_go_form_export_opengotha` - OpenGotha export handler
|
||||
- `admin_post_go_form_export_mcmahon` - McMahon 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
|
||||
- Direct file access is blocked
|
||||
- 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
|
||||
Nikola Petrov - nikola@petrovv.com
|
||||
|
||||
## License
|
||||
|
||||
MIT License - See LICENSE file for details.
|
||||
|
||||
53
go-form-plugin/database-schema.sql
Normal file
53
go-form-plugin/database-schema.sql
Normal file
@@ -0,0 +1,53 @@
|
||||
-- ========== Original Plugin Tables ==========
|
||||
|
||||
CREATE TABLE wp_go_form_forms (
|
||||
id int NOT NULL AUTO_INCREMENT,
|
||||
name varchar(255) NOT NULL,
|
||||
created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE wp_go_form_entries (
|
||||
id int NOT NULL AUTO_INCREMENT,
|
||||
form_id int DEFAULT 1,
|
||||
first_name varchar(100) NOT NULL,
|
||||
last_name varchar(100) NOT NULL,
|
||||
country varchar(100) DEFAULT NULL,
|
||||
club varchar(100) DEFAULT NULL,
|
||||
rank tinyint(2) DEFAULT 0,
|
||||
rating smallint(5) DEFAULT 0,
|
||||
egd_number varchar(20) DEFAULT NULL,
|
||||
created_at date DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (form_id) REFERENCES wp_go_form_forms(id) ON DELETE CASCADE,
|
||||
INDEX (form_id),
|
||||
INDEX (egd_number)
|
||||
);
|
||||
|
||||
-- ========== Custom Fields Tables ==========
|
||||
|
||||
CREATE TABLE wp_go_form_custom_fields (
|
||||
id int NOT NULL AUTO_INCREMENT,
|
||||
form_id int NOT NULL,
|
||||
field_name varchar(100) NOT NULL,
|
||||
field_type enum('select','text','checkbox', 'email', 'textarea') NOT NULL DEFAULT 'text',
|
||||
field_options text,
|
||||
is_public tinyint(1) NOT NULL DEFAULT 0,
|
||||
is_required tinyint(1) NOT NULL DEFAULT 0,
|
||||
is_full_width tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (form_id) REFERENCES wp_go_form_forms(id) ON DELETE CASCADE,
|
||||
INDEX (form_id)
|
||||
);
|
||||
|
||||
CREATE TABLE wp_go_form_entry_custom_values (
|
||||
id int NOT NULL AUTO_INCREMENT,
|
||||
entry_id int NOT NULL,
|
||||
field_id int NOT NULL,
|
||||
value text,
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (entry_id) REFERENCES wp_go_form_entries(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (field_id) REFERENCES wp_go_form_custom_fields(id) ON DELETE CASCADE,
|
||||
INDEX (entry_id),
|
||||
INDEX (field_id)
|
||||
);
|
||||
@@ -10,28 +10,41 @@ $form_id = intval($_POST['value_one']);
|
||||
$form = go_form_get_form_by_id($form_id);
|
||||
$form_name = $form ? $form->name : 'Unknown Form';
|
||||
$entries = go_form_get_entries($form_id);
|
||||
$custom_fields = go_form_get_custom_fields($form_id);
|
||||
|
||||
header('Content-Type: text/csv; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename="go-form-' . sanitize_title($form_name) . '-export.csv"');
|
||||
|
||||
$output = fopen('php://output', 'w');
|
||||
fputcsv($output, ['ID', 'First Name', 'Last Name', 'Country', 'Club', 'Rank', 'Rating', 'Email', 'EGD Number', 'Comment', 'Date Added']);
|
||||
|
||||
foreach ($entries as $e) {
|
||||
// Build header row
|
||||
$header = ['N', 'First Name', 'Last Name', 'Country', 'Club', 'Rank', 'Rating', 'EGD Number', 'Date Added'];
|
||||
foreach ($custom_fields as $field) {
|
||||
$header[] = $field->field_name;
|
||||
}
|
||||
fputcsv($output, $header);
|
||||
|
||||
foreach ($entries as $i => $e) {
|
||||
global $ranks;
|
||||
fputcsv($output, [
|
||||
$e->id,
|
||||
$row = [
|
||||
$i,
|
||||
$e->first_name,
|
||||
$e->last_name,
|
||||
$e->country,
|
||||
$e->club,
|
||||
$ranks[$e->rank] ?? '',
|
||||
$e->rating,
|
||||
$e->email,
|
||||
$e->egd_number,
|
||||
$e->comment,
|
||||
$e->created_at
|
||||
]);
|
||||
];
|
||||
|
||||
// Add custom field values
|
||||
foreach ($custom_fields as $field) {
|
||||
$value = go_form_get_custom_value($e->id, $field->id);
|
||||
$row[] = $value;
|
||||
}
|
||||
|
||||
fputcsv($output, $row);
|
||||
}
|
||||
|
||||
fclose($output);
|
||||
@@ -3,16 +3,16 @@ $mcmahonfirst = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<Tournament typeversion="9">
|
||||
<NumberOfRounds>5</NumberOfRounds>
|
||||
<CurrentRoundNumber>1</CurrentRoundNumber>
|
||||
<TakeCurrentRoundInAccount>false</TakeCurrentRoundInAccount>
|
||||
<TakeCurrentRoundInAccount>true</TakeCurrentRoundInAccount>
|
||||
<DefaultAsianName>false</DefaultAsianName>
|
||||
<RatingAllowed>false</RatingAllowed>
|
||||
<RatingLowestOneDanRating>2050</RatingLowestOneDanRating>
|
||||
<RatingDeterminesRank>false</RatingDeterminesRank>
|
||||
<RatingDeterminesStartScore>false</RatingDeterminesStartScore>
|
||||
<LowerMacMahonBar>false</LowerMacMahonBar>
|
||||
<LowerMacMahonBarLevel>35k</LowerMacMahonBarLevel>
|
||||
<UpperMacMahonBar>false</UpperMacMahonBar>
|
||||
<UpperMacMahonBarLevel>9d</UpperMacMahonBarLevel>
|
||||
<LowerMacMahonBar>true</LowerMacMahonBar>
|
||||
<LowerMacMahonBarLevel>10k</LowerMacMahonBarLevel>
|
||||
<UpperMacMahonBar>true</UpperMacMahonBar>
|
||||
<UpperMacMahonBarLevel>2k</UpperMacMahonBarLevel>
|
||||
<UpperMacMahonBarRating>0</UpperMacMahonBarRating>
|
||||
<ByeShouldResultInZeroSOSetc>false</ByeShouldResultInZeroSOSetc>
|
||||
<HalfScoreGroupsRoundDown>false</HalfScoreGroupsRoundDown>
|
||||
@@ -21,9 +21,9 @@ $mcmahonfirst = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<OnlineEgdSupport>true</OnlineEgdSupport>
|
||||
<OnlineEgdSupportByPin>false</OnlineEgdSupportByPin>
|
||||
<HandicapUsed>true</HandicapUsed>
|
||||
<HandicapBelow>true</HandicapBelow>
|
||||
<HandicapBelow>false</HandicapBelow>
|
||||
<HandicapBelowLevel>1d</HandicapBelowLevel>
|
||||
<HandicapByLevel>false</HandicapByLevel>
|
||||
<HandicapByLevel>true</HandicapByLevel>
|
||||
<HandicapAdjustment>true</HandicapAdjustment>
|
||||
<HandicapAdjustmentValue>-2</HandicapAdjustmentValue>
|
||||
<HandicapLimit>true</HandicapLimit>
|
||||
@@ -39,9 +39,9 @@ $mcmahonfirst = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<PairingsShortNotationForLevel>false</PairingsShortNotationForLevel>
|
||||
<PairingsShowScores>false</PairingsShowScores>
|
||||
<PairingsShowHandicaps>true</PairingsShowHandicaps>
|
||||
<PairingsFontsize>12</PairingsFontsize>
|
||||
<PairingsBlackColumnWidth>205</PairingsBlackColumnWidth>
|
||||
<PairingsWhiteColumnWidth>205</PairingsWhiteColumnWidth>
|
||||
<PairingsFontsize>18</PairingsFontsize>
|
||||
<PairingsBlackColumnWidth>283</PairingsBlackColumnWidth>
|
||||
<PairingsWhiteColumnWidth>301</PairingsWhiteColumnWidth>
|
||||
<ImportEncoding>UTF-8</ImportEncoding>
|
||||
<ExportColumnDelimiter><![CDATA[f]]></ExportColumnDelimiter>
|
||||
<ExportWalllistShowTournamentTitle>true</ExportWalllistShowTournamentTitle>
|
||||
@@ -95,13 +95,13 @@ $mcmahonfirst = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<ShowColors>false</ShowColors>
|
||||
<ShowHandicap>true</ShowHandicap>
|
||||
<ShowWarningMissingPairing>true</ShowWarningMissingPairing>
|
||||
<Fontsize>12</Fontsize>
|
||||
<NameColumnWidth>205</NameColumnWidth>
|
||||
<Fontsize>18</Fontsize>
|
||||
<NameColumnWidth>221</NameColumnWidth>
|
||||
<ClubColumnWidth>0</ClubColumnWidth>
|
||||
<ClubColumnAlignmentCenter>true</ClubColumnAlignmentCenter>
|
||||
<WeakSortCriteria>1</WeakSortCriteria>
|
||||
<SortCriterionDescriptor typeversion="2">
|
||||
<ShortName>ScoreX</ShortName>
|
||||
<ShortName>Score</ShortName>
|
||||
</SortCriterionDescriptor>
|
||||
<SortCriterionDescriptor typeversion="2">
|
||||
<ShortName>SOS</ShortName>
|
||||
@@ -109,6 +109,9 @@ $mcmahonfirst = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<SortCriterionDescriptor typeversion="2">
|
||||
<ShortName>SOSOS</ShortName>
|
||||
</SortCriterionDescriptor>
|
||||
<SortCriterionDescriptor typeversion="2">
|
||||
<ShortName>ScoreX</ShortName>
|
||||
</SortCriterionDescriptor>
|
||||
</Walllist>
|
||||
<Country typeversion="1">
|
||||
<InternetCode>ac</InternetCode>
|
||||
@@ -1989,10 +1992,6 @@ $mcmahonfirst = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<Country typeversion="1">
|
||||
<InternetCode>si</InternetCode>
|
||||
<Name>Slovenia</Name>
|
||||
<Club typeversion="1">
|
||||
<Name>Ljub</Name>
|
||||
<EGDName>Ljub</EGDName>
|
||||
</Club>
|
||||
</Country>
|
||||
<Country typeversion="1">
|
||||
<InternetCode>sj</InternetCode>
|
||||
@@ -2193,23 +2192,22 @@ $mcmahonfirst = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
$mcmahonlast = '<TournamentRound typeversion="2">
|
||||
<RoundNumber>1</RoundNumber>
|
||||
<LastUpdated>2026-05-06 22:15:42</LastUpdated>
|
||||
<LastUpdated>2026-05-13 21:30:31</LastUpdated>
|
||||
</TournamentRound>
|
||||
<TournamentRound typeversion="2">
|
||||
<RoundNumber>2</RoundNumber>
|
||||
<LastUpdated>2026-05-06 22:15:42</LastUpdated>
|
||||
<LastUpdated>2026-05-13 21:30:21</LastUpdated>
|
||||
</TournamentRound>
|
||||
<TournamentRound typeversion="2">
|
||||
<RoundNumber>3</RoundNumber>
|
||||
<LastUpdated>2026-05-06 22:15:42</LastUpdated>
|
||||
<LastUpdated>2026-05-13 21:30:10</LastUpdated>
|
||||
</TournamentRound>
|
||||
<TournamentRound typeversion="2">
|
||||
<RoundNumber>4</RoundNumber>
|
||||
<LastUpdated>2026-05-06 22:15:42</LastUpdated>
|
||||
<LastUpdated>2026-05-13 21:29:20</LastUpdated>
|
||||
</TournamentRound>
|
||||
<TournamentRound typeversion="2">
|
||||
<RoundNumber>5</RoundNumber>
|
||||
<LastUpdated>2026-05-06 22:15:42</LastUpdated>
|
||||
<LastUpdated>2026-05-13 21:29:04</LastUpdated>
|
||||
</TournamentRound>
|
||||
</Tournament>
|
||||
';
|
||||
</Tournament>';
|
||||
@@ -11,35 +11,65 @@ function go_form_activate()
|
||||
$charset = $wpdb->get_charset_collate();
|
||||
$forms = $wpdb->prefix . 'go_form_forms';
|
||||
$entries = $wpdb->prefix . 'go_form_entries';
|
||||
$custom_fields = $wpdb->prefix . 'go_form_custom_fields';
|
||||
$custom_values = $wpdb->prefix . 'go_form_entry_custom_values';
|
||||
|
||||
dbDelta("CREATE TABLE $forms (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
id int NOT NULL AUTO_INCREMENT,
|
||||
name varchar(255) NOT NULL,
|
||||
created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) $charset;");
|
||||
|
||||
dbDelta("CREATE TABLE $entries (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
form_id mediumint(9) DEFAULT 1,
|
||||
id int NOT NULL AUTO_INCREMENT,
|
||||
form_id int DEFAULT 1,
|
||||
first_name varchar(100) NOT NULL,
|
||||
last_name varchar(100) NOT NULL,
|
||||
country varchar(100) DEFAULT NULL,
|
||||
club varchar(100) DEFAULT NULL,
|
||||
rank tinyint(2) DEFAULT 0,
|
||||
rating smallint(5) DEFAULT 0,
|
||||
email varchar(255) DEFAULT NULL,
|
||||
egd_number varchar(20) DEFAULT NULL,
|
||||
comment text DEFAULT NULL,
|
||||
created_at date DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (form_id) REFERENCES $forms(id) ON DELETE CASCADE
|
||||
FOREIGN KEY (form_id) REFERENCES $forms(id) ON DELETE CASCADE,
|
||||
INDEX (form_id),
|
||||
INDEX (egd_number)
|
||||
) $charset;");
|
||||
|
||||
dbDelta("CREATE TABLE $custom_fields (
|
||||
id int NOT NULL AUTO_INCREMENT,
|
||||
form_id int NOT NULL,
|
||||
field_name varchar(100) NOT NULL,
|
||||
field_type enum('select','text','checkbox', 'email', 'textarea') NOT NULL DEFAULT 'text',
|
||||
field_options text,
|
||||
is_public tinyint(1) NOT NULL DEFAULT 0,
|
||||
is_required tinyint(1) NOT NULL DEFAULT 0,
|
||||
is_full_width tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (form_id) REFERENCES $forms(id) ON DELETE CASCADE,
|
||||
INDEX (form_id)
|
||||
) $charset;");
|
||||
|
||||
dbDelta("CREATE TABLE $custom_values (
|
||||
id int NOT NULL AUTO_INCREMENT,
|
||||
entry_id int NOT NULL,
|
||||
field_id int NOT NULL,
|
||||
value text,
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (entry_id) REFERENCES $entries(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (field_id) REFERENCES $custom_fields(id) ON DELETE CASCADE,
|
||||
INDEX (entry_id),
|
||||
INDEX (field_id)
|
||||
) $charset;");
|
||||
}
|
||||
|
||||
function go_form_uninstall()
|
||||
{
|
||||
global $wpdb;
|
||||
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}go_form_entry_custom_values");
|
||||
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}go_form_custom_fields");
|
||||
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}go_form_entries");
|
||||
$wpdb->query("DROP TABLE IF EXISTS {$wpdb->prefix}go_form_forms");
|
||||
}
|
||||
@@ -78,13 +108,62 @@ function go_form_get_entries($form_id)
|
||||
));
|
||||
}
|
||||
|
||||
function go_form_render_entries_table($entries, $show_admin = false)
|
||||
function go_form_render_entries_table($entries, $show_admin = false, $custom_fields = [], $form_id = 0)
|
||||
{
|
||||
global $ranks;
|
||||
|
||||
include "templates/table.php";
|
||||
}
|
||||
|
||||
// ========== Custom Fields Helpers ==========
|
||||
function go_form_get_custom_fields($form_id)
|
||||
{
|
||||
global $wpdb;
|
||||
return $wpdb->get_results($wpdb->prepare(
|
||||
"SELECT * FROM {$wpdb->prefix}go_form_custom_fields WHERE form_id = %d ORDER BY id ASC",
|
||||
$form_id
|
||||
));
|
||||
}
|
||||
|
||||
function go_form_get_custom_field_by_id($field_id)
|
||||
{
|
||||
global $wpdb;
|
||||
return $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT * FROM {$wpdb->prefix}go_form_custom_fields WHERE id = %d",
|
||||
$field_id
|
||||
));
|
||||
}
|
||||
|
||||
function go_form_get_custom_values($entry_id)
|
||||
{
|
||||
global $wpdb;
|
||||
return $wpdb->get_results($wpdb->prepare(
|
||||
"SELECT cf.*, cv.value FROM {$wpdb->prefix}go_form_custom_fields cf
|
||||
JOIN {$wpdb->prefix}go_form_entry_custom_values cv ON cf.id = cv.field_id
|
||||
WHERE cv.entry_id = %d",
|
||||
$entry_id
|
||||
));
|
||||
}
|
||||
|
||||
function go_form_get_custom_value($entry_id, $field_id)
|
||||
{
|
||||
global $wpdb;
|
||||
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
|
||||
));
|
||||
}
|
||||
|
||||
function go_form_get_entry_by_id($entry_id)
|
||||
{
|
||||
global $wpdb;
|
||||
return $wpdb->get_row($wpdb->prepare(
|
||||
"SELECT * FROM {$wpdb->prefix}go_form_entries WHERE id = %d",
|
||||
$entry_id
|
||||
));
|
||||
}
|
||||
|
||||
// ========== Form Handling ==========
|
||||
function go_form_handle_submission()
|
||||
{
|
||||
@@ -113,9 +192,7 @@ function go_form_handle_submission()
|
||||
'club' => sanitize_text_field($_POST['club'] ?? ''),
|
||||
'rank' => $rank,
|
||||
'rating' => $rating,
|
||||
'email' => sanitize_email($_POST['email'] ?? ''),
|
||||
'egd_number' => sanitize_text_field($_POST['egd_number'] ?? ''),
|
||||
'comment' => sanitize_textarea_field($_POST['comment'] ?? '')
|
||||
];
|
||||
|
||||
if (empty($data['first_name']) || empty($data['last_name'])) {
|
||||
@@ -124,6 +201,34 @@ function go_form_handle_submission()
|
||||
}
|
||||
|
||||
$wpdb->insert("{$wpdb->prefix}go_form_entries", $data);
|
||||
$entry_id = $wpdb->insert_id;
|
||||
|
||||
// Save custom field values
|
||||
$custom_fields = go_form_get_custom_fields($form_id);
|
||||
foreach ($custom_fields as $field) {
|
||||
$field_name = 'custom_field_' . $field->id;
|
||||
if (isset($_POST[$field_name])) {
|
||||
$value = $_POST[$field_name];
|
||||
if ($field->field_type === 'checkbox') {
|
||||
$value = isset($_POST[$field_name]) ? '1' : '0';
|
||||
} elseif (is_array($value)) {
|
||||
$value = implode(',', array_map('sanitize_text_field', $value));
|
||||
} else {
|
||||
$value = sanitize_text_field($value);
|
||||
}
|
||||
$wpdb->insert("{$wpdb->prefix}go_form_entry_custom_values", [
|
||||
'entry_id' => $entry_id,
|
||||
'field_id' => $field->id,
|
||||
'value' => $value
|
||||
]);
|
||||
} elseif ($field->is_required) {
|
||||
// If required field is missing, delete the entry and redirect back
|
||||
$wpdb->delete("{$wpdb->prefix}go_form_entries", ['id' => $entry_id]);
|
||||
wp_redirect($_SERVER['HTTP_REFERER']);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
wp_redirect($_SERVER['HTTP_REFERER']);
|
||||
exit;
|
||||
}
|
||||
@@ -237,6 +342,221 @@ function go_form_export_mcmahon()
|
||||
}
|
||||
add_action('admin_post_go_form_export_mcmahon', 'go_form_export_mcmahon');
|
||||
|
||||
// ========== Custom Field Admin Actions ==========
|
||||
function go_form_create_custom_field()
|
||||
{
|
||||
go_form_admin_action('create_custom_field');
|
||||
if (isset($_POST['form_id']) && isset($_POST['field_name']) && isset($_POST['field_type'])) {
|
||||
global $wpdb;
|
||||
$form_id = intval($_POST['form_id']);
|
||||
$field_name = sanitize_text_field($_POST['field_name']);
|
||||
$field_type = sanitize_text_field($_POST['field_type']);
|
||||
$field_options = isset($_POST['field_options']) ? sanitize_textarea_field($_POST['field_options']) : '';
|
||||
$is_public = isset($_POST['is_public']) ? 1 : 0;
|
||||
$is_required = isset($_POST['is_required']) ? 1 : 0;
|
||||
$is_full_width = isset($_POST['is_full_width']) ? 1 : 0;
|
||||
|
||||
$wpdb->insert("{$wpdb->prefix}go_form_custom_fields", [
|
||||
'form_id' => $form_id,
|
||||
'field_name' => $field_name,
|
||||
'field_type' => $field_type,
|
||||
'field_options' => $field_options,
|
||||
'is_public' => $is_public,
|
||||
'is_required' => $is_required,
|
||||
'is_full_width' => $is_full_width
|
||||
]);
|
||||
}
|
||||
$redirect_url = add_query_arg(array('page' => 'go-form-settings', 'form_id' => $_POST['form_id'], 'created_field' => 1), admin_url('admin.php'));
|
||||
wp_redirect($redirect_url);
|
||||
exit;
|
||||
}
|
||||
add_action('admin_post_go_form_create_custom_field', 'go_form_create_custom_field');
|
||||
|
||||
function go_form_update_custom_field()
|
||||
{
|
||||
go_form_admin_action('update_custom_field');
|
||||
if (isset($_POST['field_id']) && isset($_POST['field_name']) && isset($_POST['field_type'])) {
|
||||
global $wpdb;
|
||||
$field_id = intval($_POST['field_id']);
|
||||
$field_name = sanitize_text_field($_POST['field_name']);
|
||||
$field_type = sanitize_text_field($_POST['field_type']);
|
||||
$field_options = isset($_POST['field_options']) ? sanitize_textarea_field($_POST['field_options']) : '';
|
||||
$is_public = isset($_POST['is_public']) ? 1 : 0;
|
||||
$is_required = isset($_POST['is_required']) ? 1 : 0;
|
||||
$is_full_width = isset($_POST['is_full_width']) ? 1 : 0;
|
||||
|
||||
$wpdb->update("{$wpdb->prefix}go_form_custom_fields", [
|
||||
'field_name' => $field_name,
|
||||
'field_type' => $field_type,
|
||||
'field_options' => $field_options,
|
||||
'is_public' => $is_public,
|
||||
'is_required' => $is_required,
|
||||
'is_full_width' => $is_full_width
|
||||
], ['id' => $field_id]);
|
||||
}
|
||||
$redirect_url = add_query_arg(array('page' => 'go-form-settings', 'form_id' => $_POST['form_id'], 'updated_field' => 1), admin_url('admin.php'));
|
||||
wp_redirect($redirect_url);
|
||||
exit;
|
||||
}
|
||||
add_action('admin_post_go_form_update_custom_field', 'go_form_update_custom_field');
|
||||
|
||||
function go_form_delete_custom_field()
|
||||
{
|
||||
go_form_admin_action('delete_custom_field');
|
||||
if (isset($_POST['value_one'])) {
|
||||
global $wpdb;
|
||||
$field_id = intval($_POST['value_one']);
|
||||
$field = go_form_get_custom_field_by_id($field_id);
|
||||
$form_id = $field ? $field->form_id : 0;
|
||||
$wpdb->delete("{$wpdb->prefix}go_form_custom_fields", ['id' => $field_id]);
|
||||
$redirect_url = add_query_arg(array('page' => 'go-form-settings', 'form_id' => $form_id, 'deleted_field' => 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_delete_custom_field', 'go_form_delete_custom_field');
|
||||
|
||||
// ========== Entry Edit Admin Action ==========
|
||||
function go_form_update_egd_data()
|
||||
{
|
||||
go_form_admin_action('update_egd_data');
|
||||
|
||||
if (!isset($_POST['value_one'])) {
|
||||
wp_redirect(admin_url('admin.php?page=go-form-settings'));
|
||||
exit;
|
||||
}
|
||||
|
||||
global $wpdb, $ranks;
|
||||
$form_id = intval($_POST['value_one']);
|
||||
$entries = go_form_get_entries($form_id);
|
||||
$updated_count = 0;
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
if (empty($entry->egd_number)) {
|
||||
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)) {
|
||||
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
|
||||
// So we can use Grade_n directly as our rank value
|
||||
$new_rank = isset($data['Grade_n']) ? intval($data['Grade_n']) : $entry->rank;
|
||||
$new_rating = isset($data['Gor']) ? intval($data['Gor']) : $entry->rating;
|
||||
|
||||
// Only update if values changed
|
||||
if ($new_rank !== $entry->rank || $new_rating !== $entry->rating) {
|
||||
$wpdb->update(
|
||||
"{$wpdb->prefix}go_form_entries",
|
||||
['rank' => $new_rank, 'rating' => $new_rating],
|
||||
['id' => $entry->id]
|
||||
);
|
||||
$updated_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$redirect_url = add_query_arg(
|
||||
array('page' => 'go-form-settings', 'form_id' => $form_id, 'egd_updated' => $updated_count),
|
||||
admin_url('admin.php')
|
||||
);
|
||||
wp_redirect($redirect_url);
|
||||
exit;
|
||||
}
|
||||
add_action('admin_post_go_form_update_egd_data', 'go_form_update_egd_data');
|
||||
|
||||
function go_form_update_entry()
|
||||
{
|
||||
go_form_admin_action('update_entry');
|
||||
if (!isset($_POST['entry_id']) || !isset($_POST['form_id'])) {
|
||||
wp_redirect(admin_url('admin.php?page=go-form-settings'));
|
||||
exit;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$entry_id = intval($_POST['entry_id']);
|
||||
$form_id = intval($_POST['form_id']);
|
||||
|
||||
$rating = intval($_POST['rating']);
|
||||
$rank = intval($_POST['rank']);
|
||||
if ($rating < -900) {
|
||||
$rating = ($rank * 100) - 900;
|
||||
}
|
||||
|
||||
$data = [
|
||||
'first_name' => sanitize_text_field($_POST['first_name']),
|
||||
'last_name' => sanitize_text_field($_POST['last_name']),
|
||||
'country' => sanitize_text_field($_POST['country'] ?? ''),
|
||||
'club' => sanitize_text_field($_POST['club'] ?? ''),
|
||||
'rank' => $rank,
|
||||
'rating' => $rating,
|
||||
'egd_number' => sanitize_text_field($_POST['egd_number'] ?? ''),
|
||||
];
|
||||
|
||||
if (empty($data['first_name']) || empty($data['last_name'])) {
|
||||
$redirect_url = add_query_arg(array('page' => 'go-form-settings', 'form_id' => $form_id, 'edit_entry' => $entry_id, 'error' => 'missing_required'), admin_url('admin.php'));
|
||||
wp_redirect($redirect_url);
|
||||
exit;
|
||||
}
|
||||
|
||||
$wpdb->update("{$wpdb->prefix}go_form_entries", $data, ['id' => $entry_id]);
|
||||
|
||||
// Update custom field values
|
||||
$custom_fields = go_form_get_custom_fields($form_id);
|
||||
foreach ($custom_fields as $field) {
|
||||
$field_name = 'custom_field_' . $field->id;
|
||||
if (isset($_POST[$field_name])) {
|
||||
$value = $_POST[$field_name];
|
||||
if ($field->field_type === 'checkbox') {
|
||||
$value = isset($_POST[$field_name]) ? '1' : '0';
|
||||
} elseif (is_array($value)) {
|
||||
$value = implode(',', array_map('sanitize_text_field', $value));
|
||||
} else {
|
||||
$value = sanitize_text_field($value);
|
||||
}
|
||||
|
||||
// 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",
|
||||
['value' => $value],
|
||||
['entry_id' => $entry_id, 'field_id' => $field->id]);
|
||||
} else {
|
||||
$wpdb->insert("{$wpdb->prefix}go_form_entry_custom_values", [
|
||||
'entry_id' => $entry_id,
|
||||
'field_id' => $field->id,
|
||||
'value' => $value
|
||||
]);
|
||||
}
|
||||
} elseif ($field->is_required) {
|
||||
// If required field is missing, redirect back with error
|
||||
$redirect_url = add_query_arg(array('page' => 'go-form-settings', 'form_id' => $form_id, 'edit_entry' => $entry_id, 'error' => 'missing_required_field'), admin_url('admin.php'));
|
||||
wp_redirect($redirect_url);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$redirect_url = add_query_arg(array('page' => 'go-form-settings', 'form_id' => $form_id, 'updated_entry' => 1), admin_url('admin.php'));
|
||||
wp_redirect($redirect_url);
|
||||
exit;
|
||||
}
|
||||
add_action('admin_post_go_form_update_entry', 'go_form_update_entry');
|
||||
|
||||
// ========== Admin Page ====================
|
||||
function go_form_admin_menu()
|
||||
{
|
||||
@@ -248,7 +568,7 @@ function action_button($action, $name, $confirm_massage, $value_one)
|
||||
{
|
||||
echo '
|
||||
<form method="post" action="' . admin_url('admin-post.php') . '">
|
||||
' . wp_nonce_field($action . '_action', $action . '_nonce', true, false) . '
|
||||
' . wp_nonce_field("{$action}_action", "{$action}_nonce", true, false) . '
|
||||
<input type="hidden" name="action" value="' . $action . '">
|
||||
<input type="hidden" name="value_one" value="' . $value_one . '">
|
||||
<input type="submit" value="' . $name . '" class="button" onclick="return confirm(\'' . $confirm_massage . '\')">
|
||||
|
||||
@@ -99,14 +99,90 @@
|
||||
<label for="egd_number">EGD Number:</label><input type="text" name="egd_number" id="egd_number">
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="email">Email:</label><input type="email" name="email" id="email">
|
||||
</div>
|
||||
<?php
|
||||
// Display custom fields
|
||||
$custom_fields = go_form_get_custom_fields($form_id);
|
||||
$full_width_fields = [];
|
||||
$grid_fields = [];
|
||||
|
||||
foreach ($custom_fields as $field) {
|
||||
if ($field->is_full_width) {
|
||||
$full_width_fields[] = $field;
|
||||
} else {
|
||||
$grid_fields[] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
// Render grid fields
|
||||
foreach ($grid_fields as $field):
|
||||
$field_id = 'custom_field_' . $field->id;
|
||||
echo '<div' . ($field->field_type === 'checkbox' ? ' style="grid-column: span 2;"' : '') . '>';
|
||||
echo '<label for="' . esc_attr($field_id) . '">' . esc_html($field->field_name) . ($field->is_required ? '*' : '') . ':</label>';
|
||||
|
||||
switch ($field->field_type) {
|
||||
case 'text':
|
||||
echo '<input type="text" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '"' . ($field->is_required ? ' required' : '') . '>';
|
||||
break;
|
||||
case 'email':
|
||||
echo '<input type="email" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '"' . ($field->is_required ? ' required' : '') . '>';
|
||||
break;
|
||||
case 'textarea':
|
||||
echo '<textarea name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" rows="4" style="width:100%;"' . ($field->is_required ? ' required' : '') . '></textarea>';
|
||||
break;
|
||||
case 'select':
|
||||
$options = $field->field_options ? explode(',', $field->field_options) : [];
|
||||
echo '<select name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '"' . ($field->is_required ? ' required' : '') . '>';
|
||||
echo '<option value="">-- Select --</option>';
|
||||
foreach ($options as $option) {
|
||||
$option = trim($option);
|
||||
echo '<option value="' . esc_attr($option) . '">' . esc_html($option) . '</option>';
|
||||
}
|
||||
echo '</select>';
|
||||
break;
|
||||
case 'checkbox':
|
||||
echo '<input type="checkbox" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" value="1"' . ($field->is_required ? ' required' : '') . '>';
|
||||
break;
|
||||
}
|
||||
echo '</div>';
|
||||
endforeach;
|
||||
?>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<label for="comment">Comment</label>
|
||||
<textarea name="comment" id="comment" rows="3"></textarea>
|
||||
<?php
|
||||
// Render full-width fields outside the grid
|
||||
foreach ($full_width_fields as $field):
|
||||
$field_id = 'custom_field_' . $field->id;
|
||||
echo '<div style="grid-column: 1 / -1; margin-top: 10px;">';
|
||||
echo '<label for="' . esc_attr($field_id) . '">' . esc_html($field->field_name) . ($field->is_required ? '*' : '') . ':</label>';
|
||||
|
||||
switch ($field->field_type) {
|
||||
case 'text':
|
||||
echo '<input type="text" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" style="width:100%;"' . ($field->is_required ? ' required' : '') . '>';
|
||||
break;
|
||||
case 'email':
|
||||
echo '<input type="email" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" style="width:100%;"' . ($field->is_required ? ' required' : '') . '>';
|
||||
break;
|
||||
case 'textarea':
|
||||
echo '<textarea name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" rows="4" style="width:100%;"' . ($field->is_required ? ' required' : '') . '></textarea>';
|
||||
break;
|
||||
case 'select':
|
||||
$options = $field->field_options ? explode(',', $field->field_options) : [];
|
||||
echo '<select name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" style="width:100%;"' . ($field->is_required ? ' required' : '') . '>';
|
||||
echo '<option value="">-- Select --</option>';
|
||||
foreach ($options as $option) {
|
||||
$option = trim($option);
|
||||
echo '<option value="' . esc_attr($option) . '">' . esc_html($option) . '</option>';
|
||||
}
|
||||
echo '</select>';
|
||||
break;
|
||||
case 'checkbox':
|
||||
echo '<input type="checkbox" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" value="1"' . ($field->is_required ? ' required' : '') . '>';
|
||||
break;
|
||||
}
|
||||
echo '</div>';
|
||||
endforeach;
|
||||
?>
|
||||
|
||||
<p>* Required fields</p>
|
||||
<input type="submit" name="go_form_submit" value="Submit">
|
||||
@@ -122,9 +198,10 @@
|
||||
<?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); ?>
|
||||
<?php go_form_render_entries_table($entries, false, $custom_fields, $form_id); ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -7,28 +7,27 @@ 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['created_field']))
|
||||
echo '<div class="notice notice-success"><p>Custom field created!</p></div>';
|
||||
if (isset($_GET['updated_field']))
|
||||
echo '<div class="notice notice-success"><p>Custom field updated!</p></div>';
|
||||
if (isset($_GET['deleted_field']))
|
||||
echo '<div class="notice notice-success"><p>Custom field deleted!</p></div>';
|
||||
if (isset($_GET['updated_entry']))
|
||||
echo '<div class="notice notice-success"><p>Entry updated!</p></div>';
|
||||
if (isset($_GET['egd_updated']))
|
||||
echo '<div class="notice notice-success"><p>' . esc_html($_GET['egd_updated']) . ' entries updated with EGD data!</p></div>';
|
||||
if (isset($_GET['error']) && $_GET['error'] == 'missing_required')
|
||||
echo '<div class="notice notice-error"><p>First Name and Last Name are required!</p></div>';
|
||||
if (isset($_GET['error']) && $_GET['error'] == 'missing_required_field')
|
||||
echo '<div class="notice notice-error"><p>A required custom field is missing!</p></div>';
|
||||
if (isset($_GET['error']) && $_GET['error'] == 'egd_update_failed')
|
||||
echo '<div class="notice notice-error"><p>Failed to update EGD data. Check error logs.</p></div>';
|
||||
?>
|
||||
|
||||
<div class="wrap">
|
||||
<h1>Go Form Settings</h1>
|
||||
|
||||
<h2>Create New Form</h2>
|
||||
<form method="post" action=" <?= admin_url('admin-post.php') ?> ">
|
||||
<?= wp_nonce_field('go_form_create_form_action', 'go_form_create_form_nonce', true, false) ?>
|
||||
<input type="hidden" name="action" value="go_form_create_form">
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th>
|
||||
<label for="form_name">Form Name:</label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="form_name" id="form_name" required>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p class="submit"><input type="submit" class="button button-primary" value="Create Form"></p>
|
||||
</form>
|
||||
|
||||
<h2>Manage Forms & Entries</h2>
|
||||
|
||||
<?php
|
||||
@@ -39,22 +38,195 @@ if (isset($_GET['created']))
|
||||
$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">';
|
||||
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', 'Confrm Export', $selected_form_id);
|
||||
action_button('go_form_export_pairgoth', 'Export to Pairgoth', 'Confrm Export', $selected_form_id);
|
||||
action_button('go_form_export_opengotha', 'Export to Opengoth', 'Confrm Export', $selected_form_id);
|
||||
action_button('go_form_export_mcmahon', 'Export to McMahon', 'Confrm Export', $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_update_egd_data', 'Update EGD Data', 'Update rank and rating from EGD for all entries with EGD numbers?', $selected_form_id);
|
||||
|
||||
echo '</div>';
|
||||
|
||||
// ========== Custom Fields Management ==========
|
||||
$custom_fields = go_form_get_custom_fields($selected_form_id);
|
||||
|
||||
echo '<div style="margin-bottom:20px; padding:15px; background:#f9f9f9; border:1px solid #ddd; border-radius:4px;">';
|
||||
echo '<h3>Custom Fields</h3>';
|
||||
|
||||
// Add new custom field form
|
||||
echo '<details style="margin-bottom:15px;"><summary style="cursor:pointer; font-weight:bold;">Add New Custom Field</summary>';
|
||||
echo '<form method="post" action="' . admin_url('admin-post.php') . '" style="margin-top:10px; padding-left:15px;">';
|
||||
echo wp_nonce_field('go_form_create_custom_field_action', 'go_form_create_custom_field_nonce', true, false);
|
||||
echo '<input type="hidden" name="action" value="go_form_create_custom_field">';
|
||||
echo '<input type="hidden" name="form_id" value="' . esc_attr($selected_form_id) . '">';
|
||||
echo '<table class="form-table">';
|
||||
echo '<tr><th><label for="field_name">Field Name:</label></th><td><input type="text" name="field_name" id="field_name" required></td></tr>';
|
||||
echo '<tr><th><label for="field_type">Field Type:</label></th><td>';
|
||||
echo '<select name="field_type" id="field_type">';
|
||||
echo '<option value="text">Text</option>';
|
||||
echo '<option value="select">Dropdown (Select)</option>';
|
||||
echo '<option value="checkbox">Checkbox</option>';
|
||||
echo '<option value="email">Email</option>';
|
||||
echo '<option value="textarea">Textarea</option>';
|
||||
echo '</select>';
|
||||
echo '</td></tr>';
|
||||
echo '<tr><th><label for="field_options">Options (for select, comma-separated):</label></th><td><textarea name="field_options" id="field_options" rows="2" style="width:100%;"></textarea><small>e.g., Option 1,Option 2,Option 3</small></td></tr>';
|
||||
echo '<tr><th><label for="is_public">Public:</label></th><td><input type="checkbox" name="is_public" id="is_public" value="1" checked> <small>Show on public form</small></td></tr>';
|
||||
echo '<tr><th><label for="is_required">Required:</label></th><td><input type="checkbox" name="is_required" id="is_required" value="1"> <small>Required field</small></td></tr>';
|
||||
echo '<tr><th><label for="is_full_width">Full Width:</label></th><td><input type="checkbox" name="is_full_width" id="is_full_width" value="1"> <small>Display on full width (outside grid)</small></td></tr>';
|
||||
echo '</table>';
|
||||
echo '<p class="submit"><input type="submit" class="button button-primary" value="Add Custom Field"></p>';
|
||||
echo '</form>';
|
||||
echo '</details>';
|
||||
|
||||
// List existing custom fields
|
||||
if (!empty($custom_fields)) {
|
||||
echo '<table class="wp-list-table widefat striped" style="margin-top:15px;">';
|
||||
echo '<thead><tr><th>Field Name</th><th>Type</th><th>Public</th><th>Required</th><th>Full Width</th><th>Actions</th></tr></thead><tbody>';
|
||||
foreach ($custom_fields as $field) {
|
||||
echo '<tr>';
|
||||
echo '<td>' . esc_html($field->field_name) . '</td>';
|
||||
echo '<td>' . esc_html($field->field_type) . '</td>';
|
||||
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>';
|
||||
// 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> ';
|
||||
action_button('go_form_delete_custom_field', 'Delete', 'Delete this custom field?', $field->id);
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
echo '</tbody></table>';
|
||||
} else {
|
||||
echo '<p><em>No custom fields yet.</em></p>';
|
||||
}
|
||||
|
||||
// Edit custom field form
|
||||
if (isset($_GET['edit_field']) && $edit_field_id = intval($_GET['edit_field'])) {
|
||||
$edit_field = go_form_get_custom_field_by_id($edit_field_id);
|
||||
if ($edit_field && $edit_field->form_id == $selected_form_id) {
|
||||
echo '<details open style="margin-top:20px;"><summary style="cursor:pointer; font-weight:bold;">Edit Custom Field</summary>';
|
||||
echo '<form method="post" action="' . admin_url('admin-post.php') . '" style="margin-top:10px; padding-left:15px;">';
|
||||
echo wp_nonce_field('go_form_update_custom_field_action', 'go_form_update_custom_field_nonce', true, false);
|
||||
echo '<input type="hidden" name="action" value="go_form_update_custom_field">';
|
||||
echo '<input type="hidden" name="form_id" value="' . esc_attr($selected_form_id) . '">';
|
||||
echo '<input type="hidden" name="field_id" value="' . esc_attr($edit_field->id) . '">';
|
||||
echo '<table class="form-table">';
|
||||
echo '<tr><th><label for="field_name">Field Name:</label></th><td><input type="text" name="field_name" id="field_name" value="' . esc_attr($edit_field->field_name) . '" required></td></tr>';
|
||||
echo '<tr><th><label for="field_type">Field Type:</label></th><td>';
|
||||
echo '<select name="field_type" id="field_type">';
|
||||
echo '<option value="text"' . selected($edit_field->field_type, 'text', false) . '>Text</option>';
|
||||
echo '<option value="select"' . selected($edit_field->field_type, 'select', false) . '>Dropdown (Select)</option>';
|
||||
echo '<option value="checkbox"' . selected($edit_field->field_type, 'checkbox', false) . '>Checkbox</option>';
|
||||
echo '<option value="email"' . selected($edit_field->field_type, 'email', false) . '>Email</option>';
|
||||
echo '<option value="textarea"' . selected($edit_field->field_type, 'textarea', false) . '>Textarea</option>';
|
||||
echo '</select>';
|
||||
echo '</td></tr>';
|
||||
echo '<tr><th><label for="field_options">Options (for select, comma-separated):</label></th><td><textarea name="field_options" id="field_options" rows="2" style="width:100%;">' . esc_textarea($edit_field->field_options) . '</textarea><small>e.g., Option 1,Option 2,Option 3</small></td></tr>';
|
||||
echo '<tr><th><label for="is_public">Public:</label></th><td><input type="checkbox" name="is_public" id="is_public" value="1" ' . checked($edit_field->is_public, 1, false) . '> <small>Show on public form</small></td></tr>';
|
||||
echo '<tr><th><label for="is_required">Required:</label></th><td><input type="checkbox" name="is_required" id="is_required" value="1" ' . checked($edit_field->is_required, 1, false) . '> <small>Required field</small></td></tr>';
|
||||
echo '<tr><th><label for="is_full_width">Full Width:</label></th><td><input type="checkbox" name="is_full_width" id="is_full_width" value="1" ' . checked($edit_field->is_full_width, 1, false) . '> <small>Display on full width (outside grid)</small></td></tr>';
|
||||
echo '</table>';
|
||||
echo '<p class="submit"><input type="submit" class="button button-primary" value="Update Custom Field"> <a href="' . add_query_arg(array('page' => 'go-form-settings', 'form_id' => $selected_form_id), admin_url('admin.php')) . '" class="button">Cancel</a></p>';
|
||||
echo '</form>';
|
||||
echo '</details>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
|
||||
// ========== Edit Entry Form ==========
|
||||
if (isset($_GET['edit_entry']) && $edit_entry_id = intval($_GET['edit_entry'])) {
|
||||
$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);
|
||||
echo '<div style="margin-bottom:20px; padding:15px; background:#fff; border:1px solid #ddd; border-radius:4px;">';
|
||||
echo '<h3>Edit Entry</h3>';
|
||||
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="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 '</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="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
|
||||
if (!empty($custom_fields)) {
|
||||
foreach ($custom_fields as $field) {
|
||||
$field_id = 'custom_field_' . $field->id;
|
||||
$value = go_form_get_custom_value($entry->id, $field->id);
|
||||
echo '<tr><th><label for="' . esc_attr($field_id) . '">' . esc_html($field->field_name) . ($field->is_required ? '*' : '') . ':</label></th><td>';
|
||||
|
||||
switch ($field->field_type) {
|
||||
case 'text':
|
||||
echo '<input type="text" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" value="' . esc_attr($value) . '"' . ($field->is_required ? ' required' : '') . '>';
|
||||
break;
|
||||
case 'email':
|
||||
echo '<input type="email" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" value="' . esc_attr($value) . '"' . ($field->is_required ? ' required' : '') . '>';
|
||||
break;
|
||||
case 'textarea':
|
||||
echo '<textarea name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" rows="4" style="width:100%;"' . ($field->is_required ? ' required' : '') . '>' . esc_textarea($value) . '</textarea>';
|
||||
break;
|
||||
case 'select':
|
||||
$options = $field->field_options ? explode(',', $field->field_options) : [];
|
||||
echo '<select name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '"' . ($field->is_required ? ' required' : '') . '>';
|
||||
echo '<option value="">-- Select --</option>';
|
||||
foreach ($options as $option) {
|
||||
$option = trim($option);
|
||||
echo '<option value="' . esc_attr($option) . '" ' . selected($value, $option, false) . '>' . esc_html($option) . '</option>';
|
||||
}
|
||||
echo '</select>';
|
||||
break;
|
||||
case 'checkbox':
|
||||
echo '<input type="checkbox" name="' . esc_attr($field_id) . '" id="' . esc_attr($field_id) . '" value="1" ' . checked($value, '1', false) . '>';
|
||||
break;
|
||||
}
|
||||
echo '</td></tr>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</table>';
|
||||
echo '<p class="submit">';
|
||||
echo '<input type="submit" class="button button-primary" value="Update Entry">';
|
||||
echo ' <a href="' . add_query_arg(array('page' => 'go-form-settings', 'form_id' => $selected_form_id), admin_url('admin.php')) . '" class="button">Cancel</a>';
|
||||
echo '</p>';
|
||||
echo '</form>';
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
$entries = go_form_get_entries($selected_form_id);
|
||||
go_form_render_entries_table($entries, true);
|
||||
$custom_fields = go_form_get_custom_fields($selected_form_id);
|
||||
go_form_render_entries_table($entries, true, $custom_fields, $selected_form_id);
|
||||
|
||||
} else {
|
||||
|
||||
echo '<h2>Create New Form</h2>';
|
||||
echo '<form method="post" action="' . admin_url('admin-post.php') . '">';
|
||||
echo wp_nonce_field('go_form_create_form_action', 'go_form_create_form_nonce', true, false);
|
||||
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 '</table>';
|
||||
echo '<p class="submit"><input type="submit" class="button button-primary" value="Create Form"></p>';
|
||||
echo '</form>';
|
||||
|
||||
$forms = go_form_get_forms();
|
||||
echo '<h3>Forms</h3><ul>';
|
||||
foreach ($forms as $f) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<table class="wp-list-table widefat striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>N</th>
|
||||
<th>First Name</th>
|
||||
<th>Last Name</th>
|
||||
<th>Country</th>
|
||||
@@ -8,35 +9,56 @@
|
||||
<th>Rank</th>
|
||||
<th>EGD Number</th>
|
||||
<th>Date Added</th>
|
||||
<?php
|
||||
// Add custom field columns
|
||||
foreach ($custom_fields as $field):
|
||||
if ($field->is_public || $show_admin):
|
||||
echo '<th>' . esc_html($field->field_name) . '</th>';
|
||||
endif;
|
||||
endforeach;
|
||||
?>
|
||||
<?php if ($show_admin): ?>
|
||||
<th>Rating</th>
|
||||
<th>Email</th>
|
||||
<th>Action</th>
|
||||
<th>Comment</th>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<?php foreach ($entries as $e): ?>
|
||||
<?php foreach ($entries as $i => $e): ?>
|
||||
|
||||
<tr>
|
||||
<td> <?= $i + 1 ?> </td>
|
||||
<td> <?= esc_html($e->first_name) ?> </td>
|
||||
<td> <?= esc_html($e->last_name) ?> </td>
|
||||
<td> <?= esc_html($e->country) ?> </td>
|
||||
<td> <?= esc_html($e->club) ?> </td>
|
||||
<td> <?= esc_html($ranks[$e->rank]) ?> </td>
|
||||
<td> <?= esc_html($e->egd_number) ?> </td>
|
||||
<td><a href="https://europeangodatabase.eu/EGD/Player_Card.php?&key=<?= esc_html($e->egd_number) ?>"><?= esc_html($e->egd_number) ?> </a> </td>
|
||||
<td> <?= esc_html($e->created_at) ?> </td>
|
||||
<?php
|
||||
// Display custom field values
|
||||
foreach ($custom_fields as $field):
|
||||
if ($field->is_public || $show_admin):
|
||||
echo '<td>';
|
||||
$value = go_form_get_custom_value($e->id, $field->id);
|
||||
if ($field->field_type === 'checkbox') {
|
||||
echo $value ? 'Yes' : 'No';
|
||||
} else {
|
||||
echo esc_html($value);
|
||||
}
|
||||
echo '</td>';
|
||||
endif;
|
||||
endforeach;
|
||||
?>
|
||||
|
||||
<?php if ($show_admin): ?>
|
||||
|
||||
<td> <?= esc_html($e->rating) ?> </td>
|
||||
<td> <?= esc_html($e->email) ?> </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>
|
||||
<td> <?= esc_html($e->comment) ?> </td>
|
||||
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
2
main.php
2
main.php
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* Plugin Name: Go Form Plugin
|
||||
* Description: Form plugin for Go players
|
||||
* Version: 0.04
|
||||
* Version: 0.05
|
||||
* Author: Nikola Petrov
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
sudo rm -rf html/wp-content/plugins/go-form-plugin
|
||||
sudo cp -r go-form-plugin html/wp-content/plugins/
|
||||
cd ..
|
||||
sudo rm -rf scripts/html/wp-content/plugins/go-form-plugin
|
||||
sudo mkdir scripts/html/wp-content/plugins/go-form-plugin
|
||||
sudo cp main.php scripts/html/wp-content/plugins/go-form-plugin/
|
||||
sudo cp -r go-form-plugin scripts/html/wp-content/plugins/go-form-plugin/go-form-plugin/
|
||||
Reference in New Issue
Block a user