Cele
This commit is contained in:
+324
-1
@@ -21,6 +21,7 @@ function mystat_activate() {
|
||||
$table_activities = $wpdb->prefix . 'mystat_activities';
|
||||
$table_event_types = $wpdb->prefix . 'mystat_event_types';
|
||||
$table_equipment = $wpdb->prefix . 'mystat_equipment';
|
||||
$table_goals = $wpdb->prefix . 'mystat_goals';
|
||||
|
||||
// SQL dla Kategorii
|
||||
$sql_cat = "CREATE TABLE $table_categories (
|
||||
@@ -45,6 +46,19 @@ function mystat_activate() {
|
||||
PRIMARY KEY (id)
|
||||
) $charset_collate;";
|
||||
|
||||
// SQL dla Celów
|
||||
$sql_goals = "CREATE TABLE $table_goals (
|
||||
id mediumint(9) NOT NULL AUTO_INCREMENT,
|
||||
name varchar(255) NOT NULL,
|
||||
goal_type varchar(20) NOT NULL, -- 'distance', 'duration_sec', 'count'
|
||||
target_value decimal(10,2) NOT NULL,
|
||||
year smallint(4) NOT NULL,
|
||||
month tinyint(2) UNSIGNED DEFAULT NULL,
|
||||
category_id mediumint(9) DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY category_id (category_id)
|
||||
) $charset_collate;";
|
||||
|
||||
// SQL dla Aktywności
|
||||
$sql_act = "CREATE TABLE $table_activities (
|
||||
id bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
@@ -73,6 +87,7 @@ function mystat_activate() {
|
||||
) $charset_collate;";
|
||||
|
||||
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
||||
dbDelta( $sql_goals );
|
||||
dbDelta( $sql_equipment );
|
||||
dbDelta( $sql_cat );
|
||||
dbDelta( $sql_event_types );
|
||||
@@ -206,6 +221,25 @@ function mystat_add_admin_menu() {
|
||||
'mystat_equipment_page'
|
||||
);
|
||||
|
||||
$mystat_plugin_hooks[] = add_submenu_page(
|
||||
'moje-statystyki',
|
||||
'Użycie Sprzętu',
|
||||
'Użycie Sprzętu',
|
||||
'manage_options',
|
||||
'mystat-equipment-usage',
|
||||
'mystat_equipment_usage_page'
|
||||
);
|
||||
|
||||
$mystat_plugin_hooks[] = add_submenu_page(
|
||||
'moje-statystyki',
|
||||
'Cele',
|
||||
'Cele',
|
||||
'manage_options',
|
||||
'mystat-goals',
|
||||
'mystat_goals_page'
|
||||
);
|
||||
|
||||
|
||||
$mystat_plugin_hooks[] = add_submenu_page(
|
||||
null, // Ukryta strona, nie pojawia się w menu
|
||||
'Szczegóły Treningu', // Tytuł strony
|
||||
@@ -444,6 +478,247 @@ function mystat_equipment_page() {
|
||||
<?php
|
||||
}
|
||||
|
||||
function mystat_equipment_usage_page() {
|
||||
global $wpdb;
|
||||
$table_activities = $wpdb->prefix . 'mystat_activities';
|
||||
$table_equipment = $wpdb->prefix . 'mystat_equipment';
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
eq.id,
|
||||
eq.name,
|
||||
SUM(a.distance) as total_distance,
|
||||
SUM(TIME_TO_SEC(a.duration)) as total_seconds,
|
||||
COUNT(a.id) as activity_count
|
||||
FROM
|
||||
$table_equipment eq
|
||||
LEFT JOIN
|
||||
$table_activities a ON eq.id = a.equipment_id
|
||||
GROUP BY
|
||||
eq.id, eq.name
|
||||
ORDER BY
|
||||
total_distance DESC
|
||||
";
|
||||
|
||||
$equipment_usage = $wpdb->get_results($sql);
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1>Użycie Sprzętu</h1>
|
||||
<p>Tutaj znajdziesz podsumowanie wykorzystania Twojego sprzętu we wszystkich zarejestrowanych aktywnościach.</p>
|
||||
|
||||
<table class="wp-list-table widefat fixed striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nazwa Sprzętu</th>
|
||||
<th>Całkowity Dystans</th>
|
||||
<th>Całkowity Czas</th>
|
||||
<th>Liczba Aktywności</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($equipment_usage as $item) : ?>
|
||||
<tr>
|
||||
<td><strong><?php echo esc_html($item->name); ?></strong></td>
|
||||
<td><?php echo $item->total_distance ? number_format($item->total_distance, 2, ',', ' ') . ' km' : 'Brak danych'; ?></td>
|
||||
<td><?php echo $item->total_seconds ? sprintf('%d godz. %d min.', floor($item->total_seconds / 3600), floor(($item->total_seconds % 3600) / 60)) : 'Brak danych'; ?></td>
|
||||
<td><?php echo (int)$item->activity_count; ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the current progress for a given goal.
|
||||
*
|
||||
* @param object $goal The goal object from the database.
|
||||
* @return array An array containing 'current_value' and 'percentage'.
|
||||
*/
|
||||
function mystat_get_goal_progress($goal) {
|
||||
global $wpdb;
|
||||
$table_activities = $wpdb->prefix . 'mystat_activities';
|
||||
|
||||
$sql_select = '';
|
||||
switch ($goal->goal_type) {
|
||||
case 'distance':
|
||||
$sql_select = 'SUM(distance)';
|
||||
break;
|
||||
case 'duration_sec':
|
||||
$sql_select = 'SUM(TIME_TO_SEC(duration))';
|
||||
break;
|
||||
case 'count':
|
||||
$sql_select = 'COUNT(id)';
|
||||
break;
|
||||
default:
|
||||
return ['current_value' => 0, 'percentage' => 0];
|
||||
}
|
||||
|
||||
$where_clauses = [];
|
||||
$where_clauses[] = $wpdb->prepare('YEAR(date) = %d', $goal->year);
|
||||
|
||||
if (!empty($goal->month)) {
|
||||
$where_clauses[] = $wpdb->prepare('MONTH(date) = %d', $goal->month);
|
||||
}
|
||||
if (!empty($goal->category_id)) {
|
||||
$where_clauses[] = $wpdb->prepare('category_id = %d', $goal->category_id);
|
||||
}
|
||||
|
||||
$sql = "SELECT {$sql_select} FROM {$table_activities} WHERE " . implode(' AND ', $where_clauses);
|
||||
|
||||
$current_value = (float) $wpdb->get_var($sql);
|
||||
$percentage = ($goal->target_value > 0) ? ($current_value / $goal->target_value) * 100 : 0;
|
||||
|
||||
return [
|
||||
'current_value' => $current_value,
|
||||
'percentage' => $percentage,
|
||||
];
|
||||
}
|
||||
|
||||
function mystat_goals_page() {
|
||||
global $wpdb;
|
||||
$table_goals = $wpdb->prefix . 'mystat_goals';
|
||||
$table_categories = $wpdb->prefix . 'mystat_categories';
|
||||
$message = '';
|
||||
$notice_class = '';
|
||||
|
||||
// Handle POST requests (add/update)
|
||||
if ( isset( $_POST['submit'] ) && check_admin_referer( 'mystat_manage_goal' ) ) {
|
||||
$goal_id = isset( $_POST['goal_id'] ) ? intval( $_POST['goal_id'] ) : 0;
|
||||
$data = [
|
||||
'name' => sanitize_text_field($_POST['goal_name']),
|
||||
'goal_type' => sanitize_text_field($_POST['goal_type']),
|
||||
'target_value' => floatval(str_replace(',', '.', $_POST['target_value'])),
|
||||
'year' => intval($_POST['year']),
|
||||
'month' => $_POST['month'] === 'all' ? null : intval($_POST['month']),
|
||||
'category_id' => $_POST['category_id'] === 'all' ? null : intval($_POST['category_id']),
|
||||
];
|
||||
|
||||
if ( !empty($data['name']) && !empty($data['goal_type']) && $data['target_value'] > 0 && $data['year'] > 2000 ) {
|
||||
if ( $goal_id > 0 ) { // Update
|
||||
$wpdb->update( $table_goals, $data, [ 'id' => $goal_id ] );
|
||||
$message = 'Cel zaktualizowany.';
|
||||
$notice_class = 'notice-success';
|
||||
} else { // Insert
|
||||
$wpdb->insert( $table_goals, $data );
|
||||
$message = 'Cel dodany.';
|
||||
$notice_class = 'notice-success';
|
||||
}
|
||||
} else {
|
||||
$message = 'Wypełnij poprawnie wszystkie wymagane pola (Nazwa, Typ, Cel, Rok).';
|
||||
$notice_class = 'notice-error';
|
||||
}
|
||||
}
|
||||
|
||||
// Handle GET requests (delete)
|
||||
if ( isset( $_GET['action'], $_GET['id'], $_GET['_wpnonce'] ) && $_GET['action'] === 'delete' ) {
|
||||
if ( wp_verify_nonce( $_GET['_wpnonce'], 'mystat_delete_goal_' . $_GET['id'] ) ) {
|
||||
$wpdb->delete( $table_goals, [ 'id' => intval( $_GET['id'] ) ] );
|
||||
$message = 'Cel usunięty.';
|
||||
$notice_class = 'notice-success';
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare for form (for editing)
|
||||
$item_to_edit = null;
|
||||
if ( isset( $_GET['action'], $_GET['id'] ) && $_GET['action'] === 'edit' ) {
|
||||
$item_to_edit = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_goals WHERE id = %d", intval( $_GET['id'] ) ) );
|
||||
}
|
||||
|
||||
$goals = $wpdb->get_results( "SELECT g.*, c.name as category_name FROM $table_goals g LEFT JOIN $table_categories c ON g.category_id = c.id ORDER BY g.year DESC, g.name ASC" );
|
||||
$categories = $wpdb->get_results( "SELECT * FROM $table_categories ORDER BY name ASC" );
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1>Zarządzaj Celami</h1>
|
||||
<?php if ( ! empty( $message ) ) : ?>
|
||||
<div class="notice <?php echo esc_attr( $notice_class ); ?> is-dismissible"><p><?php echo esc_html( $message ); ?></p></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div id="col-container" class="wp-clearfix">
|
||||
<div id="col-left">
|
||||
<div class="col-wrap">
|
||||
<div class="form-wrap">
|
||||
<h2><?php echo $item_to_edit ? 'Edytuj cel' : 'Dodaj nowy cel'; ?></h2>
|
||||
<form method="post">
|
||||
<input type="hidden" name="goal_id" value="<?php echo $item_to_edit ? esc_attr( $item_to_edit->id ) : '0'; ?>">
|
||||
<?php wp_nonce_field( 'mystat_manage_goal' ); ?>
|
||||
<div class="form-field form-required"><label for="goal_name">Nazwa celu</label><input type="text" name="goal_name" id="goal_name" value="<?php echo $item_to_edit ? esc_attr( $item_to_edit->name ) : ''; ?>" required></div>
|
||||
<div class="form-field form-required"><label for="goal_type">Typ celu</label><select name="goal_type" id="goal_type" required><option value="distance" <?php if($item_to_edit) selected($item_to_edit->goal_type, 'distance'); ?>>Dystans (km)</option><option value="duration_sec" <?php if($item_to_edit) selected($item_to_edit->goal_type, 'duration_sec'); ?>>Czas (w godzinach)</option><option value="count" <?php if($item_to_edit) selected($item_to_edit->goal_type, 'count'); ?>>Liczba aktywności</option></select></div>
|
||||
<div class="form-field form-required"><label for="target_value">Wartość docelowa</label><input type="text" name="target_value" id="target_value" value="<?php echo $item_to_edit ? esc_attr( $item_to_edit->goal_type === 'duration_sec' ? $item_to_edit->target_value / 3600 : $item_to_edit->target_value ) : ''; ?>" required><p>Dla czasu podaj wartość w godzinach (np. 100.5).</p></div>
|
||||
<div class="form-field form-required"><label for="year">Rok</label><input type="number" name="year" id="year" value="<?php echo $item_to_edit ? esc_attr( $item_to_edit->year ) : current_time('Y'); ?>" required></div>
|
||||
<div class="form-field"><label for="month">Miesiąc</label><select name="month" id="month"><option value="all">Cały rok</option><?php for ($i=1; $i<=12; $i++): ?><option value="<?php echo $i; ?>" <?php if($item_to_edit) selected($item_to_edit->month, $i); ?>><?php echo date_i18n('F', mktime(0,0,0,$i,10)); ?></option><?php endfor; ?></select></div>
|
||||
<div class="form-field"><label for="category_id">Kategoria</label><select name="category_id" id="category_id"><option value="all">Wszystkie</option><?php foreach($categories as $cat): ?><option value="<?php echo esc_attr($cat->id); ?>" <?php if($item_to_edit) selected($item_to_edit->category_id, $cat->id); ?>><?php echo esc_html($cat->name); ?></option><?php endforeach; ?></select></div>
|
||||
<?php submit_button( $item_to_edit ? 'Zaktualizuj' : 'Dodaj' ); ?>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="col-right">
|
||||
<div class="col-wrap">
|
||||
<table class="wp-list-table widefat fixed striped">
|
||||
<thead><tr><th>Cel</th><th>Postęp</th><th style="width: 100px;">Akcje</th></tr></thead>
|
||||
<tbody>
|
||||
<?php if (empty($goals)): ?>
|
||||
<tr><td colspan="3">Brak zdefiniowanych celów.</td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ( $goals as $goal ) : ?>
|
||||
<?php
|
||||
$is_duration = $goal->goal_type === 'duration_sec';
|
||||
if ($is_duration) {
|
||||
$goal->target_value = $goal->target_value * 3600; // Convert hours back to seconds for calculation
|
||||
}
|
||||
$progress = mystat_get_goal_progress($goal);
|
||||
$percentage = min(100, $progress['percentage']);
|
||||
|
||||
$target_formatted = '';
|
||||
$current_formatted = '';
|
||||
if ($is_duration) {
|
||||
$target_formatted = round($goal->target_value / 3600) . ' godz.';
|
||||
$current_formatted = sprintf('%d godz. %d min.', floor($progress['current_value'] / 3600), floor(($progress['current_value'] % 3600) / 60));
|
||||
} elseif ($goal->goal_type === 'distance') {
|
||||
$target_formatted = number_format($goal->target_value, 0, ',', ' ') . ' km';
|
||||
$current_formatted = number_format($progress['current_value'], 2, ',', ' ') . ' km';
|
||||
} else { // count
|
||||
$target_formatted = (int)$goal->target_value;
|
||||
$current_formatted = (int)$progress['current_value'];
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td>
|
||||
<strong><?php echo esc_html($goal->name); ?></strong><br>
|
||||
<small>
|
||||
<?php echo esc_html($goal->year); ?>
|
||||
<?php if($goal->month) echo ' / ' . date_i18n('F', mktime(0,0,0,$goal->month,10)); ?>
|
||||
<?php if($goal->category_name) echo ' / ' . esc_html($goal->category_name); ?>
|
||||
</small>
|
||||
</td>
|
||||
<td>
|
||||
<div class="mystat-progress-bar-container">
|
||||
<div class="mystat-progress-bar" style="width: <?php echo esc_attr($percentage); ?>%;"></div>
|
||||
</div>
|
||||
<small><?php echo $current_formatted; ?> z <?php echo $target_formatted; ?> (<?php echo round($percentage, 1); ?>%)</small>
|
||||
</td>
|
||||
<td>
|
||||
<a href="<?php echo esc_url( add_query_arg( [ 'action' => 'edit', 'id' => $goal->id ] ) ); ?>">Edytuj</a> |
|
||||
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( [ 'action' => 'delete', 'id' => $goal->id ] ), 'mystat_delete_goal_' . $goal->id ) ); ?>" onclick="return confirm('Czy na pewno chcesz usunąć ten cel?')" style="color: #a00;">Usuń</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.mystat-progress-bar-container { background: #eee; border-radius: 4px; height: 12px; width: 100%; overflow: hidden; margin-bottom: 4px; }
|
||||
.mystat-progress-bar { background: #3498db; height: 100%; border-radius: 4px; transition: width 0.5s ease-in-out; }
|
||||
</style>
|
||||
<?php
|
||||
}
|
||||
|
||||
function mystat_settings_page() {
|
||||
?>
|
||||
<div class="wrap">
|
||||
@@ -547,6 +822,13 @@ function mystat_yearly_summary_page() {
|
||||
$available_years = [current_time('Y')]; // Domyślny rok, jeśli brak danych
|
||||
}
|
||||
|
||||
// --- GOALS SECTION ---
|
||||
$table_goals = $wpdb->prefix . 'mystat_goals';
|
||||
$goals_for_year = $wpdb->get_results($wpdb->prepare(
|
||||
"SELECT * FROM {$table_goals} WHERE year = %d ORDER BY name ASC",
|
||||
$current_year
|
||||
));
|
||||
|
||||
// Zapytanie SQL do grupowania danych miesięcznie
|
||||
$sql = $wpdb->prepare("
|
||||
SELECT
|
||||
@@ -727,6 +1009,48 @@ function mystat_yearly_summary_page() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($goals_for_year)): ?>
|
||||
<div class="postbox" style="margin-bottom: 20px;">
|
||||
<div class="postbox-header"><h2 class="hndle">Cele na <?php echo esc_html($current_year); ?></h2></div>
|
||||
<div class="inside">
|
||||
<ul class="mystat-goals-list">
|
||||
<?php foreach ($goals_for_year as $goal): ?>
|
||||
<?php
|
||||
$progress = mystat_get_goal_progress($goal);
|
||||
$percentage = min(100, $progress['percentage']);
|
||||
|
||||
$target_formatted = '';
|
||||
$current_formatted = '';
|
||||
if ($goal->goal_type === 'duration_sec') {
|
||||
$target_formatted = round($goal->target_value / 3600) . ' godz.';
|
||||
$current_formatted = sprintf('%d godz. %d min.', floor($progress['current_value'] / 3600), floor(($progress['current_value'] % 3600) / 60));
|
||||
} elseif ($goal->goal_type === 'distance') {
|
||||
$target_formatted = number_format($goal->target_value, 0, ',', ' ') . ' km';
|
||||
$current_formatted = number_format($progress['current_value'], 2, ',', ' ') . ' km';
|
||||
} else { // count
|
||||
$target_formatted = (int)$goal->target_value;
|
||||
$current_formatted = (int)$progress['current_value'];
|
||||
}
|
||||
?>
|
||||
<li class="mystat-goal-item">
|
||||
<div class="mystat-goal-info">
|
||||
<strong><?php echo esc_html($goal->name); ?></strong>
|
||||
<small><?php echo $current_formatted; ?> / <?php echo $target_formatted; ?> (<?php echo round($percentage, 1); ?>%)</small>
|
||||
</div>
|
||||
<div class="mystat-progress-bar-container">
|
||||
<div class="mystat-progress-bar" style="width: <?php echo esc_attr($percentage); ?>%;"></div>
|
||||
</div>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
.mystat-goals-list { list-style: none; margin: 0; padding: 0; } .mystat-goal-item { margin-bottom: 15px; } .mystat-goal-info { display: flex; justify-content: space-between; margin-bottom: 5px; }
|
||||
.mystat-progress-bar-container { background: #eee; border-radius: 4px; height: 18px; width: 100%; overflow: hidden; } .mystat-progress-bar { background: #3498db; height: 100%; border-radius: 4px; transition: width 0.5s ease-in-out; text-align: center; color: white; font-size: 11px; line-height: 18px; }
|
||||
</style>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="postbox" style="margin-bottom: 20px;">
|
||||
<div class="postbox-header"><h2 class="hndle">Wykresy dla <?php echo esc_html($current_year); ?></h2></div>
|
||||
<div class="inside">
|
||||
@@ -2005,7 +2329,6 @@ function mystat_render_history_table() {
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
// --- 3. SHORTCODE DO WYŚWIETLANIA NA FRONCIE ---
|
||||
|
||||
Reference in New Issue
Block a user