shop-old/core/cart_session_manager.class.php
2026-04-20 01:03:43 +02:00

246 lines
8.1 KiB
PHP

<?php
/**
* Cart Session Manager - PayPal v1 Session Fix
*
* Eliminates session dependency during PayPal redirects by storing
* cart data in database with PayPal token as key.
*
* Compatible with existing Legacy System and future PayPal v2 integration.
*
* @author PFC Claude
* @version 1.0
* @date 2025
*/
class CartSessionManager {
private $db;
private $base_object;
private $log_file;
public function __construct($base_object) {
$this->base_object = $base_object;
$this->db = $base_object->db;
// Dedicated PayPal log file - easier than Plesk chaos!
$this->log_file = $_SERVER['DOCUMENT_ROOT'] . '/logs/paypal_session_fix.log';
// Ensure log directory exists
$log_dir = dirname($this->log_file);
if (!file_exists($log_dir)) {
mkdir($log_dir, 0755, true);
}
}
/**
* Store cart data in database before PayPal redirect
*
* @param string $session_key - PayPal token or session_id
* @param array $cart_data - Complete cart contents
* @param string $payment_provider - 'paypal', 'stripe', etc.
* @return bool Success/failure
*/
public function storeCartSession($session_key, $cart_data, $payment_provider = 'paypal') {
$session_key_clean = $this->db->real_escape_string($session_key);
$cart_json = $this->db->real_escape_string(json_encode($cart_data));
$provider_clean = $this->db->real_escape_string($payment_provider);
$user_agent = $this->db->real_escape_string($_SERVER['HTTP_USER_AGENT'] ?? '');
$ip_address = $this->db->real_escape_string($_SERVER['REMOTE_ADDR'] ?? '');
$query = "
INSERT INTO cart_sessions (
session_key,
cart_data,
payment_provider,
status,
user_agent,
ip_address
) VALUES (
'{$session_key_clean}',
'{$cart_json}',
'{$provider_clean}',
'active',
'{$user_agent}',
'{$ip_address}'
) ON DUPLICATE KEY UPDATE
cart_data = VALUES(cart_data),
updated_at = CURRENT_TIMESTAMP,
status = 'active'
";
$result = $this->db->query($query);
if ($this->db->error) {
$this->writePayPalLog("STORE_ERROR", "Database error: " . $this->db->error);
return false;
}
// Dedicated PayPal logging - no more Plesk chaos!
$this->writePayPalLog("STORE_SUCCESS", "Cart stored for token: {$session_key}", array(
'cart_items' => count($cart_data['shoppingcart'] ?? []),
'order_id' => $cart_data['order_id'] ?? 'unknown'
));
return $result ? true : false;
}
/**
* Retrieve cart data from database after PayPal return
*
* @param string $session_key - PayPal token or session_id
* @return array|null Cart data or null if not found
*/
public function retrieveCartSession($session_key) {
$session_key_clean = $this->db->real_escape_string($session_key);
$query = "
SELECT
cart_data,
payment_provider,
status,
created_at,
updated_at
FROM cart_sessions
WHERE session_key = '{$session_key_clean}'
AND expires_at > NOW()
LIMIT 1
";
$result = $this->db->query($query);
if ($this->db->error) {
$this->writePayPalLog("RETRIEVE_ERROR", "Database error: " . $this->db->error);
return null;
}
if ($result && $result->num_rows > 0) {
$row = $result->fetch_object();
$cart_data = json_decode($row->cart_data, true);
// Success logging
$this->writePayPalLog("RETRIEVE_SUCCESS", "Cart retrieved for key: {$session_key}", array(
'cart_items' => count($cart_data['shoppingcart'] ?? []),
'status' => $row->status
));
return array(
'cart_data' => $cart_data,
'payment_provider' => $row->payment_provider,
'status' => $row->status,
'created_at' => $row->created_at,
'updated_at' => $row->updated_at
);
}
$this->writePayPalLog("RETRIEVE_FAILED", "No cart found for key: {$session_key}");
return null;
}
/**
* Dedicated PayPal logging system - no more Plesk chaos!
*
* @param string $type - LOG_TYPE (STORE_SUCCESS, RETRIEVE_SUCCESS, ERROR, etc.)
* @param string $message - Human readable message
* @param array $context - Additional context data
*/
private function writePayPalLog($type, $message, $context = array()) {
$timestamp = date('Y-m-d H:i:s');
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$user_agent = substr($_SERVER['HTTP_USER_AGENT'] ?? '', 0, 100);
$log_entry = sprintf(
"[%s] %s | %s | IP:%s | %s | Context:%s\n",
$timestamp,
$type,
$message,
$ip,
$user_agent,
json_encode($context)
);
// Write to dedicated PayPal log file
file_put_contents($this->log_file, $log_entry, FILE_APPEND | LOCK_EX);
// Also write to error_log as fallback
error_log("PayPal Session Fix [{$type}]: {$message}");
}
/**
* Update cart session status (processing, completed, abandoned)
*
* @param string $session_key
* @param string $status - 'processing', 'completed', 'abandoned'
* @return bool Success/failure
*/
public function updateCartStatus($session_key, $status) {
$session_key_clean = $this->db->real_escape_string($session_key);
$status_clean = $this->db->real_escape_string($status);
$query = "
UPDATE cart_sessions
SET status = '{$status_clean}',
updated_at = CURRENT_TIMESTAMP
WHERE session_key = '{$session_key_clean}'
";
$result = $this->db->query($query);
if ($this->db->error) {
$this->writePayPalLog("STATUS_ERROR", "Database error: " . $this->db->error);
return false;
}
$this->writePayPalLog("STATUS_UPDATE", "Updated {$session_key} to {$status}");
return $result ? true : false;
}
/**
* Clean up expired or completed cart sessions
* Should be called via cron job
*
* @param int $older_than_hours - Delete sessions older than X hours
* @return int Number of deleted records
*/
public function cleanupExpiredSessions($older_than_hours = 24) {
$query = "
DELETE FROM cart_sessions
WHERE expires_at < NOW()
OR (status = 'completed' AND updated_at < (NOW() - INTERVAL {$older_than_hours} HOUR))
OR (status = 'abandoned' AND updated_at < (NOW() - INTERVAL {$older_than_hours} HOUR))
";
$result = $this->db->query($query);
$deleted_count = $this->db->affected_rows;
if ($this->db->error) {
$this->writePayPalLog("CLEANUP_ERROR", "Database error: " . $this->db->error);
return 0;
}
$this->writePayPalLog("CLEANUP_SUCCESS", "Deleted {$deleted_count} expired sessions");
return $deleted_count;
}
/**
* Debug helper - get cart session info
*/
public function getCartSessionInfo($session_key) {
$session_key_clean = $this->db->real_escape_string($session_key);
$query = "
SELECT * FROM cart_sessions
WHERE session_key = '{$session_key_clean}'
LIMIT 1
";
$result = $this->db->query($query);
if ($result && $result->num_rows > 0) {
return $result->fetch_object();
}
return null;
}
}
?>