Update repo
This commit is contained in:
@@ -58,3 +58,44 @@
|
|||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Form layout improvements */
|
||||||
|
.statpress-form-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statpress-form-group {
|
||||||
|
background: #fdfdfd;
|
||||||
|
border: 1px solid #e5e5e5;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statpress-form-group h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: 1em;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statpress-form-group p {
|
||||||
|
margin: 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statpress-form-group label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GPX Parser Status */
|
||||||
|
#gpx_parse_status {
|
||||||
|
vertical-align: middle;
|
||||||
|
color: #50575e;
|
||||||
|
}
|
||||||
|
#gpx_parse_status .spinner {
|
||||||
|
margin-top: -2px;
|
||||||
|
}
|
||||||
|
|||||||
+23
-23
@@ -1,34 +1,34 @@
|
|||||||
/* Styles for WordPress Activity Stats Plugin - Frontend Shortcodes */
|
/* Styles for WordPress Activity Stats Plugin - Frontend Shortcodes */
|
||||||
|
|
||||||
/* Shortcode [moje_statystyki] */
|
/* Shortcode [statpress_summary] */
|
||||||
.mystats-shortcode-container table {
|
.statpress-shortcode-container table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin-bottom: 2em;
|
margin-bottom: 2em;
|
||||||
}
|
}
|
||||||
.mystats-shortcode-container th,
|
.statpress-shortcode-container th,
|
||||||
.mystats-shortcode-container td {
|
.statpress-shortcode-container td {
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
.mystats-shortcode-container th {
|
.statpress-shortcode-container th {
|
||||||
background-color: #f4f4f4;
|
background-color: #f4f4f4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mystats-activity-table td:nth-child(4),
|
.statpress-activity-table td:nth-child(4),
|
||||||
.mystats-activity-table td:nth-child(5) {
|
.statpress-activity-table td:nth-child(5) {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Styles for the nested details table */
|
/* Styles for the nested details table */
|
||||||
.mystats-activity-details-row > .mystats-activity-details-cell {
|
.statpress-activity-details-row > .statpress-activity-details-cell {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
border-bottom: 1px solid #ddd;
|
border-bottom: 1px solid #ddd;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mystats-nested-details-table {
|
.statpress-nested-details-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-color: #fdfdfd;
|
background-color: #fdfdfd;
|
||||||
@@ -36,8 +36,8 @@
|
|||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mystats-nested-details-table th,
|
.statpress-nested-details-table th,
|
||||||
.mystats-nested-details-table td {
|
.statpress-nested-details-table td {
|
||||||
border: none !important;
|
border: none !important;
|
||||||
padding: 6px 12px;
|
padding: 6px 12px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
width: 33.33%;
|
width: 33.33%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mystats-nested-details-table th {
|
.statpress-nested-details-table th {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
color: #777;
|
color: #777;
|
||||||
@@ -53,49 +53,49 @@
|
|||||||
padding-bottom: 2px;
|
padding-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mystats-nested-details-table td {
|
.statpress-nested-details-table td {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shortcode [moje_statystyki_wpis] */
|
/* Shortcode [statpress_activity] */
|
||||||
.mystat-single-activity-shortcode {
|
.statpress-single-activity-shortcode {
|
||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
margin-bottom: 1.5em;
|
margin-bottom: 1.5em;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background: #f9f9f9;
|
background: #f9f9f9;
|
||||||
}
|
}
|
||||||
.mystat-single-activity-shortcode h4 {
|
.statpress-single-activity-shortcode h4 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
.mystat-single-activity-shortcode p em {
|
.statpress-single-activity-shortcode p em {
|
||||||
color: #777;
|
color: #777;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
.mystat-single-columns-container {
|
.statpress-single-columns-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
gap: 30px;
|
gap: 30px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
.mystat-single-col {
|
.statpress-single-col {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 240px;
|
min-width: 240px;
|
||||||
}
|
}
|
||||||
.mystat-single-summary-table {
|
.statpress-single-summary-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
}
|
}
|
||||||
.mystat-single-summary-table th,
|
.statpress-single-summary-table th,
|
||||||
.mystat-single-summary-table td {
|
.statpress-single-summary-table td {
|
||||||
padding: 4px 0;
|
padding: 4px 0;
|
||||||
border: none;
|
border: none;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
.mystat-single-summary-table th {
|
.statpress-single-summary-table th {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|||||||
@@ -14,16 +14,16 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function mystat_activate() {
|
function statpress_activate() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
$charset_collate = $wpdb->get_charset_collate();
|
$charset_collate = $wpdb->get_charset_collate();
|
||||||
|
|
||||||
$table_categories = $wpdb->prefix . 'mystat_categories';
|
$table_categories = $wpdb->prefix . 'statpress_categories';
|
||||||
$table_activities = $wpdb->prefix . 'mystat_activities';
|
$table_activities = $wpdb->prefix . 'statpress_activities';
|
||||||
$table_event_types = $wpdb->prefix . 'mystat_event_types';
|
$table_event_types = $wpdb->prefix . 'statpress_event_types';
|
||||||
$table_equipment = $wpdb->prefix . 'mystat_equipment';
|
$table_equipment = $wpdb->prefix . 'statpress_equipment';
|
||||||
$table_equipment_log = $wpdb->prefix . 'mystat_equipment_log';
|
$table_equipment_log = $wpdb->prefix . 'statpress_equipment_log';
|
||||||
$table_goals = $wpdb->prefix . 'mystat_goals';
|
$table_goals = $wpdb->prefix . 'statpress_goals';
|
||||||
|
|
||||||
// SQL dla Kategorii
|
// SQL dla Kategorii
|
||||||
$sql_cat = "CREATE TABLE $table_categories (
|
$sql_cat = "CREATE TABLE $table_categories (
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
/**
|
/**
|
||||||
* Set up admin-specific hooks.
|
* Set up admin-specific hooks.
|
||||||
*/
|
*/
|
||||||
function mystat_admin_init_setup() {
|
function statpress_admin_init_setup() {
|
||||||
add_filter( 'upload_mimes', 'mystat_add_gpx_mime_type' );
|
add_filter( 'upload_mimes', 'statpress_add_gpx_mime_type' );
|
||||||
add_filter( 'wp_check_filetype_and_ext', 'mystat_fix_gpx_upload_permission', 10, 4 );
|
add_filter( 'wp_check_filetype_and_ext', 'statpress_fix_gpx_upload_permission', 10, 4 );
|
||||||
mystat_register_settings();
|
statpress_register_settings();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -17,11 +17,11 @@ function mystat_admin_init_setup() {
|
|||||||
*
|
*
|
||||||
* @param string $hook The current admin page hook.
|
* @param string $hook The current admin page hook.
|
||||||
*/
|
*/
|
||||||
function mystat_enqueue_admin_styles( $hook ) {
|
function statpress_enqueue_admin_styles( $hook ) {
|
||||||
global $mystat_plugin_hooks;
|
global $statpress_plugin_hooks;
|
||||||
|
|
||||||
if ( in_array( $hook, $mystat_plugin_hooks, true ) ) {
|
if ( is_array( $statpress_plugin_hooks ) && in_array( $hook, $statpress_plugin_hooks, true ) ) {
|
||||||
$plugin_version = '1.0'; // You can use filemtime() for cache-busting in development
|
$plugin_version = '1.0'; // You can use filemtime() for cache-busting in development
|
||||||
wp_enqueue_style( 'mystat-admin-styles', MYSTAT_PLUGIN_URL . 'assets/css/admin.css', array(), $plugin_version );
|
wp_enqueue_style( 'statpress-admin-styles', STATPRESS_PLUGIN_URL . 'assets/css/admin.css', array(), $plugin_version );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+47
-47
@@ -14,110 +14,110 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function mystat_add_admin_menu() {
|
function statpress_add_admin_menu() {
|
||||||
global $mystat_plugin_hooks;
|
global $statpress_plugin_hooks;
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_menu_page(
|
$statpress_plugin_hooks[] = add_menu_page(
|
||||||
'Moje Statystyki', // Tytuł strony
|
'StatPress Dashboard', // Tytuł strony
|
||||||
'Statystyki', // Tytuł w menu
|
'StatPress', // Tytuł w menu
|
||||||
'manage_options', // Wymagane uprawnienia
|
'manage_options', // Wymagane uprawnienia
|
||||||
'moje-statystyki', // Slug menu
|
'statpress-dashboard', // Slug menu
|
||||||
'mystat_dashboard_page', // Funkcja renderująca stronę główną (dashboard)
|
'statpress_dashboard_page', // Funkcja renderująca stronę główną (dashboard)
|
||||||
'dashicons-chart-line', // Ikona
|
'dashicons-chart-line', // Ikona
|
||||||
6 // Pozycja
|
6 // Pozycja
|
||||||
);
|
);
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_submenu_page(
|
$statpress_plugin_hooks[] = add_submenu_page(
|
||||||
'moje-statystyki', // Slug rodzica
|
'statpress-dashboard', // Slug rodzica
|
||||||
'Dodaj Nowy Trening', // Tytuł strony
|
'Dodaj Nowy Trening', // Tytuł strony
|
||||||
'Nowy trening', // Tytuł w podmenu
|
'Nowy trening', // Tytuł w podmenu
|
||||||
'manage_options', // Wymagane uprawnienia
|
'manage_options', // Wymagane uprawnienia
|
||||||
'mystat-nowy-trening', // Slug podmenu
|
'statpress-add-new', // Slug podmenu
|
||||||
'mystat_add_new_page' // Funkcja renderująca stronę dodawania
|
'statpress_add_new_page' // Funkcja renderująca stronę dodawania
|
||||||
);
|
);
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_submenu_page(
|
$statpress_plugin_hooks[] = add_submenu_page(
|
||||||
'moje-statystyki',
|
'statpress-dashboard',
|
||||||
'Typy Wydarzeń',
|
'Typy Wydarzeń',
|
||||||
'Typy wydarzeń',
|
'Typy wydarzeń',
|
||||||
'manage_options',
|
'manage_options',
|
||||||
'mystat-event-types',
|
'statpress-event-types',
|
||||||
'mystat_event_types_page'
|
'statpress_event_types_page'
|
||||||
);
|
);
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_submenu_page(
|
$statpress_plugin_hooks[] = add_submenu_page(
|
||||||
'moje-statystyki',
|
'statpress-dashboard',
|
||||||
'Sprzęt',
|
'Sprzęt',
|
||||||
'Sprzęt',
|
'Sprzęt',
|
||||||
'manage_options',
|
'manage_options',
|
||||||
'mystat-equipment',
|
'statpress-equipment',
|
||||||
'mystat_equipment_page'
|
'statpress_equipment_page'
|
||||||
);
|
);
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_submenu_page(
|
$statpress_plugin_hooks[] = add_submenu_page(
|
||||||
'moje-statystyki',
|
'statpress-dashboard',
|
||||||
'Cele',
|
'Cele',
|
||||||
'Cele',
|
'Cele',
|
||||||
'manage_options',
|
'manage_options',
|
||||||
'mystat-goals',
|
'statpress-goals',
|
||||||
'mystat_goals_page'
|
'statpress_goals_page'
|
||||||
);
|
);
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_submenu_page(
|
$statpress_plugin_hooks[] = add_submenu_page(
|
||||||
null, 'Dziennik Serwisowy', 'Dziennik Serwisowy', 'manage_options', 'mystat-equipment-details', 'mystat_equipment_details_page'
|
null, 'Dziennik Serwisowy', 'Dziennik Serwisowy', 'manage_options', 'statpress-equipment-details', 'statpress_equipment_details_page'
|
||||||
);
|
);
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_submenu_page(
|
$statpress_plugin_hooks[] = add_submenu_page(
|
||||||
null, // Ukryta strona, nie pojawia się w menu
|
null, // Ukryta strona, nie pojawia się w menu
|
||||||
'Szczegóły Treningu', // Tytuł strony
|
'Szczegóły Treningu', // Tytuł strony
|
||||||
'Szczegóły Treningu', // Tytuł w menu (nieistotny)
|
'Szczegóły Treningu', // Tytuł w menu (nieistotny)
|
||||||
'manage_options', // Wymagane uprawnienia
|
'manage_options', // Wymagane uprawnienia
|
||||||
'mystat-view-activity', // Slug podmenu
|
'statpress-view-activity', // Slug podmenu
|
||||||
'mystat_view_activity_page' // Funkcja renderująca
|
'statpress_view_activity_page' // Funkcja renderująca
|
||||||
);
|
);
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_submenu_page(
|
$statpress_plugin_hooks[] = add_submenu_page(
|
||||||
null, // Ukryta strona
|
null, // Ukryta strona
|
||||||
'Edytuj Trening', // Tytuł strony
|
'Edytuj Trening', // Tytuł strony
|
||||||
'Edytuj Trening', // Tytuł w menu (nieistotny)
|
'Edytuj Trening', // Tytuł w menu (nieistotny)
|
||||||
'manage_options', // Wymagane uprawnienia
|
'manage_options', // Wymagane uprawnienia
|
||||||
'mystat-edit-activity', // Slug podmenu
|
'statpress-edit-activity', // Slug podmenu
|
||||||
'mystat_edit_activity_page' // Funkcja renderująca
|
'statpress_edit_activity_page' // Funkcja renderująca
|
||||||
);
|
);
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_submenu_page(
|
$statpress_plugin_hooks[] = add_submenu_page(
|
||||||
'moje-statystyki', // Slug rodzica
|
'statpress-dashboard', // Slug rodzica
|
||||||
'Podsumowanie Roczne', // Tytuł strony
|
'Podsumowanie Roczne', // Tytuł strony
|
||||||
'Podsumowanie Roczne', // Tytuł w podmenu
|
'Podsumowanie Roczne', // Tytuł w podmenu
|
||||||
'manage_options', // Wymagane uprawnienia
|
'manage_options', // Wymagane uprawnienia
|
||||||
'mystat-yearly-summary', // Slug podmenu
|
'statpress-yearly-summary', // Slug podmenu
|
||||||
'mystat_yearly_summary_page'// Funkcja renderująca
|
'statpress_yearly_summary_page'// Funkcja renderująca
|
||||||
);
|
);
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_submenu_page(
|
$statpress_plugin_hooks[] = add_submenu_page(
|
||||||
'moje-statystyki', // Slug rodzica
|
'statpress-dashboard', // Slug rodzica
|
||||||
'Infografika', // Tytuł strony
|
'Infografika', // Tytuł strony
|
||||||
'Infografika', // Tytuł w podmenu
|
'Infografika', // Tytuł w podmenu
|
||||||
'manage_options', // Wymagane uprawnienia
|
'manage_options', // Wymagane uprawnienia
|
||||||
'mystat-infographic', // Slug podmenu
|
'statpress-infographic', // Slug podmenu
|
||||||
'mystat_infographic_page' // Funkcja renderująca
|
'statpress_infographic_page' // Funkcja renderująca
|
||||||
);
|
);
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_submenu_page(
|
$statpress_plugin_hooks[] = add_submenu_page(
|
||||||
'moje-statystyki', // Slug rodzica
|
'statpress-dashboard', // Slug rodzica
|
||||||
'Import CSV', // Tytuł strony
|
'Import CSV', // Tytuł strony
|
||||||
'Import CSV', // Tytuł w podmenu
|
'Import CSV', // Tytuł w podmenu
|
||||||
'manage_options', // Wymagane uprawnienia
|
'manage_options', // Wymagane uprawnienia
|
||||||
'mystat-import-csv', // Slug podmenu
|
'statpress-import-csv', // Slug podmenu
|
||||||
'mystat_import_csv_page' // Funkcja renderująca
|
'statpress_import_csv_page' // Funkcja renderująca
|
||||||
);
|
);
|
||||||
|
|
||||||
$mystat_plugin_hooks[] = add_submenu_page(
|
$statpress_plugin_hooks[] = add_submenu_page(
|
||||||
'moje-statystyki', // Slug rodzica
|
'statpress-dashboard', // Slug rodzica
|
||||||
'Ustawienia', // Tytuł strony
|
'Ustawienia', // Tytuł strony
|
||||||
'Ustawienia', // Tytuł w podmenu
|
'Ustawienia', // Tytuł w podmenu
|
||||||
'manage_options', // Wymagane uprawnienia
|
'manage_options', // Wymagane uprawnienia
|
||||||
'mystat-settings', // Slug podmenu
|
'statpress-settings', // Slug podmenu
|
||||||
'mystat_settings_page' // Funkcja renderująca
|
'statpress_settings_page' // Funkcja renderująca
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -106,6 +106,18 @@ function statpress_render_add_form( $activity = null ) {
|
|||||||
<th scope="row"><label for="title">Tytuł</label></th>
|
<th scope="row"><label for="title">Tytuł</label></th>
|
||||||
<td><input type="text" name="title" id="title" class="large-text" placeholder="np. Poranny trening w lesie" value="<?php echo $is_edit_mode ? esc_attr( $activity->title ) : ''; ?>" required></td>
|
<td><input type="text" name="title" id="title" class="large-text" placeholder="np. Poranny trening w lesie" value="<?php echo $is_edit_mode ? esc_attr( $activity->title ) : ''; ?>" required></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row"><label for="gpx_url">Link do pliku GPX</label></th>
|
||||||
|
<td>
|
||||||
|
<input type="text" name="gpx_url" id="gpx_url" class="large-text" placeholder="Wklej URL lub wgraj plik..." value="<?php echo $is_edit_mode ? esc_attr( $activity->gpx_url ) : ''; ?>" style="width: calc(100% - 150px); margin-right: 10px;">
|
||||||
|
<span id="gpx_parse_status"></span>
|
||||||
|
<button type="button" class="button" id="upload_gpx_button" style="margin-top: 5px;">Wgraj lub wybierz plik</button>
|
||||||
|
<p class="description">Wklej link lub wgraj plik GPX, aby automatycznie uzupełnić pola poniżej.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" style="padding: 15px 0 5px;"><hr></td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><label for="category_id">Kategoria</label></th>
|
<th scope="row"><label for="category_id">Kategoria</label></th>
|
||||||
<td>
|
<td>
|
||||||
@@ -155,67 +167,45 @@ function statpress_render_add_form( $activity = null ) {
|
|||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="form-field">
|
|
||||||
<td colspan="2"><hr><h4>Dane szczegółowe (opcjonalne)</h4></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><label for="avg_speed">Śr. prędkość (km/h)</label></th>
|
<td colspan="2" style="padding: 20px 0;">
|
||||||
<td><input type="text" name="avg_speed" id="avg_speed" class="small-text" placeholder="0,0" value="<?php echo $is_edit_mode ? esc_attr( number_format( (float) $activity->avg_speed, 2, ',', '' ) ) : ''; ?>"></td>
|
<hr>
|
||||||
</tr>
|
<h3 style="font-size: 1.2em; margin: 1em 0;">Dane szczegółowe (opcjonalne)</h3>
|
||||||
<tr>
|
<div class="statpress-form-grid">
|
||||||
<th scope="row"><label for="max_speed">Maks. prędkość (km/h)</label></th>
|
<div class="statpress-form-group">
|
||||||
<td><input type="text" name="max_speed" id="max_speed" class="small-text" placeholder="0,0" value="<?php echo $is_edit_mode ? esc_attr( number_format( (float) $activity->max_speed, 2, ',', '' ) ) : ''; ?>"></td>
|
<h3><span class="dashicons dashicons-dashboard" style="vertical-align: middle;"></span> Prędkość</h3>
|
||||||
</tr>
|
<p><label for="avg_speed">Średnia (km/h)</label><input type="text" name="avg_speed" id="avg_speed" placeholder="0,0" value="<?php echo $is_edit_mode ? esc_attr( number_format( (float) $activity->avg_speed, 2, ',', '' ) ) : ''; ?>"></p>
|
||||||
<tr>
|
<p><label for="max_speed">Maksymalna (km/h)</label><input type="text" name="max_speed" id="max_speed" placeholder="0,0" value="<?php echo $is_edit_mode ? esc_attr( number_format( (float) $activity->max_speed, 2, ',', '' ) ) : ''; ?>"></p>
|
||||||
<th scope="row"><label for="avg_heart_rate">Śr. tętno</label></th>
|
</div>
|
||||||
<td><input type="number" name="avg_heart_rate" id="avg_heart_rate" class="small-text" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->avg_heart_rate ) : ''; ?>"></td>
|
<div class="statpress-form-group">
|
||||||
</tr>
|
<h3><span class="dashicons dashicons-heart" style="vertical-align: middle;"></span> Tętno</h3>
|
||||||
<tr>
|
<p><label for="avg_heart_rate">Średnie (bpm)</label><input type="number" name="avg_heart_rate" id="avg_heart_rate" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->avg_heart_rate ) : ''; ?>"></p>
|
||||||
<th scope="row"><label for="max_heart_rate">Maks. tętno</label></th>
|
<p><label for="max_heart_rate">Maksymalne (bpm)</label><input type="number" name="max_heart_rate" id="max_heart_rate" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->max_heart_rate ) : ''; ?>"></p>
|
||||||
<td><input type="number" name="max_heart_rate" id="max_heart_rate" class="small-text" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->max_heart_rate ) : ''; ?>"></td>
|
</div>
|
||||||
</tr>
|
<div class="statpress-form-group">
|
||||||
<tr>
|
<h3><span class="dashicons dashicons-update" style="vertical-align: middle;"></span> Rytm</h3>
|
||||||
<th scope="row"><label for="avg_cadence">Śr. rytm pedałowania</label></th>
|
<p><label for="avg_cadence">Średni (rpm)</label><input type="number" name="avg_cadence" id="avg_cadence" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->avg_cadence ) : ''; ?>"></p>
|
||||||
<td><input type="number" name="avg_cadence" id="avg_cadence" class="small-text" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->avg_cadence ) : ''; ?>"></td>
|
<p><label for="max_cadence">Maksymalny (rpm)</label><input type="number" name="max_cadence" id="max_cadence" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->max_cadence ) : ''; ?>"></p>
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
<div class="statpress-form-group">
|
||||||
<th scope="row"><label for="max_cadence">Maks. rytm pedałowania</label></th>
|
<h3><span class="dashicons dashicons-chart-area" style="vertical-align: middle;"></span> Wysokość</h3>
|
||||||
<td><input type="number" name="max_cadence" id="max_cadence" class="small-text" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->max_cadence ) : ''; ?>"></td>
|
<p><label for="total_elevation_gain">Suma wzniosów (m)</label><input type="number" name="total_elevation_gain" id="total_elevation_gain" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->total_elevation_gain ) : ''; ?>"></p>
|
||||||
</tr>
|
<p><label for="total_elevation_loss">Suma spadków (m)</label><input type="number" name="total_elevation_loss" id="total_elevation_loss" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->total_elevation_loss ) : ''; ?>"></p>
|
||||||
<tr>
|
<p><label for="min_altitude">Min. wysokość (m n.p.m.)</label><input type="number" name="min_altitude" id="min_altitude" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->min_altitude ) : ''; ?>"></p>
|
||||||
<th scope="row"><label for="total_elevation_gain">Całkowity wznios (m)</label></th>
|
<p><label for="max_altitude">Maks. wysokość (m n.p.m.)</label><input type="number" name="max_altitude" id="max_altitude" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->max_altitude ) : ''; ?>"></p>
|
||||||
<td><input type="number" name="total_elevation_gain" id="total_elevation_gain" class="small-text" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->total_elevation_gain ) : ''; ?>"></td>
|
</div>
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
<hr style="margin-top: 2em;">
|
||||||
<th scope="row"><label for="total_elevation_loss">Całkowity spadek (m)</label></th>
|
</td>
|
||||||
<td><input type="number" name="total_elevation_loss" id="total_elevation_loss" class="small-text" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->total_elevation_loss ) : ''; ?>"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row"><label for="min_altitude">Min. wysokość (m)</labe></th>
|
|
||||||
<td><input type="number" name="min_altitude" id="min_altitude" class="small-text" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->min_altitude ) : ''; ?>"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<th scope="row"><label for="max_altitude">Maks. wysokość (m)</label></th>
|
|
||||||
<td><input type="number" name="max_altitude" id="max_altitude" class="small-text" placeholder="0" value="<?php echo $is_edit_mode ? esc_attr( $activity->max_altitude ) : ''; ?>"></td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><label for="comment">Komentarz</label></th>
|
<th scope="row"><label for="comment">Komentarz</label></th>
|
||||||
<td><textarea name="comment" id="comment" rows="3" class="large-text"><?php echo $is_edit_mode ? esc_textarea( $activity->comment ) : ''; ?></textarea></td>
|
<td><textarea name="comment" id="comment" rows="3" class="large-text"><?php echo $is_edit_mode ? esc_textarea( $activity->comment ) : ''; ?></textarea></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="form-field">
|
|
||||||
<td colspan="2"><hr><h4>Linki zewnętrzne (opcjonalne)</h4></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><label for="strava_url">Link do Strava</label></th>
|
<th scope="row"><label for="strava_url">Link do Strava</label></th>
|
||||||
<td><input type="url" name="strava_url" id="strava_url" class="large-text" placeholder="https://www.strava.com/activities/..." value="<?php echo $is_edit_mode ? esc_attr( $activity->strava_url ) : ''; ?>"></td>
|
<td><input type="url" name="strava_url" id="strava_url" class="large-text" placeholder="https://www.strava.com/activities/..." value="<?php echo $is_edit_mode ? esc_attr( $activity->strava_url ) : ''; ?>"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<th scope="row"><label for="gpx_url">Link do pliku GPX</label></th>
|
|
||||||
<td>
|
|
||||||
<input type="text" name="gpx_url" id="gpx_url" class="large-text" placeholder="Wklej URL lub wgraj plik..." value="<?php echo $is_edit_mode ? esc_attr( $activity->gpx_url ) : ''; ?>">
|
|
||||||
<button type="button" class="button" id="upload_gpx_button" style="margin-top: 5px;">Wgraj lub wybierz plik</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
</table>
|
||||||
<p class="submit">
|
<p class="submit">
|
||||||
<input type="submit" name="statpress_submit_activity" id="submit" class="button button-primary" value="<?php echo esc_attr( $button_text ); ?>">
|
<input type="submit" name="statpress_submit_activity" id="submit" class="button button-primary" value="<?php echo esc_attr( $button_text ); ?>">
|
||||||
@@ -236,6 +226,76 @@ function statpress_render_add_form( $activity = null ) {
|
|||||||
$('#gpx_url').val(attachment.url).trigger('change');
|
$('#gpx_url').val(attachment.url).trigger('change');
|
||||||
}).open();
|
}).open();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// --- GPX Auto-fill Feature ---
|
||||||
|
const gpxUrlInput = $('#gpx_url');
|
||||||
|
const statusEl = $('#gpx_parse_status');
|
||||||
|
let debounceTimer;
|
||||||
|
|
||||||
|
gpxUrlInput.on('input change', function() {
|
||||||
|
clearTimeout(debounceTimer);
|
||||||
|
debounceTimer = setTimeout(function() {
|
||||||
|
const url = gpxUrlInput.val();
|
||||||
|
if (url && url.toLowerCase().endsWith('.gpx')) {
|
||||||
|
parseGpx(url);
|
||||||
|
}
|
||||||
|
}, 500); // 500ms delay to avoid firing on every keystroke
|
||||||
|
});
|
||||||
|
|
||||||
|
function parseGpx(url) {
|
||||||
|
statusEl.html('<span class="spinner is-active" style="float:none; vertical-align: middle;"></span> Analizuję plik...');
|
||||||
|
|
||||||
|
wp.apiFetch({
|
||||||
|
path: '/statpress/v1/gpx/parse-summary',
|
||||||
|
method: 'POST',
|
||||||
|
data: { gpx_url: url }
|
||||||
|
})
|
||||||
|
.then(function(data) {
|
||||||
|
statusEl.html('<span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span> Dane wczytane!');
|
||||||
|
|
||||||
|
const fieldsToCheck = [
|
||||||
|
'#distance', '#duration', '#calories', '#avg_speed', '#max_speed',
|
||||||
|
'#avg_heart_rate', '#max_heart_rate', '#avg_cadence', '#max_cadence',
|
||||||
|
'#total_elevation_gain', '#total_elevation_loss', '#min_altitude', '#max_altitude'
|
||||||
|
];
|
||||||
|
|
||||||
|
let hasExistingData = false;
|
||||||
|
fieldsToCheck.forEach(function(selector) {
|
||||||
|
const field = $(selector);
|
||||||
|
if (field.val() && field.val() !== '00:00:00' && field.val() !== '0' && field.val() !== '0,00') {
|
||||||
|
hasExistingData = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let proceed = true;
|
||||||
|
if (hasExistingData) {
|
||||||
|
proceed = confirm('Niektóre pola formularza zawierają już dane. Czy na pewno chcesz je nadpisać danymi z pliku GPX?');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proceed) {
|
||||||
|
const formatNum = (num) => String(num).replace('.', ',');
|
||||||
|
|
||||||
|
if (data.distance) $('#distance').val(formatNum(data.distance));
|
||||||
|
if (data.duration) $('#duration').val(data.duration);
|
||||||
|
if (data.avg_speed) $('#avg_speed').val(formatNum(data.avg_speed));
|
||||||
|
if (data.max_speed) $('#max_speed').val(formatNum(data.max_speed));
|
||||||
|
if (data.avg_heart_rate) $('#avg_heart_rate').val(data.avg_heart_rate);
|
||||||
|
if (data.max_heart_rate) $('#max_heart_rate').val(data.max_heart_rate);
|
||||||
|
if (data.avg_cadence) $('#avg_cadence').val(data.avg_cadence);
|
||||||
|
if (data.max_cadence) $('#max_cadence').val(data.max_cadence);
|
||||||
|
if (data.total_elevation_gain) $('#total_elevation_gain').val(data.total_elevation_gain);
|
||||||
|
if (data.total_elevation_loss) $('#total_elevation_loss').val(data.total_elevation_loss);
|
||||||
|
if (data.min_altitude) $('#min_altitude').val(data.min_altitude);
|
||||||
|
if (data.max_altitude) $('#max_altitude').val(data.max_altitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => statusEl.html(''), 4000);
|
||||||
|
})
|
||||||
|
.catch(function(error) {
|
||||||
|
const errorMsg = error.message || 'Nieznany błąd.';
|
||||||
|
statusEl.html('<span class="dashicons dashicons-warning" style="color: #d63638;"></span> Błąd: ' + errorMsg);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,6 +5,44 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
|
|
||||||
function statpress_dashboard_page() {
|
function statpress_dashboard_page() {
|
||||||
echo '<div class="wrap"><h1>StatPress Dashboard</h1>';
|
echo '<div class="wrap"><h1>StatPress Dashboard</h1>';
|
||||||
|
|
||||||
|
// --- MIGRATION NOTICE ---
|
||||||
|
// Show the migration button if it hasn't been completed yet.
|
||||||
|
if ( ! get_option( 'statpress_migration_complete' ) ) {
|
||||||
|
$migration_url = wp_nonce_url(
|
||||||
|
admin_url( 'admin.php?page=statpress-dashboard&action=statpress_migrate_data' ),
|
||||||
|
'statpress_migration_nonce'
|
||||||
|
);
|
||||||
|
echo '<div class="notice notice-warning is-dismissible" style="padding-bottom: 10px;">';
|
||||||
|
echo '<h4>Migracja danych StatPress</h4>';
|
||||||
|
echo '<p>Wygląda na to, że istnieją dane w starych tabelach (<code>mystat_*</code>), które można przenieść. Kliknij przycisk poniżej, aby rozpocząć proces.</p>';
|
||||||
|
echo '<p><strong>Ważne:</strong> Ta operacja jest jednorazowa i powinna być wykonana tylko raz, na pustej instalacji wtyczki StatPress.</p>';
|
||||||
|
echo '<a href="' . esc_url( $migration_url ) . '" class="button button-primary">Rozpocznij migrację danych</a>';
|
||||||
|
echo '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the results of the migration after it's done.
|
||||||
|
$migration_results = get_transient( 'statpress_migration_results' );
|
||||||
|
if ( $migration_results ) {
|
||||||
|
echo '<div class="notice notice-success is-dismissible">';
|
||||||
|
echo '<h4>Migracja zakończona!</h4>';
|
||||||
|
echo '<ul>';
|
||||||
|
foreach ( $migration_results as $table => $result ) {
|
||||||
|
if ( 'success' === $result['status'] ) {
|
||||||
|
echo '<li>Tabela <strong>' . esc_html( $table ) . '</strong>: Przeniesiono <strong>' . esc_html( $result['count'] ) . '</strong> wierszy.</li>';
|
||||||
|
} elseif ( 'skipped' === $result['status'] ) {
|
||||||
|
echo '<li>Tabela <strong>' . esc_html( $table ) . '</strong>: Pominięto, ponieważ nowa tabela zawiera już dane (' . esc_html( $result['count'] ) . ' wierszy).</li>';
|
||||||
|
} elseif ( 'failure' === $result['status'] ) {
|
||||||
|
echo '<li>Tabela <strong>' . esc_html( $table ) . '</strong>: <strong style="color:red;">Migracja nieudana.</strong> Błąd bazy danych: <pre style="display:inline;white-space:pre-wrap;">' . esc_html( $result['error'] ) . '</pre></li>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
echo '</ul>';
|
||||||
|
echo '<p>Twoje dane powinny być teraz widoczne. Stare tabele (<code>' . esc_html( $GLOBALS['wpdb']->prefix ) . 'mystat_*</code>) wciąż istnieją w bazie danych, ale nie są już używane. Możesz je usunąć ręcznie (np. przez phpMyAdmin), jeśli wszystko działa poprawnie.</p>';
|
||||||
|
echo '</div>';
|
||||||
|
delete_transient( 'statpress_migration_results' );
|
||||||
|
}
|
||||||
|
// --- END MIGRATION NOTICE ---
|
||||||
|
|
||||||
statpress_render_history_table();
|
statpress_render_history_table();
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,39 +6,68 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
function statpress_settings_page() {
|
function statpress_settings_page() {
|
||||||
?>
|
?>
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
|
<?php
|
||||||
|
if ( get_transient( 'statpress_migration_reset_notice' ) ) {
|
||||||
|
echo '<div class="notice notice-success is-dismissible"><p>Status migracji został zresetowany. Wróć do <a href="' . esc_url( admin_url( 'admin.php?page=statpress-dashboard' ) ) . '">głównego panelu</a>, aby ponownie uruchomić migrację.</p></div>';
|
||||||
|
delete_transient( 'statpress_migration_reset_notice' );
|
||||||
|
}
|
||||||
|
?>
|
||||||
<h1>Ustawienia Wtyczki Statystyk</h1>
|
<h1>Ustawienia Wtyczki Statystyk</h1>
|
||||||
<form method="post" action="options.php">
|
<form method="post" action="options.php">
|
||||||
<?php
|
<?php
|
||||||
settings_fields( 'statpress_privacy_settings' );
|
settings_fields( 'statpress_settings_group' );
|
||||||
do_settings_sections( 'statpress-privacy-section' );
|
do_settings_sections( 'statpress_settings_page' );
|
||||||
settings_fields( 'statpress_api_settings' );
|
|
||||||
do_settings_sections( 'statpress-api-section' );
|
|
||||||
submit_button();
|
submit_button();
|
||||||
?>
|
?>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
<h2>Narzędzia deweloperskie</h2>
|
||||||
|
<div class="postbox">
|
||||||
|
<div class="postbox-header"><h3 class="hndle">Resetowanie migracji</h3></div>
|
||||||
|
<div class="inside">
|
||||||
|
<p>Jeśli migracja danych nie powiodła się, a przycisk do jej ponownego uruchomienia zniknął, możesz użyć tego narzędzia, aby zresetować status migracji. Po kliknięciu, przycisk w głównym panelu wtyczki pojawi się ponownie.</p>
|
||||||
|
<form method="post">
|
||||||
|
<input type="hidden" name="statpress_action" value="reset_migration"><?php wp_nonce_field( 'statpress_reset_migration_nonce', '_wpnonce' ); ?><?php submit_button( 'Zresetuj status migracji', 'delete' ); ?></form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
|
||||||
function statpress_register_settings() {
|
function statpress_register_settings() {
|
||||||
|
// Define a single group and page for all settings on this form.
|
||||||
|
$option_group = 'statpress_settings_group';
|
||||||
|
$page_slug = 'statpress_settings_page';
|
||||||
|
|
||||||
|
// Register Privacy settings under the main group.
|
||||||
register_setting(
|
register_setting(
|
||||||
'statpress_privacy_settings',
|
$option_group,
|
||||||
'statpress_privacy_options',
|
'statpress_privacy_options',
|
||||||
'statpress_sanitize_privacy_options'
|
'statpress_sanitize_privacy_options'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Register API settings under the same main group.
|
||||||
|
register_setting(
|
||||||
|
$option_group,
|
||||||
|
'statpress_api_options',
|
||||||
|
'statpress_sanitize_api_options'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add the Privacy section to the main page.
|
||||||
add_settings_section(
|
add_settings_section(
|
||||||
'statpress_privacy_zone_section',
|
'statpress_privacy_zone_section',
|
||||||
'Strefa Prywatności GPX',
|
'Strefa Prywatności GPX',
|
||||||
'statpress_privacy_section_callback',
|
'statpress_privacy_section_callback',
|
||||||
'statpress-privacy-section'
|
$page_slug
|
||||||
);
|
);
|
||||||
|
|
||||||
add_settings_field(
|
add_settings_field(
|
||||||
'statpress_privacy_latitude',
|
'statpress_privacy_latitude',
|
||||||
'Szerokość geograficzna (Latitude)',
|
'Szerokość geograficzna (Latitude)',
|
||||||
'statpress_render_lat_field',
|
'statpress_render_lat_field',
|
||||||
'statpress-privacy-section',
|
$page_slug,
|
||||||
'statpress_privacy_zone_section'
|
'statpress_privacy_zone_section'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -46,7 +75,7 @@ function statpress_register_settings() {
|
|||||||
'statpress_privacy_longitude',
|
'statpress_privacy_longitude',
|
||||||
'Długość geograficzna (Longitude)',
|
'Długość geograficzna (Longitude)',
|
||||||
'statpress_render_lon_field',
|
'statpress_render_lon_field',
|
||||||
'statpress-privacy-section',
|
$page_slug,
|
||||||
'statpress_privacy_zone_section'
|
'statpress_privacy_zone_section'
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -54,30 +83,24 @@ function statpress_register_settings() {
|
|||||||
'statpress_privacy_radius',
|
'statpress_privacy_radius',
|
||||||
'Promień strefy (w metrach)',
|
'Promień strefy (w metrach)',
|
||||||
'statpress_render_radius_field',
|
'statpress_render_radius_field',
|
||||||
'statpress-privacy-section',
|
$page_slug,
|
||||||
'statpress_privacy_zone_section'
|
'statpress_privacy_zone_section'
|
||||||
);
|
);
|
||||||
|
|
||||||
// API Settings
|
// Add the API section to the same main page.
|
||||||
register_setting(
|
|
||||||
'statpress_api_settings',
|
|
||||||
'statpress_api_options',
|
|
||||||
'statpress_sanitize_api_options'
|
|
||||||
);
|
|
||||||
|
|
||||||
add_settings_section(
|
add_settings_section(
|
||||||
'statpress_api_section',
|
'statpress_api_section',
|
||||||
'Ustawienia API',
|
'Ustawienia API',
|
||||||
'statpress_api_section_callback',
|
'statpress_api_section_callback',
|
||||||
'statpress-api-section'
|
$page_slug
|
||||||
);
|
);
|
||||||
|
|
||||||
add_settings_field(
|
add_settings_field(
|
||||||
'statpress_enable_api',
|
'statpress_enable_api',
|
||||||
'REST API',
|
'REST API',
|
||||||
'statpress_render_enable_api_field',
|
'statpress_render_enable_api_field',
|
||||||
'statpress-privacy-section',
|
$page_slug,
|
||||||
'statpress_privacy_zone_section'
|
'statpress_api_section'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,23 @@ function statpress_register_rest_routes() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Route for parsing GPX file summary
|
||||||
|
register_rest_route(
|
||||||
|
$namespace,
|
||||||
|
'/gpx/parse-summary',
|
||||||
|
array(
|
||||||
|
'methods' => WP_REST_Server::CREATABLE, // Use POST to send URL in the body
|
||||||
|
'callback' => 'statpress_parse_gpx_summary_api',
|
||||||
|
'permission_callback' => 'statpress_api_permissions_check',
|
||||||
|
'args' => array(
|
||||||
|
'gpx_url' => array(
|
||||||
|
'required' => true,
|
||||||
|
'validate_callback' => 'esc_url_raw',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -88,6 +105,10 @@ function statpress_get_activities_api( WP_REST_Request $request ) {
|
|||||||
$page = $request->get_param( 'page' ) ? (int) $request->get_param( 'page' ) : 1;
|
$page = $request->get_param( 'page' ) ? (int) $request->get_param( 'page' ) : 1;
|
||||||
$offset = ( $page - 1 ) * $per_page;
|
$offset = ( $page - 1 ) * $per_page;
|
||||||
|
|
||||||
|
// Get total items for pagination headers
|
||||||
|
$total_items = (int) $wpdb->get_var( "SELECT COUNT(id) FROM $table_activities" );
|
||||||
|
$total_pages = ceil( $total_items / $per_page );
|
||||||
|
|
||||||
$sql = $wpdb->prepare(
|
$sql = $wpdb->prepare(
|
||||||
"SELECT a.*, c.name as category_name, et.name as event_type_name, eq.name as equipment_name
|
"SELECT a.*, c.name as category_name, et.name as event_type_name, eq.name as equipment_name
|
||||||
FROM $table_activities a
|
FROM $table_activities a
|
||||||
@@ -102,7 +123,11 @@ function statpress_get_activities_api( WP_REST_Request $request ) {
|
|||||||
|
|
||||||
$results = $wpdb->get_results( $sql );
|
$results = $wpdb->get_results( $sql );
|
||||||
|
|
||||||
return new WP_REST_Response( $results, 200 );
|
$response = new WP_REST_Response( $results, 200 );
|
||||||
|
$response->header( 'X-WP-Total', $total_items );
|
||||||
|
$response->header( 'X-WP-TotalPages', $total_pages );
|
||||||
|
|
||||||
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -115,7 +140,16 @@ function statpress_get_activity_api( WP_REST_Request $request ) {
|
|||||||
global $wpdb;
|
global $wpdb;
|
||||||
$id = (int) $request['id'];
|
$id = (int) $request['id'];
|
||||||
|
|
||||||
$sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}statpress_activities WHERE id = %d", $id );
|
// Use the same rich query as the collection endpoint for consistency.
|
||||||
|
$sql = $wpdb->prepare(
|
||||||
|
"SELECT a.*, c.name as category_name, et.name as event_type_name, eq.name as equipment_name
|
||||||
|
FROM {$wpdb->prefix}statpress_activities a
|
||||||
|
LEFT JOIN {$wpdb->prefix}statpress_categories c ON a.category_id = c.id
|
||||||
|
LEFT JOIN {$wpdb->prefix}statpress_event_types et ON a.event_type_id = et.id
|
||||||
|
LEFT JOIN {$wpdb->prefix}statpress_equipment eq ON a.equipment_id = eq.id
|
||||||
|
WHERE a.id = %d",
|
||||||
|
$id
|
||||||
|
);
|
||||||
$activity = $wpdb->get_row( $sql );
|
$activity = $wpdb->get_row( $sql );
|
||||||
|
|
||||||
if ( ! $activity ) {
|
if ( ! $activity ) {
|
||||||
@@ -139,7 +173,10 @@ function statpress_create_activity_api( WP_REST_Request $request ) {
|
|||||||
return new WP_Error( 'cant-create', 'Error creating activity', array( 'status' => 500 ) );
|
return new WP_Error( 'cant-create', 'Error creating activity', array( 'status' => 500 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
$response = statpress_get_activity_api( new WP_REST_Request( 'GET', "/statpress/v1/activities/{$activity_id}" ) );
|
// Create a new request object to fetch the newly created activity.
|
||||||
|
$new_request = new WP_REST_Request();
|
||||||
|
$new_request->set_param( 'id', $activity_id );
|
||||||
|
$response = statpress_get_activity_api( $new_request );
|
||||||
$response->set_status( 201 ); // 201 Created
|
$response->set_status( 201 ); // 201 Created
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
@@ -180,3 +217,27 @@ function statpress_delete_activity_api( WP_REST_Request $request ) {
|
|||||||
|
|
||||||
return new WP_REST_Response( array( 'message' => 'Activity deleted successfully.' ), 200 );
|
return new WP_REST_Response( array( 'message' => 'Activity deleted successfully.' ), 200 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API callback to parse a GPX file and return its summary data.
|
||||||
|
*
|
||||||
|
* @param WP_REST_Request $request The request object.
|
||||||
|
* @return WP_REST_Response|WP_Error A response object with summary data or an error.
|
||||||
|
*/
|
||||||
|
function statpress_parse_gpx_summary_api( WP_REST_Request $request ) {
|
||||||
|
$params = $request->get_json_params();
|
||||||
|
$gpx_url = $params['gpx_url'] ?? '';
|
||||||
|
|
||||||
|
if ( empty( $gpx_url ) ) {
|
||||||
|
return new WP_Error( 'no_url_provided', 'Nie podano adresu URL do pliku GPX.', array( 'status' => 400 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// This new function will do the heavy lifting of calculation.
|
||||||
|
$summary = statpress_calculate_gpx_summary( $gpx_url );
|
||||||
|
|
||||||
|
if ( empty( $summary ) || ! $summary['distance'] > 0 ) {
|
||||||
|
return new WP_Error( 'gpx_parse_error', 'Nie udało się przetworzyć pliku GPX. Sprawdź, czy plik jest poprawny i zawiera dane trasy.', array( 'status' => 400 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return new WP_REST_Response( $summary, 200 );
|
||||||
|
}
|
||||||
@@ -137,3 +137,161 @@ function statpress_parse_gpx_data( $gpx_url ) {
|
|||||||
'profiles' => $profiles,
|
'profiles' => $profiles,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches and calculates a full summary from a GPX file.
|
||||||
|
* This function parses the entire file to get accurate summary stats, ignoring privacy zones.
|
||||||
|
*
|
||||||
|
* @param string $gpx_url The URL of the GPX file.
|
||||||
|
* @return array An associative array with summary statistics.
|
||||||
|
*/
|
||||||
|
function statpress_calculate_gpx_summary( $gpx_url ) {
|
||||||
|
if ( empty( $gpx_url ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$response = wp_remote_get( $gpx_url, array( 'timeout' => 20 ) );
|
||||||
|
if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$gpx_content = wp_remote_retrieve_body( $response );
|
||||||
|
if ( empty( $gpx_content ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
libxml_use_internal_errors( true );
|
||||||
|
$gpx = simplexml_load_string( $gpx_content );
|
||||||
|
libxml_clear_errors();
|
||||||
|
|
||||||
|
if ( false === $gpx ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$gpx->registerXPathNamespace( 'gpx', 'http://www.topografix.com/GPX/1/1' );
|
||||||
|
$trackpoints = $gpx->xpath( '//gpx:trkpt' );
|
||||||
|
if ( empty( $trackpoints ) ) {
|
||||||
|
$trackpoints = $gpx->xpath( '//trkpt' );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( empty( $trackpoints ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$haversine = function( $lat1, $lon1, $lat2, $lon2 ) {
|
||||||
|
$earth_radius = 6371; // km
|
||||||
|
$dLat = deg2rad( $lat2 - $lat1 );
|
||||||
|
$dLon = deg2rad( $lon2 - $lon1 );
|
||||||
|
$a = sin( $dLat / 2 ) * sin( $dLat / 2 ) + cos( deg2rad( $lat1 ) ) * cos( deg2rad( $lat2 ) ) * sin( $dLon / 2 ) * sin( $dLon / 2 );
|
||||||
|
$c = 2 * atan2( sqrt( $a ), sqrt( 1 - $a ) );
|
||||||
|
return $earth_radius * $c;
|
||||||
|
};
|
||||||
|
|
||||||
|
$stats = array(
|
||||||
|
'distance' => 0,
|
||||||
|
'total_elevation_gain' => 0,
|
||||||
|
'total_elevation_loss' => 0,
|
||||||
|
'min_altitude' => null,
|
||||||
|
'max_altitude' => null,
|
||||||
|
'max_speed' => 0,
|
||||||
|
'max_heart_rate' => 0,
|
||||||
|
'max_cadence' => 0,
|
||||||
|
'hr_sum' => 0,
|
||||||
|
'hr_count' => 0,
|
||||||
|
'cad_sum' => 0,
|
||||||
|
'cad_count' => 0,
|
||||||
|
'speed_sum' => 0,
|
||||||
|
'speed_count' => 0,
|
||||||
|
'start_time' => null,
|
||||||
|
'end_time' => null,
|
||||||
|
);
|
||||||
|
|
||||||
|
$prev_point = null;
|
||||||
|
|
||||||
|
foreach ( $trackpoints as $trkpt ) {
|
||||||
|
$point = array(
|
||||||
|
'lat' => (float) $trkpt['lat'],
|
||||||
|
'lon' => (float) $trkpt['lon'],
|
||||||
|
'ele' => isset( $trkpt->ele ) ? (float) $trkpt->ele : null,
|
||||||
|
'time' => isset( $trkpt->time ) ? strtotime( (string) $trkpt->time ) : null,
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( is_null( $stats['start_time'] ) && ! is_null( $point['time'] ) ) {
|
||||||
|
$stats['start_time'] = $point['time'];
|
||||||
|
}
|
||||||
|
$stats['end_time'] = $point['time'];
|
||||||
|
|
||||||
|
if ( ! is_null( $point['ele'] ) ) {
|
||||||
|
if ( is_null( $stats['min_altitude'] ) || $point['ele'] < $stats['min_altitude'] ) {
|
||||||
|
$stats['min_altitude'] = $point['ele'];
|
||||||
|
}
|
||||||
|
if ( is_null( $stats['max_altitude'] ) || $point['ele'] > $stats['max_altitude'] ) {
|
||||||
|
$stats['max_altitude'] = $point['ele'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$extensions = $trkpt->extensions ? $trkpt->extensions->children( 'gpxtpx', true ) : null;
|
||||||
|
if ( $extensions ) {
|
||||||
|
if ( isset( $extensions->TrackPointExtension->hr ) ) {
|
||||||
|
$hr = (int) $extensions->TrackPointExtension->hr;
|
||||||
|
$stats['hr_sum'] += $hr;
|
||||||
|
$stats['hr_count']++;
|
||||||
|
if ( $hr > $stats['max_heart_rate'] ) {
|
||||||
|
$stats['max_heart_rate'] = $hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( isset( $extensions->TrackPointExtension->cad ) ) {
|
||||||
|
$cad = (int) $extensions->TrackPointExtension->cad;
|
||||||
|
$stats['cad_sum'] += $cad;
|
||||||
|
$stats['cad_count']++;
|
||||||
|
if ( $cad > $stats['max_cadence'] ) {
|
||||||
|
$stats['max_cadence'] = $cad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $prev_point ) {
|
||||||
|
$distance_delta = $haversine( $prev_point['lat'], $prev_point['lon'], $point['lat'], $point['lon'] );
|
||||||
|
$stats['distance'] += $distance_delta;
|
||||||
|
|
||||||
|
if ( ! is_null( $point['ele'] ) && ! is_null( $prev_point['ele'] ) ) {
|
||||||
|
$ele_delta = $point['ele'] - $prev_point['ele'];
|
||||||
|
if ( $ele_delta > 0 ) {
|
||||||
|
$stats['total_elevation_gain'] += $ele_delta;
|
||||||
|
} else {
|
||||||
|
$stats['total_elevation_loss'] += abs( $ele_delta );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! is_null( $point['time'] ) && ! is_null( $prev_point['time'] ) ) {
|
||||||
|
$time_delta = $point['time'] - $prev_point['time'];
|
||||||
|
if ( $time_delta > 0 ) {
|
||||||
|
$speed = ( $distance_delta * 3600 ) / $time_delta; // km/h
|
||||||
|
$stats['speed_sum'] += $speed;
|
||||||
|
$stats['speed_count']++;
|
||||||
|
if ( $speed > $stats['max_speed'] ) {
|
||||||
|
$stats['max_speed'] = $speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$prev_point = $point;
|
||||||
|
}
|
||||||
|
|
||||||
|
$duration_sec = ( ! is_null( $stats['end_time'] ) && ! is_null( $stats['start_time'] ) ) ? ( $stats['end_time'] - $stats['start_time'] ) : 0;
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'distance' => round( $stats['distance'], 2 ),
|
||||||
|
'duration' => gmdate( 'H:i:s', $duration_sec ),
|
||||||
|
'avg_speed' => ( $stats['distance'] > 0 && $duration_sec > 0 ) ? round( ( $stats['distance'] / ( $duration_sec / 3600 ) ), 1 ) : 0,
|
||||||
|
'max_speed' => round( $stats['max_speed'], 1 ),
|
||||||
|
'total_elevation_gain' => round( $stats['total_elevation_gain'] ),
|
||||||
|
'total_elevation_loss' => round( $stats['total_elevation_loss'] ),
|
||||||
|
'min_altitude' => ! is_null( $stats['min_altitude'] ) ? round( $stats['min_altitude'] ) : null,
|
||||||
|
'max_altitude' => ! is_null( $stats['max_altitude'] ) ? round( $stats['max_altitude'] ) : null,
|
||||||
|
'avg_heart_rate' => $stats['hr_count'] > 0 ? round( $stats['hr_sum'] / $stats['hr_count'] ) : 0,
|
||||||
|
'max_heart_rate' => $stats['max_heart_rate'],
|
||||||
|
'avg_cadence' => $stats['cad_count'] > 0 ? round( $stats['cad_sum'] / $stats['cad_count'] ) : 0,
|
||||||
|
'max_cadence' => $stats['max_cadence'],
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -6,12 +6,12 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
/**
|
/**
|
||||||
* Registers styles for frontend and enqueues them when shortcodes are used.
|
* Registers styles for frontend and enqueues them when shortcodes are used.
|
||||||
*/
|
*/
|
||||||
function mystat_enqueue_frontend_assets() {
|
function statpress_enqueue_frontend_assets() {
|
||||||
// Register the stylesheet. It will be enqueued by the shortcodes when needed.
|
// Register the stylesheet. It will be enqueued by the shortcodes when needed.
|
||||||
$plugin_version = '1.0';
|
$plugin_version = '1.0';
|
||||||
wp_register_style(
|
wp_register_style(
|
||||||
'mystat-frontend-styles',
|
'statpress-frontend-styles',
|
||||||
MYSTAT_PLUGIN_URL . 'assets/css/frontend.css',
|
STATPRESS_PLUGIN_URL . 'assets/css/frontend.css',
|
||||||
array(),
|
array(),
|
||||||
$plugin_version
|
$plugin_version
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rejestruje shortcode [moje_statystyki].
|
* Rejestruje shortcode [statpress_summary] and [statpress_activity].
|
||||||
*/
|
*/
|
||||||
function mystat_register_shortcode() {
|
function statpress_register_shortcode() {
|
||||||
add_shortcode( 'moje_statystyki', 'mystat_shortcode_handler' );
|
add_shortcode( 'statpress_summary', 'statpress_shortcode_handler' );
|
||||||
add_shortcode( 'moje_statystyki_wpis', 'mystat_single_activity_shortcode_handler' );
|
add_shortcode( 'statpress_activity', 'statpress_single_activity_shortcode_handler' );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,8 +16,8 @@ function mystat_register_shortcode() {
|
|||||||
* @param array $atts Atrybuty shortcode'u (np. year, month).
|
* @param array $atts Atrybuty shortcode'u (np. year, month).
|
||||||
* @return string HTML do wyświetlenia.
|
* @return string HTML do wyświetlenia.
|
||||||
*/
|
*/
|
||||||
function mystat_shortcode_handler( $atts ) {
|
function statpress_shortcode_handler( $atts ) {
|
||||||
wp_enqueue_style( 'mystat-frontend-styles' );
|
wp_enqueue_style( 'statpress-frontend-styles' );
|
||||||
|
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
@@ -28,20 +28,20 @@ function mystat_shortcode_handler( $atts ) {
|
|||||||
'month' => current_time( 'n' ),
|
'month' => current_time( 'n' ),
|
||||||
),
|
),
|
||||||
$atts,
|
$atts,
|
||||||
'moje_statystyki'
|
'statpress_summary'
|
||||||
);
|
);
|
||||||
|
|
||||||
$year = intval( $atts['year'] );
|
$year = intval( $atts['year'] );
|
||||||
$month = intval( $atts['month'] );
|
$month = intval( $atts['month'] );
|
||||||
|
|
||||||
// Pobieranie danych z bazy
|
// Pobieranie danych z bazy
|
||||||
$table_activities = $wpdb->prefix . 'mystat_activities';
|
$table_activities = $wpdb->prefix . 'statpress_activities';
|
||||||
$sql = $wpdb->prepare(
|
$sql = $wpdb->prepare(
|
||||||
"
|
"
|
||||||
SELECT a.*, c.name as category_name, eq.name as equipment_name
|
SELECT a.*, c.name as category_name, eq.name as equipment_name
|
||||||
FROM $table_activities a
|
FROM $table_activities a
|
||||||
LEFT JOIN {$wpdb->prefix}mystat_categories c ON a.category_id = c.id
|
LEFT JOIN {$wpdb->prefix}statpress_categories c ON a.category_id = c.id
|
||||||
LEFT JOIN {$wpdb->prefix}mystat_equipment eq ON a.equipment_id = eq.id
|
LEFT JOIN {$wpdb->prefix}statpress_equipment eq ON a.equipment_id = eq.id
|
||||||
WHERE YEAR(a.date) = %d AND MONTH(a.date) = %d
|
WHERE YEAR(a.date) = %d AND MONTH(a.date) = %d
|
||||||
ORDER BY a.date ASC
|
ORDER BY a.date ASC
|
||||||
",
|
",
|
||||||
@@ -68,10 +68,10 @@ function mystat_shortcode_handler( $atts ) {
|
|||||||
// Rozpoczęcie buforowania wyjścia
|
// Rozpoczęcie buforowania wyjścia
|
||||||
ob_start();
|
ob_start();
|
||||||
?>
|
?>
|
||||||
<div class="mystats-shortcode-container">
|
<div class="statpress-shortcode-container">
|
||||||
|
|
||||||
<h3>Podsumowanie miesiąca</h3>
|
<h3>Podsumowanie miesiąca</h3>
|
||||||
<table class="mystats-summary-table">
|
<table class="statpress-summary-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Całkowity dystans</th>
|
<th>Całkowity dystans</th>
|
||||||
@@ -87,7 +87,7 @@ function mystat_shortcode_handler( $atts ) {
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<h3>Lista aktywności</h3>
|
<h3>Lista aktywności</h3>
|
||||||
<table class="mystats-activity-table">
|
<table class="statpress-activity-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Data</th>
|
<th>Data</th>
|
||||||
@@ -111,9 +111,9 @@ function mystat_shortcode_handler( $atts ) {
|
|||||||
<td><?php echo esc_html( $row->equipment_name ); ?></td>
|
<td><?php echo esc_html( $row->equipment_name ); ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php if ( $row->avg_speed || $row->avg_heart_rate || $row->avg_cadence ) : ?>
|
<?php if ( $row->avg_speed || $row->avg_heart_rate || $row->avg_cadence ) : ?>
|
||||||
<tr class="mystats-activity-details-row">
|
<tr class="statpress-activity-details-row">
|
||||||
<td colspan="6" class="mystats-activity-details-cell">
|
<td colspan="6" class="statpress-activity-details-cell">
|
||||||
<table class="mystats-nested-details-table">
|
<table class="statpress-nested-details-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<?php if ( $row->avg_speed ) { echo '<th>Śr. prędkość</th>'; } ?>
|
<?php if ( $row->avg_speed ) { echo '<th>Śr. prędkość</th>'; } ?>
|
||||||
@@ -146,8 +146,8 @@ function mystat_shortcode_handler( $atts ) {
|
|||||||
return ob_get_clean();
|
return ob_get_clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
function mystat_single_activity_shortcode_handler( $atts ) {
|
function statpress_single_activity_shortcode_handler( $atts ) {
|
||||||
wp_enqueue_style( 'mystat-frontend-styles' );
|
wp_enqueue_style( 'statpress-frontend-styles' );
|
||||||
|
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ function mystat_single_activity_shortcode_handler( $atts ) {
|
|||||||
'id' => 0,
|
'id' => 0,
|
||||||
),
|
),
|
||||||
$atts,
|
$atts,
|
||||||
'moje_statystyki_wpis'
|
'statpress_activity'
|
||||||
);
|
);
|
||||||
|
|
||||||
$activity_id = intval( $atts['id'] );
|
$activity_id = intval( $atts['id'] );
|
||||||
@@ -166,14 +166,14 @@ function mystat_single_activity_shortcode_handler( $atts ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pobieranie danych z bazy
|
// Pobieranie danych z bazy
|
||||||
$table_activities = $wpdb->prefix . 'mystat_activities';
|
$table_activities = $wpdb->prefix . 'statpress_activities';
|
||||||
$sql = $wpdb->prepare(
|
$sql = $wpdb->prepare(
|
||||||
"
|
"
|
||||||
SELECT a.*, c.name as category_name, c.color as category_color, et.name as event_type_name, eq.name as equipment_name
|
SELECT a.*, c.name as category_name, c.color as category_color, et.name as event_type_name, eq.name as equipment_name
|
||||||
FROM $table_activities a
|
FROM $table_activities a
|
||||||
LEFT JOIN {$wpdb->prefix}mystat_categories c ON a.category_id = c.id
|
LEFT JOIN {$wpdb->prefix}statpress_categories c ON a.category_id = c.id
|
||||||
LEFT JOIN {$wpdb->prefix}mystat_event_types et ON a.event_type_id = et.id
|
LEFT JOIN {$wpdb->prefix}statpress_event_types et ON a.event_type_id = et.id
|
||||||
LEFT JOIN {$wpdb->prefix}mystat_equipment eq ON a.equipment_id = eq.id
|
LEFT JOIN {$wpdb->prefix}statpress_equipment eq ON a.equipment_id = eq.id
|
||||||
WHERE a.id = %d
|
WHERE a.id = %d
|
||||||
",
|
",
|
||||||
$activity_id
|
$activity_id
|
||||||
@@ -201,11 +201,11 @@ function mystat_single_activity_shortcode_handler( $atts ) {
|
|||||||
$gpx_data = array();
|
$gpx_data = array();
|
||||||
$has_gpx_data = false;
|
$has_gpx_data = false;
|
||||||
if ( ! empty( $activity->gpx_url ) ) {
|
if ( ! empty( $activity->gpx_url ) ) {
|
||||||
$gpx_data = mystat_parse_gpx_data( $activity->gpx_url );
|
$gpx_data = statpress_parse_gpx_data( $activity->gpx_url );
|
||||||
$has_gpx_data = ! empty( $gpx_data['points'] );
|
$has_gpx_data = ! empty( $gpx_data['points'] );
|
||||||
}
|
}
|
||||||
|
|
||||||
$unique_id = 'mystat-activity-' . esc_attr( $activity->id );
|
$unique_id = 'statpress-activity-' . esc_attr( $activity->id );
|
||||||
|
|
||||||
if ( $has_gpx_data ) {
|
if ( $has_gpx_data ) {
|
||||||
wp_enqueue_style( 'leaflet-css', 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css' );
|
wp_enqueue_style( 'leaflet-css', 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css' );
|
||||||
@@ -227,8 +227,8 @@ function mystat_single_activity_shortcode_handler( $atts ) {
|
|||||||
|
|
||||||
$has_time_data = ! empty( array_filter( $gpx_data['profiles']['time'], fn( $t ) => ! is_null( $t ) ) );
|
$has_time_data = ! empty( array_filter( $gpx_data['profiles']['time'], fn( $t ) => ! is_null( $t ) ) );
|
||||||
|
|
||||||
wp_register_script( 'mystat-shortcode-loader-' . $activity->id, false );
|
wp_register_script( 'statpress-shortcode-loader-' . $activity->id, false );
|
||||||
wp_enqueue_script( 'mystat-shortcode-loader-' . $activity->id );
|
wp_enqueue_script( 'statpress-shortcode-loader-' . $activity->id );
|
||||||
|
|
||||||
$js_script = '
|
$js_script = '
|
||||||
(function() {
|
(function() {
|
||||||
@@ -268,7 +268,7 @@ function mystat_single_activity_shortcode_handler( $atts ) {
|
|||||||
|
|
||||||
function renderChart() {
|
function renderChart() {
|
||||||
if (activeChart) activeChart.destroy();
|
if (activeChart) activeChart.destroy();
|
||||||
const activeTab = containerEl.querySelector(".mystat-chart-tab.active");
|
const activeTab = containerEl.querySelector(".statpress-chart-tab.active");
|
||||||
if (!activeTab) return;
|
if (!activeTab) return;
|
||||||
const chartType = activeTab.dataset.type;
|
const chartType = activeTab.dataset.type;
|
||||||
const xAxisRadio = containerEl.querySelector(\'input[name="xaxis-\' + uniqueId + \'"]:checked\');
|
const xAxisRadio = containerEl.querySelector(\'input[name="xaxis-\' + uniqueId + \'"]:checked\');
|
||||||
@@ -309,27 +309,27 @@ function mystat_single_activity_shortcode_handler( $atts ) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
containerEl.querySelectorAll(".mystat-chart-tab").forEach(t => t.addEventListener("click", e => {
|
containerEl.querySelectorAll(".statpress-chart-tab").forEach(t => t.addEventListener("click", e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
containerEl.querySelector(".mystat-chart-tab.active").classList.remove("active");
|
containerEl.querySelector(".statpress-chart-tab.active").classList.remove("active");
|
||||||
e.currentTarget.classList.add("active");
|
e.currentTarget.classList.add("active");
|
||||||
renderChart();
|
renderChart();
|
||||||
}));
|
}));
|
||||||
containerEl.querySelectorAll(\'input[name="xaxis-\' + uniqueId + \'"]\').forEach(r => r.addEventListener("change", renderChart));
|
containerEl.querySelectorAll(\'input[name="xaxis-\' + uniqueId + \'"]\').forEach(r => r.addEventListener("change", renderChart));
|
||||||
if (containerEl.querySelector(".mystat-chart-tab")) renderChart();
|
if (containerEl.querySelector(".statpress-chart-tab")) renderChart();
|
||||||
});
|
});
|
||||||
})();';
|
})();';
|
||||||
wp_add_inline_script( 'mystat-shortcode-loader-' . $activity->id, $js_script );
|
wp_add_inline_script( 'statpress-shortcode-loader-' . $activity->id, $js_script );
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<div class="mystat-single-activity-shortcode" id="<?php echo esc_attr( $unique_id ); ?>">
|
<div class="statpress-single-activity-shortcode" id="<?php echo esc_attr( $unique_id ); ?>">
|
||||||
<h4><?php echo esc_html( $activity->title ); ?></h4>
|
<h4><?php echo esc_html( $activity->title ); ?></h4>
|
||||||
<p><em><?php echo esc_html( date_i18n( 'j F Y', strtotime( $activity->date ) ) ); ?></em></p>
|
<p><em><?php echo esc_html( date_i18n( 'j F Y', strtotime( $activity->date ) ) ); ?></em></p>
|
||||||
|
|
||||||
<div class="mystat-single-columns-container">
|
<div class="statpress-single-columns-container">
|
||||||
<div class="mystat-single-col">
|
<div class="statpress-single-col">
|
||||||
<table class="mystat-single-summary-table">
|
<table class="statpress-single-summary-table">
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php $render_row( 'Dystans', number_format( $activity->distance, 2, ',', ' ' ), 'km' ); ?>
|
<?php $render_row( 'Dystans', number_format( $activity->distance, 2, ',', ' ' ), 'km' ); ?>
|
||||||
<?php $render_row( 'Czas trwania', $activity->duration ); ?>
|
<?php $render_row( 'Czas trwania', $activity->duration ); ?>
|
||||||
@@ -338,8 +338,8 @@ function mystat_single_activity_shortcode_handler( $atts ) {
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="mystat-single-col">
|
<div class="statpress-single-col">
|
||||||
<table class="mystat-single-summary-table">
|
<table class="statpress-single-summary-table">
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php $render_row( 'Kategoria', $activity->category_name ); ?>
|
<?php $render_row( 'Kategoria', $activity->category_name ); ?>
|
||||||
<?php $render_row( 'Sprzęt', $activity->equipment_name ); ?>
|
<?php $render_row( 'Sprzęt', $activity->equipment_name ); ?>
|
||||||
@@ -352,17 +352,17 @@ function mystat_single_activity_shortcode_handler( $atts ) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php if ( $has_gpx_data ) : ?>
|
<?php if ( $has_gpx_data ) : ?>
|
||||||
<div id="<?php echo esc_attr( $map_id ); ?>" class="mystat-single-map" style="height: 350px; width: 100%; margin-top: 15px; border-radius: 5px; margin-bottom: 20px;"></div>
|
<div id="<?php echo esc_attr( $map_id ); ?>" class="statpress-single-map" style="height: 350px; width: 100%; margin-top: 15px; border-radius: 5px; margin-bottom: 20px;"></div>
|
||||||
|
|
||||||
<?php if ( ! empty( $available_profiles ) ) : ?>
|
<?php if ( ! empty( $available_profiles ) ) : ?>
|
||||||
<div class="mystat-charts-container">
|
<div class="statpress-charts-container">
|
||||||
<div class="mystat-chart-controls" style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; margin-bottom: 15px; border-bottom: 1px solid #eee; padding-bottom: 10px; gap: 10px;">
|
<div class="statpress-chart-controls" style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; margin-bottom: 15px; border-bottom: 1px solid #eee; padding-bottom: 10px; gap: 10px;">
|
||||||
<div class="mystat-chart-tabs" style="display: flex; flex-wrap: wrap; gap: 5px;">
|
<div class="statpress-chart-tabs" style="display: flex; flex-wrap: wrap; gap: 5px;">
|
||||||
<?php
|
<?php
|
||||||
$is_first = true;
|
$is_first = true;
|
||||||
foreach ( $available_profiles as $key => $label ) :
|
foreach ( $available_profiles as $key => $label ) :
|
||||||
?>
|
?>
|
||||||
<button data-type="<?php echo esc_attr( $key ); ?>" class="mystat-chart-tab <?php
|
<button data-type="<?php echo esc_attr( $key ); ?>" class="statpress-chart-tab <?php
|
||||||
if ( $is_first ) {
|
if ( $is_first ) {
|
||||||
echo 'active';
|
echo 'active';
|
||||||
$is_first = false; }
|
$is_first = false; }
|
||||||
@@ -371,7 +371,7 @@ function mystat_single_activity_shortcode_handler( $atts ) {
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</div>
|
</div>
|
||||||
<?php if ( $has_time_data ) : ?>
|
<?php if ( $has_time_data ) : ?>
|
||||||
<div class="mystat-xaxis-switcher" style="padding-top: 5px; font-size: 0.9em; white-space: nowrap;">
|
<div class="statpress-xaxis-switcher" style="padding-top: 5px; font-size: 0.9em; white-space: nowrap;">
|
||||||
<strong>Oś X:</strong>
|
<strong>Oś X:</strong>
|
||||||
<label><input type="radio" name="xaxis-<?php echo esc_attr( $unique_id ); ?>" value="distance" checked> Dystans</label>
|
<label><input type="radio" name="xaxis-<?php echo esc_attr( $unique_id ); ?>" value="distance" checked> Dystans</label>
|
||||||
|
|
||||||
@@ -381,7 +381,7 @@ function mystat_single_activity_shortcode_handler( $atts ) {
|
|||||||
<input type="hidden" name="xaxis-<?php echo esc_attr( $unique_id ); ?>" value="distance" checked>
|
<input type="hidden" name="xaxis-<?php echo esc_attr( $unique_id ); ?>" value="distance" checked>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="mystat-chart-wrapper" style="position: relative; height:250px; width:100%;">
|
<div class="statpress-chart-wrapper" style="position: relative; height:250px; width:100%;">
|
||||||
<canvas id="<?php echo esc_attr( $chart_id ); ?>"></canvas>
|
<canvas id="<?php echo esc_attr( $chart_id ); ?>"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-yearly-summary.ph
|
|||||||
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-infographic.php';
|
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-infographic.php';
|
||||||
require_once STATPRESS_PLUGIN_DIR . 'includes/admin/pages/page-import-csv.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_menu', 'statpress_add_admin_menu' );
|
||||||
add_action( 'admin_init', 'statpress_admin_init_setup' );
|
add_action( 'admin_init', 'statpress_admin_init_setup' );
|
||||||
add_action( 'admin_enqueue_scripts', 'statpress_enqueue_admin_styles' );
|
add_action( 'admin_enqueue_scripts', 'statpress_enqueue_admin_styles' );
|
||||||
@@ -53,3 +56,112 @@ require_once STATPRESS_PLUGIN_DIR . 'includes/frontend/shortcodes.php';
|
|||||||
|
|
||||||
add_action( 'wp_enqueue_scripts', 'statpress_enqueue_frontend_assets' );
|
add_action( 'wp_enqueue_scripts', 'statpress_enqueue_frontend_assets' );
|
||||||
add_action( 'init', 'statpress_register_shortcode' );
|
add_action( 'init', 'statpress_register_shortcode' );
|
||||||
|
|
||||||
|
// --- 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user