Файловый менеджер - Редактировать - /home/admin/domains/octawebtools.com/public_html/wp-content/plugins/teer-results/teer-results.php
�азад
<?php /* Plugin Name: Teer Results Description: A plugin to manage and display Teer results with CSV import, date filtering, and search. Version: 1.8 Author: Your Name */ // Create database table on plugin activation register_activation_hook(__FILE__, 'teer_results_create_table'); function teer_results_create_table() { global $wpdb; $table_name = $wpdb->prefix . 'teer_results'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, result_date date NOT NULL, first_round varchar(10) NOT NULL, second_round varchar(10) NOT NULL, PRIMARY KEY (id), UNIQUE KEY result_date (result_date) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); } // Add admin menu add_action('admin_menu', 'teer_results_admin_menu'); function teer_results_admin_menu() { add_menu_page( 'Teer Results', 'Teer Results', 'manage_options', 'teer-results', 'teer_results_admin_page', 'dashicons-calendar-alt', 20 ); } // Admin page content function teer_results_admin_page() { global $wpdb; $table_name = $wpdb->prefix . 'teer_results'; // Handle form submission if (isset($_POST['submit_result'])) { $result_date = sanitize_text_field($_POST['result_date']); $first_round = sanitize_text_field($_POST['first_round']); $second_round = sanitize_text_field($_POST['second_round']); // Validate inputs $validation_errors = array(); if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $result_date)) { $validation_errors[] = "Invalid date format. Please use YYYY-MM-DD."; } if (!is_numeric($first_round) || strlen($first_round) > 2) { $validation_errors[] = "First round must be a number (max 2 digits)."; } if (!is_numeric($second_round) || strlen($second_round) > 2) { $validation_errors[] = "Second round must be a number (max 2 digits)."; } if (empty($validation_errors)) { // Check if entry already exists for this date $existing = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM $table_name WHERE result_date = %s", $result_date )); if ($existing) { $wpdb->update( $table_name, array( 'first_round' => $first_round, 'second_round' => $second_round ), array('result_date' => $result_date), array('%s', '%s'), array('%s') ); $message = "Results updated successfully!"; } else { $wpdb->insert( $table_name, array( 'result_date' => $result_date, 'first_round' => $first_round, 'second_round' => $second_round ), array('%s', '%s', '%s') ); $message = "Results added successfully!"; } } else { $message = '<div class="notice notice-error"><p>' . implode('<br>', $validation_errors) . '</p></div>'; } } // Handle CSV import if (isset($_POST['import_csv']) && isset($_FILES['csv_file']) && $_FILES['csv_file']['error'] == 0) { $file = $_FILES['csv_file']['tmp_name']; $handle = fopen($file, "r"); // Skip header row $header = fgetcsv($handle, 0, "\t"); $imported = 0; $updated = 0; $errors = 0; $error_details = array(); $line_number = 1; // Start counting after header while (($data = fgetcsv($handle, 0, "\t")) !== FALSE) { $line_number++; // Skip empty rows if (count(array_filter($data)) === 0) { continue; } // Validate minimum columns if (count($data) < 3) { $errors++; $error_details[] = "Line $line_number: Not enough columns (expected 3, found " . count($data) . ")"; continue; } // Trim all values $data = array_map('trim', $data); // Convert DD-MM-YYYY to YYYY-MM-DD $date_parts = explode('-', $data[0]); if (count($date_parts) == 3) { $result_date = sprintf('%04d-%02d-%02d', $date_parts[2], $date_parts[1], $date_parts[0]); } else { $errors++; $error_details[] = "Line $line_number: Invalid date format '{$data[0]}' (expected DD-MM-YYYY)"; continue; } // Validate first round number $first_round = sanitize_text_field($data[1]); if (!is_numeric($first_round) || strlen($first_round) > 2) { $errors++; $error_details[] = "Line $line_number: Invalid first round number '{$data[1]}' (must be 1-2 digits)"; continue; } // Validate second round number $second_round = sanitize_text_field($data[2]); if (!is_numeric($second_round) || strlen($second_round) > 2) { $errors++; $error_details[] = "Line $line_number: Invalid second round number '{$data[2]}' (must be 1-2 digits)"; continue; } // Check if entry exists $existing = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM $table_name WHERE result_date = %s", $result_date )); if ($existing) { $result = $wpdb->update( $table_name, array( 'first_round' => $first_round, 'second_round' => $second_round ), array('result_date' => $result_date) ); if ($result !== false) { $updated++; } else { $errors++; $error_details[] = "Line $line_number: Failed to update existing record for date $result_date"; } } else { $result = $wpdb->insert( $table_name, array( 'result_date' => $result_date, 'first_round' => $first_round, 'second_round' => $second_round ) ); if ($result !== false) { $imported++; } else { $errors++; $error_details[] = "Line $line_number: Failed to insert new record for date $result_date"; } } } fclose($handle); // Prepare import message $import_message = sprintf( "CSV import completed. %d new records added, %d records updated, %d errors.", $imported, $updated, $errors ); // Add error details if there were errors if ($errors > 0) { $import_message .= '<div class="error-details" style="margin-top: 10px; max-height: 200px; overflow-y: auto; background: #f5f5f5; padding: 10px; border: 1px solid #ddd;">'; $import_message .= '<strong>Error details:</strong><ul style="margin: 5px 0 0 15px;">'; foreach ($error_details as $error) { $import_message .= '<li>' . esc_html($error) . '</li>'; } $import_message .= '</ul></div>'; } } // Get all results for listing $results = $wpdb->get_results("SELECT * FROM $table_name ORDER BY result_date DESC"); ?> <div class="wrap"> <h1>Teer Results</h1> <?php if (isset($message)): ?> <?php echo (strpos($message, 'notice-error') !== false) ? $message : '<div class="notice notice-success"><p>' . esc_html($message) . '</p></div>'; ?> <?php endif; ?> <?php if (isset($import_message)): ?> <div class="notice notice-info"><?php echo $import_message; ?></div> <?php endif; ?> <h2>Add New Results</h2> <form method="post" action=""> <table class="form-table"> <tr> <th scope="row"><label for="result_date">Date (YYYY-MM-DD)</label></th> <td> <input type="date" id="result_date" name="result_date" required value="<?php echo date('Y-m-d'); ?>" pattern="\d{4}-\d{2}-\d{2}"> </td> </tr> <tr> <th scope="row"><label for="first_round">First Round (2 digits)</label></th> <td> <input type="text" id="first_round" name="first_round" required maxlength="2" pattern="\d{1,2}" title="1-2 digit number"> </td> </tr> <tr> <th scope="row"><label for="second_round">Second Round (2 digits)</label></th> <td> <input type="text" id="second_round" name="second_round" required maxlength="2" pattern="\d{1,2}" title="1-2 digit number"> </td> </tr> </table> <p class="submit"> <input type="submit" name="submit_result" class="button button-primary" value="Save Results"> </p> </form> <h2>Import Results from CSV</h2> <form method="post" enctype="multipart/form-data"> <table class="form-table"> <tr> <th scope="row"><label for="csv_file">CSV File</label></th> <td> <input type="file" id="csv_file" name="csv_file" accept=".csv,.txt" required> <p class="description">File format: Tab-delimited text with columns <code>Date (DD-MM-YYYY)</code>, <code>F/R (2 digits)</code>, <code>S/R (2 digits)</code></p> <p class="description">Example:<br> <code>08-05-2025	67	18<br> 07-05-2025	89	88</code></p> </td> </tr> </table> <p class="submit"> <input type="submit" name="import_csv" class="button button-primary" value="Import CSV"> </p> </form> <h2>Previous Results</h2> <table class="wp-list-table widefat fixed striped"> <thead> <tr> <th>Date</th> <th>First Round</th> <th>Second Round</th> </tr> </thead> <tbody> <?php if ($results): ?> <?php foreach ($results as $result): ?> <tr> <td><?php echo date('d-m-Y', strtotime($result->result_date)); ?></td> <td><?php echo esc_html($result->first_round); ?></td> <td><?php echo esc_html($result->second_round); ?></td> </tr> <?php endforeach; ?> <?php else: ?> <tr> <td colspan="3">No results found.</td> </tr> <?php endif; ?> </tbody> </table> </div> <?php } // Shortcode to display results with pagination, date filtering, and search add_shortcode('teer_results', 'teer_results_shortcode'); function teer_results_shortcode($atts) { global $wpdb; $table_name = $wpdb->prefix . 'teer_results'; $atts = shortcode_atts(array( 'per_page' => 10, 'title' => 'Previous Teer Results', 'header_bg' => '#4a6ea9', 'header_text' => '#ffffff', 'row_bg' => '#f8f9fa', 'alternate_bg' => '#e9ecef', 'text_color' => '#212529', 'border_color' => '#dee2e6', 'hover_color' => '#f1f5fd', 'highlight_first' => '#ff5722', 'highlight_second' => '#4caf50', 'show_search' => 'yes' ), $atts); // Enqueue necessary scripts wp_enqueue_script('jquery'); wp_enqueue_script('jquery-ui-datepicker'); wp_enqueue_style('jquery-ui-css', 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css'); // Pagination setup $per_page = intval($atts['per_page']); $current_page = max(1, get_query_var('paged') ? get_query_var('paged') : 1); $offset = ($current_page - 1) * $per_page; // Base query $query = "SELECT * FROM $table_name"; $count_query = "SELECT COUNT(*) FROM $table_name"; $where_clauses = array(); // Apply date filters if set $date_from = isset($_GET['date_from']) ? sanitize_text_field($_GET['date_from']) : ''; $date_to = isset($_GET['date_to']) ? sanitize_text_field($_GET['date_to']) : ''; if ($date_from) { $date_from_obj = DateTime::createFromFormat('d-m-Y', $date_from); if ($date_from_obj) { $where_clauses[] = $wpdb->prepare("result_date >= %s", $date_from_obj->format('Y-m-d')); } } if ($date_to) { $date_to_obj = DateTime::createFromFormat('d-m-Y', $date_to); if ($date_to_obj) { $where_clauses[] = $wpdb->prepare("result_date <= %s", $date_to_obj->format('Y-m-d')); } } // Apply search if set $search_term = isset($_GET['teer_search']) ? sanitize_text_field($_GET['teer_search']) : ''; if ($search_term && $atts['show_search'] === 'yes') { $where_clauses[] = $wpdb->prepare("(first_round LIKE %s OR second_round LIKE %s)", '%' . $wpdb->esc_like($search_term) . '%', '%' . $wpdb->esc_like($search_term) . '%'); } // Build WHERE clause if (!empty($where_clauses)) { $where = ' WHERE ' . implode(' AND ', $where_clauses); $query .= $where; $count_query .= $where; } // Complete queries $query .= " ORDER BY result_date DESC LIMIT $per_page OFFSET $offset"; $results = $wpdb->get_results($query); $total_items = $wpdb->get_var($count_query); $total_pages = ceil($total_items / $per_page); ob_start(); ?> <div class="teer-results-container"> <h2 class="teer-results-title" style="color: <?php echo esc_attr($atts['header_bg']); ?>; text-align: center; margin-bottom: 20px; font-size: 28px; font-weight: 600;"> <?php echo esc_html($atts['title']); ?> </h2> <div class="teer-filters" style="margin-bottom: 20px;"> <form method="get" action="" class="teer-filter-form" style="display: flex; flex-wrap: wrap; gap: 15px; justify-content: center;"> <?php if (!empty($_GET['page_id'])): ?> <input type="hidden" name="page_id" value="<?php echo esc_attr($_GET['page_id']); ?>"> <?php endif; ?> <?php if ($atts['show_search'] === 'yes'): ?> <div class="teer-search-filter" style="flex: 1; min-width: 250px;"> <input type="text" name="teer_search" placeholder="Search results..." value="<?php echo esc_attr($search_term); ?>" style="width: 100%; padding: 8px 12px; border: 1px solid <?php echo esc_attr($atts['border_color']); ?>; border-radius: 4px;"> </div> <?php endif; ?> <div class="teer-date-filters" style="display: flex; gap: 10px; align-items: center; flex-wrap: wrap;"> <span style="font-weight: 500;">Filter by date:</span> <input type="text" name="date_from" id="teer-date-from" placeholder="From (DD-MM-YYYY)" value="<?php echo esc_attr($date_from); ?>" class="teer-date-picker" style="width: 120px; padding: 8px; border: 1px solid <?php echo esc_attr($atts['border_color']); ?>; border-radius: 4px;"> <span>to</span> <input type="text" name="date_to" id="teer-date-to" placeholder="To (DD-MM-YYYY)" value="<?php echo esc_attr($date_to); ?>" class="teer-date-picker" style="width: 120px; padding: 8px; border: 1px solid <?php echo esc_attr($atts['border_color']); ?>; border-radius: 4px;"> <button type="submit" style="padding: 8px 15px; background: <?php echo esc_attr($atts['header_bg']); ?>; color: white; border: none; border-radius: 4px; cursor: pointer;">Apply</button> <?php if ($date_from || $date_to || $search_term): ?> <a href="<?php echo remove_query_arg(array('date_from', 'date_to', 'teer_search', 'paged')); ?>" style="padding: 8px 15px; background: #ccc; color: #333; border: none; border-radius: 4px; cursor: pointer; text-decoration: none;">Reset All</a> <?php endif; ?> </div> </form> </div> <div class="teer-results-table-wrapper"> <table class="teer-results-table"> <thead> <tr> <th style="background: <?php echo esc_attr($atts['header_bg']); ?>; color: <?php echo esc_attr($atts['header_text']); ?>;">Date</th> <th style="background: <?php echo esc_attr($atts['header_bg']); ?>; color: <?php echo esc_attr($atts['header_text']); ?>;">First Round</th> <th style="background: <?php echo esc_attr($atts['header_bg']); ?>; color: <?php echo esc_attr($atts['header_text']); ?>;">Second Round</th> </tr> </thead> <tbody> <?php if ($results): ?> <?php foreach ($results as $index => $result): ?> <tr style="background-color: <?php echo ($index % 2) ? esc_attr($atts['alternate_bg']) : esc_attr($atts['row_bg']); ?>; color: <?php echo esc_attr($atts['text_color']); ?>;"> <td><?php echo date('d-m-Y', strtotime($result->result_date)); ?></td> <td style="font-weight: bold; color: <?php echo esc_attr($atts['highlight_first']); ?>"><?php echo esc_html($result->first_round); ?></td> <td style="font-weight: bold; color: <?php echo esc_attr($atts['highlight_second']); ?>"><?php echo esc_html($result->second_round); ?></td> </tr> <?php endforeach; ?> <?php else: ?> <tr> <td colspan="3" style="text-align: center;">No results found.</td> </tr> <?php endif; ?> </tbody> </table> </div> <?php if ($total_pages > 1): ?> <div class="teer-pagination" style="margin-top: 20px; text-align: center;"> <?php echo paginate_links(array( 'base' => add_query_arg('paged', '%#%'), 'format' => '', 'prev_text' => __('« Previous'), 'next_text' => __('Next »'), 'total' => $total_pages, 'current' => $current_page, 'type' => 'plain' )); ?> </div> <?php endif; ?> </div> <style> .teer-results-container { margin: 25px 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } .teer-results-table-wrapper { overflow-x: auto; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); border-radius: 8px; background: white; } .teer-results-table { width: 100%; border-collapse: collapse; margin: 0; font-size: 15px; min-width: 400px; border-radius: 8px 8px 0 0; overflow: hidden; } .teer-results-table th { padding: 12px 15px; text-align: center; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; position: sticky; top: 0; font-size: 14px; } .teer-results-table td { padding: 10px 15px; text-align: center; border-bottom: 1px solid <?php echo esc_attr($atts['border_color']); ?>; transition: all 0.2s ease; font-size: 14px; } .teer-results-table tr:last-child td { border-bottom: none; } .teer-results-table tr:hover td { background-color: <?php echo esc_attr($atts['hover_color']); ?>; } .teer-results-title { position: relative; padding-bottom: 8px; } .teer-results-title:after { content: ''; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 60px; height: 2px; background: <?php echo esc_attr($atts['header_bg']); ?>; } /* Pagination styles */ .teer-pagination a, .teer-pagination span { display: inline-block; padding: 5px 10px; margin: 0 2px; border: 1px solid #ddd; background: #f8f8f8; color: #333; text-decoration: none; } .teer-pagination .current { background: <?php echo esc_attr($atts['header_bg']); ?>; color: white; border-color: <?php echo esc_attr($atts['header_bg']); ?>; } /* Filter form styles */ .teer-filter-form { max-width: 800px; margin: 0 auto; } .teer-date-picker { border: 1px solid <?php echo esc_attr($atts['border_color']); ?>; border-radius: 4px; } /* Ensure datepicker appears above other elements */ .ui-datepicker { z-index: 999999 !important; font-size: 13px; } @media (max-width: 600px) { .teer-results-table { font-size: 14px; } .teer-results-table th, .teer-results-table td { padding: 8px 10px; } .teer-results-title { font-size: 22px; } .teer-date-filters { flex-direction: column; align-items: flex-start; gap: 8px; } .teer-date-filters input { width: 140px !important; } } </style> <script> jQuery(document).ready(function($) { // Initialize datepicker with DD-MM-YYYY format $('.teer-date-picker').datepicker({ dateFormat: 'dd-mm-yy', changeMonth: true, changeYear: true, yearRange: '2010:<?php echo date('Y') + 2; ?>', showButtonPanel: true, beforeShow: function(input, inst) { setTimeout(function() { inst.dpDiv.css({ 'z-index': 999999, 'position': 'absolute' }); }, 0); } }); }); </script> <?php return ob_get_clean(); } // Add some CSS to the admin area add_action('admin_head', 'teer_results_admin_css'); function teer_results_admin_css() { echo '<style> .wp-list-table.widefat th, .wp-list-table.widefat td { padding: 10px 12px; } #result_date, #first_round, #second_round { padding: 8px; border-radius: 4px; border: 1px solid #ddd; } .form-table th { width: 150px; } .error-details { margin-top: 10px; max-height: 200px; overflow-y: auto; background: #f5f5f5; padding: 10px; border: 1px solid #ddd; } .error-details ul { margin: 5px 0 0 15px; } </style>'; }
| ver. 1.4 |
Github
|
.
| PHP 8.1.32 | Генераци� �траницы: 0 |
proxy
|
phpinfo
|
�а�тройка