Update repo

This commit is contained in:
2026-04-22 12:51:16 +02:00
parent d303a55638
commit d31591e287
24 changed files with 3994 additions and 3501 deletions
+198 -198
View File
@@ -1,199 +1,199 @@
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* 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 statpress_get_goal_progress( $goal ) {
global $wpdb;
$table_activities = $wpdb->prefix . 'statpress_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 array(
'current_value' => 0,
'percentage' => 0,
);
}
$where_clauses = array();
$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 array(
'current_value' => $current_value,
'percentage' => $percentage,
);
}
function statpress_goals_page() {
global $wpdb;
$table_goals = $wpdb->prefix . 'statpress_goals';
$table_categories = $wpdb->prefix . 'statpress_categories';
$message = '';
$notice_class = '';
// Handle POST requests (add/update)
if ( isset( $_POST['submit'] ) && check_admin_referer( 'statpress_manage_goal' ) ) {
$goal_id = isset( $_POST['goal_id'] ) ? intval( $_POST['goal_id'] ) : 0;
// Convert hours to seconds for duration goal type before saving
$target_value = floatval( str_replace( ',', '.', $_POST['target_value'] ) );
if ( 'duration_sec' === $_POST['goal_type'] ) {
$target_value *= 3600;
}
$data = array(
'name' => sanitize_text_field( $_POST['goal_name'] ),
'goal_type' => sanitize_text_field( $_POST['goal_type'] ),
'target_value' => $target_value,
'year' => intval( $_POST['year'] ),
'month' => 'all' === $_POST['month'] ? null : intval( $_POST['month'] ),
'category_id' => 'all' === $_POST['category_id'] ? 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, array( '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'] ) && 'delete' === $_GET['action'] ) {
if ( wp_verify_nonce( $_GET['_wpnonce'], 'statpress_delete_goal_' . $_GET['id'] ) ) {
$wpdb->delete( $table_goals, array( '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'] ) && 'edit' === $_GET['action'] ) {
$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( 'statpress_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( 'duration_sec' === $item_to_edit->goal_type ? $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
$progress = statpress_get_goal_progress( $goal );
$percentage = min( 100, $progress['percentage'] );
$target_formatted = '';
$current_formatted = '';
if ( 'duration_sec' === $goal->goal_type ) {
$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 ( 'distance' === $goal->goal_type ) {
$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="statpress-progress-bar-container">
<div class="statpress-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( array( 'action' => 'edit', 'id' => $goal->id ) ) ); ?>">Edytuj</a> |
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'delete', 'id' => $goal->id ) ), 'statpress_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>
.statpress-progress-bar-container { background: #eee; border-radius: 4px; height: 12px; width: 100%; overflow: hidden; margin-bottom: 4px; }
.statpress-progress-bar { background: #3498db; height: 100%; border-radius: 4px; transition: width 0.5s ease-in-out; }
</style>
<?php
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* 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 statpress_get_goal_progress( $goal ) {
global $wpdb;
$table_activities = $wpdb->prefix . 'statpress_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 array(
'current_value' => 0,
'percentage' => 0,
);
}
$where_clauses = array();
$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 array(
'current_value' => $current_value,
'percentage' => $percentage,
);
}
function statpress_goals_page() {
global $wpdb;
$table_goals = $wpdb->prefix . 'statpress_goals';
$table_categories = $wpdb->prefix . 'statpress_categories';
$message = '';
$notice_class = '';
// Handle POST requests (add/update)
if ( isset( $_POST['submit'] ) && check_admin_referer( 'statpress_manage_goal' ) ) {
$goal_id = isset( $_POST['goal_id'] ) ? intval( $_POST['goal_id'] ) : 0;
// Convert hours to seconds for duration goal type before saving
$target_value = floatval( str_replace( ',', '.', $_POST['target_value'] ) );
if ( 'duration_sec' === $_POST['goal_type'] ) {
$target_value *= 3600;
}
$data = array(
'name' => sanitize_text_field( $_POST['goal_name'] ),
'goal_type' => sanitize_text_field( $_POST['goal_type'] ),
'target_value' => $target_value,
'year' => intval( $_POST['year'] ),
'month' => 'all' === $_POST['month'] ? null : intval( $_POST['month'] ),
'category_id' => 'all' === $_POST['category_id'] ? 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, array( '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'] ) && 'delete' === $_GET['action'] ) {
if ( wp_verify_nonce( $_GET['_wpnonce'], 'statpress_delete_goal_' . $_GET['id'] ) ) {
$wpdb->delete( $table_goals, array( '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'] ) && 'edit' === $_GET['action'] ) {
$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( 'statpress_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( 'duration_sec' === $item_to_edit->goal_type ? $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
$progress = statpress_get_goal_progress( $goal );
$percentage = min( 100, $progress['percentage'] );
$target_formatted = '';
$current_formatted = '';
if ( 'duration_sec' === $goal->goal_type ) {
$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 ( 'distance' === $goal->goal_type ) {
$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="statpress-progress-bar-container">
<div class="statpress-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( array( 'action' => 'edit', 'id' => $goal->id ) ) ); ?>">Edytuj</a> |
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'delete', 'id' => $goal->id ) ), 'statpress_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>
.statpress-progress-bar-container { background: #eee; border-radius: 4px; height: 12px; width: 100%; overflow: hidden; margin-bottom: 4px; }
.statpress-progress-bar { background: #3498db; height: 100%; border-radius: 4px; transition: width 0.5s ease-in-out; }
</style>
<?php
}