283 lines
12 KiB
PHP
283 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* Plugin Name: StatPress
|
|
* Description: Wtyczka do śledzenia statystyk sportowych (Rower, Bieganie, itp.).
|
|
* Version: 1.0
|
|
* Author: Jacek Fefliński
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
// Definicja stałych
|
|
define( 'STATPRESS_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
|
define( 'STATPRESS_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
|
|
|
// --- 1. PLIKI RDZENNE I AKTYWACJA ---
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/activation.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/core/gpx-parser.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/core/crud-activity.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/core/gpx-upload.php';
|
|
|
|
register_activation_hook( __FILE__, 'statpress_activate' );
|
|
|
|
// --- 2. PLIKI I HOOKI PANELU ADMINA ---
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/hooks.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/menu.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-dashboard.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-activity-form.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-activity-view.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-event-types.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-equipment.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-goals.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-settings.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-yearly-summary.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-infographic.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-import-csv.php';
|
|
|
|
global $statpress_plugin_hooks;
|
|
$statpress_plugin_hooks = array();
|
|
|
|
add_action( 'admin_menu', 'statpress_add_admin_menu' );
|
|
add_action( 'admin_init', 'statpress_admin_init_setup' );
|
|
add_action( 'admin_enqueue_scripts', 'statpress_enqueue_admin_styles' );
|
|
|
|
add_action( 'admin_enqueue_scripts', 'statpress_enqueue_material_assets' );
|
|
function statpress_enqueue_material_assets() {
|
|
$screen = get_current_screen();
|
|
if ( $screen && strpos( $screen->id, 'statpress' ) !== false ) {
|
|
wp_enqueue_style( 'google-fonts-roboto', 'https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap', false );
|
|
wp_enqueue_style( 'google-material-icons', 'https://fonts.googleapis.com/icon?family=Material+Icons', false );
|
|
}
|
|
}
|
|
|
|
add_action( 'admin_head', 'statpress_material_design_styles' );
|
|
function statpress_material_design_styles() {
|
|
$screen = get_current_screen();
|
|
if ( ! $screen || strpos( $screen->id, 'statpress' ) === false ) {
|
|
return;
|
|
}
|
|
?>
|
|
<style>
|
|
/* Zmiana głównej czcionki i nagłówków */
|
|
#wpbody-content { font-family: 'Roboto', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
|
|
.wrap h1, .wrap h2 { font-weight: 400; color: #202124; }
|
|
|
|
/* Material Cards (karty) */
|
|
.wrap .postbox, .wrap .wp-list-table {
|
|
border: none !important;
|
|
border-radius: 8px;
|
|
box-shadow: 0 1px 2px 0 rgba(60,64,67,0.3), 0 1px 3px 1px rgba(60,64,67,0.15) !important;
|
|
background: #fff;
|
|
}
|
|
.wrap .postbox-header { border-bottom: 1px solid #dadce0; }
|
|
.wrap .postbox-header h2 { font-weight: 500; font-size: 16px; color: #202124; }
|
|
|
|
/* Tabele danych */
|
|
.wrap .wp-list-table { overflow: hidden; border-spacing: 0; }
|
|
.wrap .wp-list-table thead th { background: #f8f9fa; font-weight: 500; text-transform: uppercase; font-size: 12px; color: #5f6368; border-bottom: 1px solid #dadce0; padding: 16px 12px; }
|
|
.wrap .wp-list-table tbody td { border-bottom: 1px solid #e8eaed; padding: 14px 12px; vertical-align: middle; color: #3c4043; font-size: 14px; }
|
|
.wrap .wp-list-table.striped>tbody>:nth-child(odd), .wrap .wp-list-table>tbody>:nth-child(odd) { background-color: #ffffff; }
|
|
.wrap .wp-list-table tbody tr:hover { background-color: #f1f3f4; }
|
|
|
|
/* Przyciski */
|
|
.wrap .button.button-primary {
|
|
background: #1a73e8 !important; /* Google Blue */
|
|
border: none !important;
|
|
border-radius: 4px !important;
|
|
box-shadow: 0 1px 2px 0 rgba(60,64,67,0.3), 0 1px 3px 1px rgba(60,64,67,0.15) !important;
|
|
color: #fff !important;
|
|
text-transform: uppercase;
|
|
font-weight: 500;
|
|
letter-spacing: 0.25px;
|
|
transition: all 0.2s;
|
|
text-shadow: none !important;
|
|
padding: 4px 16px !important;
|
|
}
|
|
.wrap .button.button-primary:hover, .wrap .button.button-primary:focus {
|
|
background: #174ea6 !important;
|
|
box-shadow: 0 1px 3px 0 rgba(60,64,67,0.3), 0 4px 8px 3px rgba(60,64,67,0.15) !important;
|
|
transform: translateY(-1px);
|
|
}
|
|
.wrap .button {
|
|
border-radius: 4px;
|
|
text-transform: uppercase;
|
|
font-weight: 500;
|
|
font-size: 13px;
|
|
border: 1px solid #dadce0 !important;
|
|
color: #1a73e8 !important;
|
|
background: transparent;
|
|
transition: all 0.2s;
|
|
box-shadow: none !important;
|
|
padding: 4px 16px;
|
|
}
|
|
.wrap .button:hover { background: #f8f9fa !important; border-color: #dadce0 !important; color: #174ea6 !important; }
|
|
.wrap .button-link-delete { color: #d93025 !important; border-color: #fce8e6 !important; background: #fce8e6 !important; }
|
|
.wrap .button-link-delete:hover { background: #fad2cf !important; border-color: #fad2cf !important; color: #b31412 !important; }
|
|
|
|
/* Pola formularzy (Inputs) */
|
|
.wrap .form-table th { font-weight: 500; color: #3c4043; }
|
|
.wrap input[type="text"], .wrap input[type="number"], .wrap input[type="date"], .wrap input[type="time"], .wrap select, .wrap textarea, .wrap input[type="url"] {
|
|
border: 1px solid #dadce0;
|
|
border-radius: 4px;
|
|
padding: 8px 12px;
|
|
box-shadow: none;
|
|
transition: border-color 0.2s, box-shadow 0.2s;
|
|
color: #202124;
|
|
font-size: 14px;
|
|
background: #fff;
|
|
}
|
|
.wrap input:focus, .wrap select:focus, .wrap textarea:focus {
|
|
border-color: #1a73e8;
|
|
box-shadow: inset 0 0 0 2px #1a73e8;
|
|
outline: none;
|
|
}
|
|
|
|
/* Zakładki (Tabs) */
|
|
.wrap .nav-tab-wrapper { border-bottom: 1px solid #dadce0; margin-bottom: 20px; padding-top: 10px; }
|
|
.wrap .nav-tab { border: none; background: transparent; font-weight: 500; text-transform: uppercase; color: #5f6368; padding: 12px 16px; margin: 0; font-size: 14px; }
|
|
.wrap .nav-tab:hover { background: #f1f3f4; color: #202124; }
|
|
.wrap .nav-tab-active, .wrap .nav-tab-active:hover { border-bottom: 3px solid #1a73e8; color: #1a73e8; background: transparent; }
|
|
|
|
/* Notyfikacje */
|
|
.wrap .notice { border-radius: 8px; border-left-width: 6px; box-shadow: 0 1px 2px 0 rgba(60,64,67,0.3); border-color: #1a73e8; background: #fff; margin-bottom: 20px; }
|
|
.wrap .notice-success { border-color: #188038; }
|
|
.wrap .notice-error { border-color: #d93025; }
|
|
.wrap .notice-warning { border-color: #f9ab00; }
|
|
|
|
/* Inne */
|
|
.wrap hr { border: 0; height: 1px; background: #dadce0; margin: 24px 0; }
|
|
</style>
|
|
<?php
|
|
}
|
|
|
|
// --- 3. REST API ---
|
|
$api_options = get_option( 'statpress_api_options' );
|
|
if ( ! empty( $api_options['enable_api'] ) ) {
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/routes.php';
|
|
add_action( 'rest_api_init', 'statpress_register_rest_routes' );
|
|
}
|
|
|
|
// --- 4. SHORTCODE DO WYŚWIETLANIA NA FRONCIE ---
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/frontend/assets.php';
|
|
require_once STATPRESS_PLUGIN_DIR . 'includes/frontend/shortcodes.php';
|
|
|
|
add_action( 'wp_enqueue_scripts', 'statpress_enqueue_frontend_assets' );
|
|
add_action( 'init', 'statpress_register_shortcode' );
|
|
|
|
add_action( 'wp_enqueue_scripts', 'statpress_enqueue_frontend_material_assets' );
|
|
function statpress_enqueue_frontend_material_assets() {
|
|
wp_enqueue_style( 'google-fonts-roboto', 'https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap', false );
|
|
wp_enqueue_style( 'google-material-icons', 'https://fonts.googleapis.com/icon?family=Material+Icons', false );
|
|
}
|
|
|
|
// --- 5. MIGRACJA DANYCH (jednorazowa) ---
|
|
add_action( 'admin_init', 'statpress_handle_data_migration' );
|
|
add_action( 'admin_init', 'statpress_handle_admin_tools' );
|
|
|
|
/**
|
|
* Handles the one-time data migration from 'mystat_' tables to 'statpress_' tables.
|
|
*/
|
|
function statpress_handle_data_migration() {
|
|
// Check if the migration action is triggered, nonce is valid, and user has permissions.
|
|
if ( ! isset( $_GET['action'] ) || 'statpress_migrate_data' !== $_GET['action'] ) {
|
|
return;
|
|
}
|
|
if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( $_GET['_wpnonce'], 'statpress_migration_nonce' ) ) {
|
|
return;
|
|
}
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
return;
|
|
}
|
|
|
|
global $wpdb;
|
|
|
|
// Define table columns to ensure robust migration, even if schemas differ.
|
|
$table_columns = array(
|
|
'activities' => 'id, category_id, date, title, distance, duration, calories, comment, strava_url, avg_heart_rate, max_heart_rate, avg_speed, max_speed, avg_cadence, max_cadence, total_elevation_gain, total_elevation_loss, min_altitude, max_altitude, equipment_id, gpx_url, event_type_id',
|
|
'categories' => 'id, name, icon, color',
|
|
'equipment' => 'id, name, type, purchase_date, initial_cost, status, notes',
|
|
'equipment_log' => 'id, equipment_id, log_date, log_type, description, cost, mileage',
|
|
'event_types' => 'id, name',
|
|
'goals' => 'id, name, goal_type, target_value, year, month, category_id',
|
|
);
|
|
|
|
$results = array();
|
|
$all_successful = true;
|
|
|
|
foreach ( $table_columns as $table_suffix => $columns ) {
|
|
$old_table = $wpdb->prefix . 'mystat_' . $table_suffix;
|
|
$new_table = $wpdb->prefix . 'statpress_' . $table_suffix;
|
|
|
|
// Check if old table exists and new table is empty
|
|
if ( $wpdb->get_var( "SHOW TABLES LIKE '{$old_table}'" ) === $old_table ) {
|
|
// Check if there's anything to migrate
|
|
$old_table_count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$old_table}" );
|
|
$new_table_count = (int) $wpdb->get_var( "SELECT COUNT(*) FROM {$new_table}" );
|
|
|
|
// Only migrate if the new table is empty but the old one has data.
|
|
if ( $old_table_count > 0 && 0 === $new_table_count ) {
|
|
// Use explicit column list for a robust query
|
|
$query = "INSERT INTO {$new_table} ({$columns}) SELECT {$columns} FROM {$old_table}";
|
|
$copied_rows = $wpdb->query( $query );
|
|
|
|
if ( false === $copied_rows ) {
|
|
$all_successful = false;
|
|
$results[ $table_suffix ] = array(
|
|
'status' => 'failure',
|
|
'error' => $wpdb->last_error,
|
|
);
|
|
} else {
|
|
$results[ $table_suffix ] = array(
|
|
'status' => 'success',
|
|
'count' => $copied_rows,
|
|
);
|
|
}
|
|
} else {
|
|
// If the new table is not empty, skip it.
|
|
$results[ $table_suffix ] = array(
|
|
'status' => 'skipped',
|
|
'count' => $new_table_count,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Store the results in a transient to display a notice
|
|
set_transient( 'statpress_migration_results', $results, 60 );
|
|
|
|
// Mark migration as complete only if everything was successful or skipped.
|
|
if ( $all_successful ) {
|
|
update_option( 'statpress_migration_complete', true );
|
|
}
|
|
|
|
// Redirect to the main dashboard to show the notice and remove query args
|
|
wp_safe_redirect( admin_url( 'admin.php?page=statpress-dashboard' ) );
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Handles various admin tool actions, like resetting the migration flag.
|
|
*/
|
|
function statpress_handle_admin_tools() {
|
|
// Check if the reset migration action is triggered
|
|
if ( isset( $_POST['statpress_action'] ) && 'reset_migration' === $_POST['statpress_action'] ) {
|
|
// Verify nonce and permissions
|
|
if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'statpress_reset_migration_nonce' ) ) {
|
|
return;
|
|
}
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
return;
|
|
}
|
|
|
|
// Delete the option that hides the migration button
|
|
delete_option( 'statpress_migration_complete' );
|
|
|
|
// Set a transient to show a success notice on the settings page
|
|
set_transient( 'statpress_migration_reset_notice', true, 60 );
|
|
wp_safe_redirect( admin_url( 'admin.php?page=statpress-settings' ) );
|
|
exit;
|
|
}
|
|
}
|