| Server IP : 104.171.130.249 / Your IP : 216.73.216.146 Web Server : nginx/1.25.5 System : Linux 0dac65491b7e 6.8.0-134-generic #134-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 26 18:43:11 UTC 2026 x86_64 User : root ( 0) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : ON | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /var/www/html/wp-content/themes/matreshka/inc/ |
Upload File : |
<?php
/**
* User notifications system
*
* @package Matreshka
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Get user notifications
*
* @param int|null $user_id User ID. If null, uses current user.
* @param int $limit Number of notifications to retrieve. -1 for all.
* @return array Array of notifications
*/
function matreshka_get_user_notifications( $user_id = null, $limit = -1 ) {
if ( ! $user_id ) {
$user_id = get_current_user_id();
}
$notifications = get_user_meta( $user_id, 'matreshka_notifications', true );
if ( empty( $notifications ) || ! is_array( $notifications ) ) {
return array();
}
// Sort by date (newest first)
usort( $notifications, function( $a, $b ) {
$date_a = isset( $a['date'] ) ? $a['date'] : 0;
$date_b = isset( $b['date'] ) ? $b['date'] : 0;
return $date_b - $date_a;
});
// Limit results if needed
if ( $limit > 0 ) {
$notifications = array_slice( $notifications, 0, $limit );
}
return $notifications;
}
/**
* Clear all notifications for user
*
* @param int|null $user_id User ID. If null, uses current user.
* @return bool True on success, false on failure
*/
function matreshka_clear_all_notifications( $user_id = null ) {
if ( ! $user_id ) {
$user_id = get_current_user_id();
}
// Set empty array instead of deleting meta to prevent demo notifications from showing
return update_user_meta( $user_id, 'matreshka_notifications', array() );
}
/**
* Add notification for user
*
* @param int $user_id User ID
* @param string $title Notification title
* @param string $content Notification content
* @param array $args Additional arguments (type, link, etc.)
* @return bool True on success, false on failure
*/
function matreshka_add_notification( $user_id, $title, $content, $args = array() ) {
$notifications = get_user_meta( $user_id, 'matreshka_notifications', true );
if ( empty( $notifications ) || ! is_array( $notifications ) ) {
$notifications = array();
}
$notification = array(
'title' => sanitize_text_field( $title ),
'content' => sanitize_textarea_field( $content ),
'date' => current_time( 'timestamp' ),
'read' => false,
);
// Merge with additional arguments
$notification = array_merge( $notification, $args );
// Add to beginning of array (newest first)
array_unshift( $notifications, $notification );
// Keep only last 100 notifications
$notifications = array_slice( $notifications, 0, 100 );
return update_user_meta( $user_id, 'matreshka_notifications', $notifications );
}
/**
* Mark notification as read
*
* @param int $user_id User ID
* @param int $notification_index Index of notification in array
* @return bool True on success, false on failure
*/
function matreshka_mark_notification_read( $user_id, $notification_index ) {
$notifications = get_user_meta( $user_id, 'matreshka_notifications', true );
if ( empty( $notifications ) || ! isset( $notifications[ $notification_index ] ) ) {
return false;
}
$notifications[ $notification_index ]['read'] = true;
return update_user_meta( $user_id, 'matreshka_notifications', $notifications );
}
/**
* Get count of unread notifications
*
* @param int|null $user_id User ID. If null, uses current user.
* @return int Count of unread notifications
*/
function matreshka_get_unread_notifications_count( $user_id = null ) {
$notifications = matreshka_get_user_notifications( $user_id );
$unread_count = 0;
foreach ( $notifications as $notification ) {
if ( empty( $notification['read'] ) ) {
$unread_count++;
}
}
return $unread_count;
}
/**
* Clear old notifications (older than 60 days)
*
* @param int $user_id User ID
* @return bool True on success, false on failure
*/
function matreshka_clear_old_notifications( $user_id ) {
$notifications = get_user_meta( $user_id, 'matreshka_notifications', true );
if ( empty( $notifications ) || ! is_array( $notifications ) ) {
return false;
}
$cutoff_date = current_time( 'timestamp' ) - ( 60 * DAY_IN_SECONDS );
$filtered_notifications = array_filter( $notifications, function( $notification ) use ( $cutoff_date ) {
$date = isset( $notification['date'] ) ? $notification['date'] : 0;
return $date >= $cutoff_date;
});
return update_user_meta( $user_id, 'matreshka_notifications', array_values( $filtered_notifications ) );
}
/**
* ─── Order status change notifications ───
*/
add_action( 'woocommerce_order_status_changed', 'matreshka_notify_order_status_changed', 10, 4 );
function matreshka_notify_order_status_changed( $order_id, $old_status, $new_status, $order ) {
$user_id = $order->get_user_id();
if ( ! $user_id ) {
return;
}
// Skip completed — handled separately with cashback notification
if ( $new_status === 'completed' ) {
return;
}
$status_labels = [
'processing' => [ 'Заказ принят ✅', 'Ваш заказ #%d принят и готовится к сборке.' ],
'on-hold' => [ 'Заказ на удержании ⏳', 'Заказ #%d ожидает подтверждения оплаты.' ],
'shipped' => [ 'Заказ в пути 🚚', 'Ваш заказ #%d передан курьеру и уже в пути!' ],
'cancelled' => [ 'Заказ отменён ❌', 'Заказ #%d был отменён. Если это ошибка — свяжитесь с нами.' ],
'refunded' => [ 'Возврат средств 💸', 'По заказу #%d оформлен возврат средств.' ],
'failed' => [ 'Ошибка оплаты ⚠️', 'Оплата по заказу #%d не прошла. Попробуйте ещё раз.' ],
];
if ( ! isset( $status_labels[ $new_status ] ) ) {
return;
}
$label = $status_labels[ $new_status ];
matreshka_add_notification(
$user_id,
$label[0],
sprintf( $label[1], $order_id ),
[ 'type' => 'order', 'order_id' => $order_id ]
);
}
/**
* ─── Order completed + cashback notification ───
* Fires after cashback is awarded (priority 21, cashback is priority 20)
*/
add_action( 'woocommerce_order_status_completed', 'matreshka_notify_order_completed', 21 );
function matreshka_notify_order_completed( $order_id ) {
$order = wc_get_order( $order_id );
if ( ! $order ) return;
$user_id = $order->get_user_id();
if ( ! $user_id ) return;
$order_total = $order->get_total();
// Order completed notification
matreshka_add_notification(
$user_id,
'Заказ выполнен! 🎉',
sprintf( 'Ваш заказ #%d на сумму %s успешно доставлен. Спасибо за покупку!', $order_id, wc_price( $order_total ) ),
[ 'type' => 'order', 'order_id' => $order_id ]
);
// Cashback notification (if cashback was awarded)
$bonus_points = $order->get_meta( '_matreshka_cashback_awarded' );
$cashback_amt = $order->get_meta( '_matreshka_cashback_amount' );
if ( $bonus_points && $cashback_amt ) {
matreshka_add_notification(
$user_id,
'Бонусы начислены! 🎁',
sprintf(
'За заказ #%d вам начислено %s ₽ кешбека (%d бонусов). Используйте их при следующей покупке!',
$order_id,
number_format( (float) $cashback_amt, 2, '.', ' ' ),
(int) $bonus_points
),
[ 'type' => 'cashback', 'order_id' => $order_id ]
);
}
}
/**
* ─── Mark all notifications as read when user visits notifications page ───
*/
add_action( 'template_redirect', 'matreshka_mark_notifications_read_on_visit' );
function matreshka_mark_notifications_read_on_visit() {
if ( ! is_user_logged_in() ) {
return;
}
// Check if we're on the notifications page (by template or slug)
if ( ! is_page_template( 'page-notifications.php' ) && ! is_page( 'notifications' ) ) {
return;
}
$user_id = get_current_user_id();
$notifications = get_user_meta( $user_id, 'matreshka_notifications', true );
if ( empty( $notifications ) || ! is_array( $notifications ) ) {
return;
}
$changed = false;
foreach ( $notifications as &$n ) {
if ( empty( $n['read'] ) ) {
$n['read'] = true;
$changed = true;
}
}
unset( $n );
if ( $changed ) {
update_user_meta( $user_id, 'matreshka_notifications', $notifications );
}
}
/**
* Clean old notifications daily
*/
function matreshka_cleanup_notifications() {
$users = get_users( array( 'fields' => 'ID' ) );
foreach ( $users as $user_id ) {
matreshka_clear_old_notifications( $user_id );
}
}
// Schedule daily cleanup
if ( ! wp_next_scheduled( 'matreshka_daily_cleanup' ) ) {
wp_schedule_event( time(), 'daily', 'matreshka_daily_cleanup' );
}
add_action( 'matreshka_daily_cleanup', 'matreshka_cleanup_notifications' );
/**
* AJAX handler for clearing all notifications
*/
function matreshka_ajax_clear_all_notifications() {
// Check if user is logged in
if ( ! is_user_logged_in() ) {
wp_send_json_error( array( 'message' => 'Необходимо войти в систему' ) );
}
// Verify nonce
if ( ! check_ajax_referer( 'matreshka_notifications_nonce', 'nonce', false ) ) {
wp_send_json_error( array( 'message' => 'Недействительный запрос' ) );
}
$user_id = get_current_user_id();
$result = matreshka_clear_all_notifications( $user_id );
if ( $result ) {
wp_send_json_success( array( 'message' => 'Все уведомления удалены' ) );
} else {
wp_send_json_error( array( 'message' => 'Ошибка при удалении уведомлений' ) );
}
}
add_action( 'wp_ajax_matreshka_clear_notifications', 'matreshka_ajax_clear_all_notifications' );