Przygotwanie do REST
This commit is contained in:
@@ -57,76 +57,17 @@ function mystat_handle_activity_form_submission() {
|
||||
return;
|
||||
}
|
||||
|
||||
$table_activities = $wpdb->prefix . 'mystat_activities';
|
||||
|
||||
// Przygotowanie danych (zamiana przecinka na kropkę w dystansie)
|
||||
$distance = isset( $_POST['distance'] ) ? floatval( str_replace( ',', '.', $_POST['distance'] ) ) : 0;
|
||||
|
||||
// Funkcja pomocnicza do zamiany pustych wartości na NULL, aby poprawnie zapisać je w bazie
|
||||
$null_if_empty = function( $value ) {
|
||||
return $value !== '' ? $value : null;
|
||||
};
|
||||
|
||||
$data = array(
|
||||
'category_id' => intval( $_POST['category_id'] ),
|
||||
'date' => sanitize_text_field( $_POST['date'] ),
|
||||
'title' => sanitize_text_field( $_POST['title'] ),
|
||||
'distance' => $distance,
|
||||
'duration' => sanitize_text_field( $_POST['duration'] ),
|
||||
'calories' => intval( $_POST['calories'] ),
|
||||
'comment' => sanitize_textarea_field( $_POST['comment'] ),
|
||||
'strava_url' => $null_if_empty( esc_url_raw( $_POST['strava_url'] ) ),
|
||||
'avg_heart_rate' => $null_if_empty( intval( $_POST['avg_heart_rate'] ) ),
|
||||
'max_heart_rate' => $null_if_empty( intval( $_POST['max_heart_rate'] ) ),
|
||||
'avg_speed' => $null_if_empty( floatval( str_replace( ',', '.', $_POST['avg_speed'] ) ) ),
|
||||
'max_speed' => $null_if_empty( floatval( str_replace( ',', '.', $_POST['max_speed'] ) ) ),
|
||||
'avg_cadence' => $null_if_empty( intval( $_POST['avg_cadence'] ) ),
|
||||
'max_cadence' => $null_if_empty( intval( $_POST['max_cadence'] ) ),
|
||||
'total_elevation_gain' => $null_if_empty( intval( $_POST['total_elevation_gain'] ) ),
|
||||
'total_elevation_loss' => $null_if_empty( intval( $_POST['total_elevation_loss'] ) ),
|
||||
'min_altitude' => $null_if_empty( intval( $_POST['min_altitude'] ) ),
|
||||
'max_altitude' => $null_if_empty( intval( $_POST['max_altitude'] ) ),
|
||||
'equipment_id' => $null_if_empty( intval( $_POST['equipment_id'] ) ),
|
||||
'gpx_url' => $null_if_empty( esc_url_raw( $_POST['gpx_url'] ) ),
|
||||
'event_type_id' => $null_if_empty( intval( $_POST['event_type_id'] ) ),
|
||||
);
|
||||
|
||||
// Format danych dla $wpdb->insert
|
||||
$format = array(
|
||||
'%d',
|
||||
'%s',
|
||||
'%s',
|
||||
'%f',
|
||||
'%s',
|
||||
'%d',
|
||||
'%s', // Pola podstawowe
|
||||
'%s',
|
||||
'%d',
|
||||
'%d',
|
||||
'%f',
|
||||
'%f',
|
||||
'%d',
|
||||
'%d', // Tętno, prędkość, kadencja
|
||||
'%d',
|
||||
'%d',
|
||||
'%d',
|
||||
'%d',
|
||||
'%d',
|
||||
'%s',
|
||||
'%d', // Wysokość, sprzęt, linki, typ wydarzenia
|
||||
);
|
||||
// Use the refactored function to save data.
|
||||
// We can pass $_POST directly as the function will sanitize it.
|
||||
$result = mystat_save_activity_data( $_POST, $activity_id );
|
||||
|
||||
if ( $activity_id > 0 ) {
|
||||
// UPDATE
|
||||
$result = $wpdb->update( $table_activities, $data, array( 'id' => $activity_id ), $format, array( '%d' ) );
|
||||
$message = 'Trening zaktualizowany pomyślnie!';
|
||||
} else {
|
||||
// INSERT
|
||||
$result = $wpdb->insert( $table_activities, $data, $format );
|
||||
$message = 'Trening dodany pomyślnie!';
|
||||
}
|
||||
|
||||
if ( false !== $result ) {
|
||||
if ( $result ) {
|
||||
echo '<div class="notice notice-success is-dismissible"><p>' . esc_html( $message ) . '</p></div>';
|
||||
} else {
|
||||
echo '<div class="notice notice-error is-dismissible"><p>Wystąpił błąd podczas zapisu do bazy.</p></div>';
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
/**
|
||||
* REST API routes for the plugin.
|
||||
*
|
||||
* @package WordPress Activity Stats
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Register REST API routes.
|
||||
*/
|
||||
function mystat_register_rest_routes() {
|
||||
$namespace = 'mystat/v1';
|
||||
|
||||
// Route for getting a collection of activities
|
||||
register_rest_route(
|
||||
$namespace,
|
||||
'/activities',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => 'mystat_get_activities_api',
|
||||
'permission_callback' => 'mystat_api_permissions_check',
|
||||
'args' => array(
|
||||
'page' => array(
|
||||
'validate_callback' => 'is_numeric',
|
||||
),
|
||||
'per_page' => array(
|
||||
'validate_callback' => 'is_numeric',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
'callback' => 'mystat_create_activity_api',
|
||||
'permission_callback' => 'mystat_api_permissions_check',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
// Route for a single activity
|
||||
register_rest_route(
|
||||
$namespace,
|
||||
'/activities/(?P<id>[\d]+)',
|
||||
array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => 'mystat_get_activity_api',
|
||||
'permission_callback' => 'mystat_api_permissions_check',
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::EDITABLE,
|
||||
'callback' => 'mystat_update_activity_api',
|
||||
'permission_callback' => 'mystat_api_permissions_check',
|
||||
),
|
||||
array(
|
||||
'methods' => WP_REST_Server::DELETABLE,
|
||||
'callback' => 'mystat_delete_activity_api',
|
||||
'permission_callback' => 'mystat_api_permissions_check',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Permission check for API endpoints.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function mystat_api_permissions_check() {
|
||||
return current_user_can( 'manage_options' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a collection of activities.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
function mystat_get_activities_api( WP_REST_Request $request ) {
|
||||
global $wpdb;
|
||||
$table_activities = $wpdb->prefix . 'mystat_activities';
|
||||
|
||||
$per_page = $request->get_param( 'per_page' ) ? (int) $request->get_param( 'per_page' ) : 20;
|
||||
$page = $request->get_param( 'page' ) ? (int) $request->get_param( 'page' ) : 1;
|
||||
$offset = ( $page - 1 ) * $per_page;
|
||||
|
||||
$sql = $wpdb->prepare(
|
||||
"SELECT a.*, c.name as category_name, et.name as event_type_name, eq.name as equipment_name
|
||||
FROM $table_activities a
|
||||
LEFT JOIN {$wpdb->prefix}mystat_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}mystat_equipment eq ON a.equipment_id = eq.id
|
||||
ORDER BY a.date DESC, a.id DESC
|
||||
LIMIT %d OFFSET %d",
|
||||
$per_page,
|
||||
$offset
|
||||
);
|
||||
|
||||
$results = $wpdb->get_results( $sql );
|
||||
|
||||
return new WP_REST_Response( $results, 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single activity.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
function mystat_get_activity_api( WP_REST_Request $request ) {
|
||||
global $wpdb;
|
||||
$id = (int) $request['id'];
|
||||
|
||||
$sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}mystat_activities WHERE id = %d", $id );
|
||||
$activity = $wpdb->get_row( $sql );
|
||||
|
||||
if ( ! $activity ) {
|
||||
return new WP_Error( 'not_found', 'Activity not found', array( 'status' => 404 ) );
|
||||
}
|
||||
|
||||
return new WP_REST_Response( $activity, 200 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new activity.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
function mystat_create_activity_api( WP_REST_Request $request ) {
|
||||
$params = $request->get_json_params();
|
||||
$activity_id = mystat_save_activity_data( $params );
|
||||
|
||||
if ( ! $activity_id ) {
|
||||
return new WP_Error( 'cant-create', 'Error creating activity', array( 'status' => 500 ) );
|
||||
}
|
||||
|
||||
$response = mystat_get_activity_api( new WP_REST_Request( 'GET', "/mystat/v1/activities/{$activity_id}" ) );
|
||||
$response->set_status( 201 ); // 201 Created
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an existing activity.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
function mystat_update_activity_api( WP_REST_Request $request ) {
|
||||
$id = (int) $request['id'];
|
||||
$params = $request->get_json_params();
|
||||
$activity_id = mystat_save_activity_data( $params, $id );
|
||||
|
||||
if ( ! $activity_id ) {
|
||||
return new WP_Error( 'cant-update', 'Error updating activity', array( 'status' => 500 ) );
|
||||
}
|
||||
|
||||
return mystat_get_activity_api( $request );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an activity.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_REST_Response|WP_Error
|
||||
*/
|
||||
function mystat_delete_activity_api( WP_REST_Request $request ) {
|
||||
global $wpdb;
|
||||
$id = (int) $request['id'];
|
||||
|
||||
$result = $wpdb->delete( $wpdb->prefix . 'mystat_activities', array( 'id' => $id ), array( '%d' ) );
|
||||
|
||||
if ( ! $result ) {
|
||||
return new WP_Error( 'cant-delete', 'Error deleting activity', array( 'status' => 500 ) );
|
||||
}
|
||||
|
||||
return new WP_REST_Response( array( 'message' => 'Activity deleted successfully.' ), 200 );
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* CRUD functions for Activities.
|
||||
*
|
||||
* @package WordPress Activity Stats
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves or updates an activity in the database.
|
||||
*
|
||||
* @param array $data Associative array of data to save.
|
||||
* @param int $activity_id The ID of the activity to update. 0 for new activity.
|
||||
* @return int|false The ID of the saved/updated activity, or false on failure.
|
||||
*/
|
||||
function mystat_save_activity_data( array $data, int $activity_id = 0 ) {
|
||||
global $wpdb;
|
||||
|
||||
$table_activities = $wpdb->prefix . 'mystat_activities';
|
||||
|
||||
// Helper to convert empty strings to NULL for the database.
|
||||
$null_if_empty = function( $value ) {
|
||||
// Also check for 0 as we don't want to nullify it for numeric fields.
|
||||
return ( '' !== $value && ! is_null( $value ) ) ? $value : null;
|
||||
};
|
||||
|
||||
// Sanitize and prepare data.
|
||||
$prepared_data = array(
|
||||
'category_id' => isset( $data['category_id'] ) ? intval( $data['category_id'] ) : null,
|
||||
'date' => isset( $data['date'] ) ? sanitize_text_field( $data['date'] ) : current_time( 'Y-m-d' ),
|
||||
'title' => isset( $data['title'] ) ? sanitize_text_field( $data['title'] ) : '',
|
||||
'distance' => isset( $data['distance'] ) ? floatval( str_replace( ',', '.', $data['distance'] ) ) : 0,
|
||||
'duration' => isset( $data['duration'] ) ? sanitize_text_field( $data['duration'] ) : '00:00:00',
|
||||
'calories' => isset( $data['calories'] ) ? intval( $data['calories'] ) : null,
|
||||
'comment' => isset( $data['comment'] ) ? sanitize_textarea_field( $data['comment'] ) : null,
|
||||
'strava_url' => isset( $data['strava_url'] ) ? $null_if_empty( esc_url_raw( $data['strava_url'] ) ) : null,
|
||||
'avg_heart_rate' => isset( $data['avg_heart_rate'] ) ? $null_if_empty( intval( $data['avg_heart_rate'] ) ) : null,
|
||||
'max_heart_rate' => isset( $data['max_heart_rate'] ) ? $null_if_empty( intval( $data['max_heart_rate'] ) ) : null,
|
||||
'avg_speed' => isset( $data['avg_speed'] ) ? $null_if_empty( floatval( str_replace( ',', '.', $data['avg_speed'] ) ) ) : null,
|
||||
'max_speed' => isset( $data['max_speed'] ) ? $null_if_empty( floatval( str_replace( ',', '.', $data['max_speed'] ) ) ) : null,
|
||||
'avg_cadence' => isset( $data['avg_cadence'] ) ? $null_if_empty( intval( $data['avg_cadence'] ) ) : null,
|
||||
'max_cadence' => isset( $data['max_cadence'] ) ? $null_if_empty( intval( $data['max_cadence'] ) ) : null,
|
||||
'total_elevation_gain' => isset( $data['total_elevation_gain'] ) ? $null_if_empty( intval( $data['total_elevation_gain'] ) ) : null,
|
||||
'total_elevation_loss' => isset( $data['total_elevation_loss'] ) ? $null_if_empty( intval( $data['total_elevation_loss'] ) ) : null,
|
||||
'min_altitude' => isset( $data['min_altitude'] ) ? $null_if_empty( intval( $data['min_altitude'] ) ) : null,
|
||||
'max_altitude' => isset( $data['max_altitude'] ) ? $null_if_empty( intval( $data['max_altitude'] ) ) : null,
|
||||
'equipment_id' => isset( $data['equipment_id'] ) ? $null_if_empty( intval( $data['equipment_id'] ) ) : null,
|
||||
'gpx_url' => isset( $data['gpx_url'] ) ? $null_if_empty( esc_url_raw( $data['gpx_url'] ) ) : null,
|
||||
'event_type_id' => isset( $data['event_type_id'] ) ? $null_if_empty( intval( $data['event_type_id'] ) ) : null,
|
||||
);
|
||||
|
||||
// Data formats for $wpdb.
|
||||
$format = array(
|
||||
'%d', // category_id
|
||||
'%s', // date
|
||||
'%s', // title
|
||||
'%f', // distance
|
||||
'%s', // duration
|
||||
'%d', // calories
|
||||
'%s', // comment
|
||||
'%s', // strava_url
|
||||
'%d', // avg_heart_rate
|
||||
'%d', // max_heart_rate
|
||||
'%f', // avg_speed
|
||||
'%f', // max_speed
|
||||
'%d', // avg_cadence
|
||||
'%d', // max_cadence
|
||||
'%d', // total_elevation_gain
|
||||
'%d', // total_elevation_loss
|
||||
'%d', // min_altitude
|
||||
'%d', // max_altitude
|
||||
'%d', // equipment_id
|
||||
'%s', // gpx_url
|
||||
'%d', // event_type_id
|
||||
);
|
||||
|
||||
if ( $activity_id > 0 ) {
|
||||
// UPDATE
|
||||
$result = $wpdb->update( $table_activities, $prepared_data, array( 'id' => $activity_id ), $format, array( '%d' ) );
|
||||
if ( false !== $result ) {
|
||||
return $activity_id;
|
||||
}
|
||||
} else {
|
||||
// INSERT
|
||||
$result = $wpdb->insert( $table_activities, $prepared_data, $format );
|
||||
if ( $result ) {
|
||||
return $wpdb->insert_id;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -17,6 +17,7 @@ define( 'MYSTAT_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
||||
// --- 1. PLIKI RDZENNE I AKTYWACJA ---
|
||||
require_once MYSTAT_PLUGIN_DIR . 'includes/activation.php';
|
||||
require_once MYSTAT_PLUGIN_DIR . 'includes/core/gpx-parser.php';
|
||||
require_once MYSTAT_PLUGIN_DIR . 'includes/core/crud-activity.php';
|
||||
require_once MYSTAT_PLUGIN_DIR . 'includes/core/gpx-upload.php';
|
||||
|
||||
register_activation_hook( __FILE__, 'mystat_activate' );
|
||||
@@ -42,6 +43,11 @@ add_action( 'admin_menu', 'mystat_add_admin_menu' );
|
||||
add_action( 'admin_init', 'mystat_admin_init_setup' );
|
||||
add_action( 'admin_enqueue_scripts', 'mystat_enqueue_admin_styles' );
|
||||
|
||||
// --- 3. REST API ---
|
||||
require_once MYSTAT_PLUGIN_DIR . 'includes/api/routes.php';
|
||||
add_action( 'rest_api_init', 'mystat_register_rest_routes' );
|
||||
|
||||
|
||||
// --- 3. SHORTCODE DO WYŚWIETLANIA NA FRONCIE ---
|
||||
require_once MYSTAT_PLUGIN_DIR . 'includes/frontend/assets.php';
|
||||
require_once MYSTAT_PLUGIN_DIR . 'includes/frontend/shortcodes.php';
|
||||
|
||||
Reference in New Issue
Block a user