```php
// Prevent direct access
if (!defined('ABSPATH')) {
exit;
}
// Central handler for WooCommerce order status changes
add_action('woocommerce_order_status_changed', 'rahnama_on_order_status_change', 10, 4);
function rahnama_on_order_status_change($order_id, $old_status, $new_status, $order) {
error_log("Rahnama CRM LOG: Hook 'woocommerce_order_status_changed' triggered for order #{$order_id}. Status changed from '{$old_status}' to '{$new_status}'. Time: " . current_time('mysql'));
if (!$order) {
$order = wc_get_order($order_id);
if (!$order) {
error_log("Rahnama CRM ERROR: Could not get order object for order #{$order_id}. Aborting.");
return;
}
}
// لاگ اضافی برای بررسی اجرای هوک
error_log("Rahnama CRM DEBUG: Processing order #{$order_id} for status {$new_status}. Order object exists: " . (is_a($order, 'WC_Order') ? 'Yes' : 'No'));
// ریست متادیتا برای اجازه ارسال پیامک در هر تغییر وضعیت
$meta_keys = ['rahnama_processing_sent', 'rahnama_pending_admin1_sent', 'rahnama_pending_admin2_sent', 'rahnama_completed_sent', 'rahnama_cancelled_sent', 'rahnama_reminder_sent'];
foreach ($meta_keys as $meta_key) {
delete_post_meta($order_id, $meta_key);
error_log("Rahnama CRM LOG: Reset meta '$meta_key' for order #{$order_id} due to status change to '{$new_status}' at " . current_time('mysql'));
}
$customer_phone = rahnama_normalize_phone_number($order->get_billing_phone() ?: '', true, false);
error_log("Rahnama CRM LOG: Order #{$order_id} - Customer phone raw: '{$order->get_billing_phone()}', Normalized: '{$customer_phone}'");
if (!$customer_phone) {
error_log("Rahnama CRM ERROR: No valid customer phone for order #{$order_id}. Skipping customer SMS.");
}
// آمادهسازی متغیرها برای پیامک
$variables = rahnama_prepare_sms_variables($order, $order->get_customer_id());
error_log("Rahnama CRM DEBUG: Variables for order #{$order_id}: " . json_encode($variables, JSON_UNESCAPED_UNICODE));
// لاگ تنظیمات مرتبط
$settings = [
'rahnama_pending_admin1_pattern' => get_option('rahnama_pending_admin1_pattern', ''),
'rahnama_pending_admin1_message' => get_option('rahnama_pending_admin1_message', ''),
'rahnama_pending_admin2_pattern' => get_option('rahnama_pending_admin2_pattern', ''),
'rahnama_pending_admin2_message' => get_option('rahnama_pending_admin2_message', ''),
'rahnama_processing_pattern' => get_option('rahnama_processing_pattern', ''),
'rahnama_processing_message' => get_option('rahnama_processing_message', ''),
'rahnama_completed_pattern' => get_option('rahnama_completed_pattern', ''),
'rahnama_completed_message' => get_option('rahnama_completed_message', ''),
'rahnama_cancelled_pattern' => get_option('rahnama_cancelled_pattern', ''),
'rahnama_cancelled_message' => get_option('rahnama_cancelled_message', ''),
'rahnama_pending_reminder_pattern' => get_option('rahnama_pending_reminder_pattern', ''),
'rahnama_pending_reminder_message' => get_option('rahnama_pending_reminder_message', ''),
'rahnama_admin1_number' => get_option('rahnama_admin1_number', ''),
'rahnama_admin2_number' => get_option('rahnama_admin2_number', ''),
];
error_log("Rahnama CRM LOG: Order #{$order_id} - Settings: " . json_encode($settings, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
// تابع کمکی برای ارسال پیامک
$send_sms_if_needed = function($pattern_key, $message_key, $phone_number, $meta_key, $delay_hours = 0) use ($order, $order_id, $new_status, $variables) {
$pattern_code = get_option($pattern_key, '');
$message = get_option($message_key, '');
$normalized_phone = rahnama_normalize_phone_number($phone_number, true, false);
// لاگ دقیق برای بررسی تنظیمات
error_log("Rahnama CRM DEBUG: Attempting SMS for order #{$order_id} ({$meta_key}) - Pattern key: {$pattern_key}, Message key: {$message_key}, Phone raw: {$phone_number}, Normalized: " . ($normalized_phone ?: 'false') . ", Pattern: " . ($pattern_code ?: 'None') . ", Message: " . (strlen($message) > 100 ? substr($message, 0, 100) . '...' : $message));
// بررسی پیشنیازها
if (!$normalized_phone) {
error_log("Rahnama CRM ERROR: SMS for order #{$order_id} ({$meta_key}) skipped - Invalid or empty phone number ('{$phone_number}').");
return ['status' => 'error', 'message' => 'شماره تلفن نامعتبر یا خالی است'];
}
if (empty($pattern_code)) {
error_log("Rahnama CRM ERROR: SMS for order #{$order_id} ({$meta_key}) skipped - Pattern code '{$pattern_key}' is empty.");
return ['status' => 'error', 'message' => 'کد پترن خالی است'];
}
if (empty($message)) {
error_log("Rahnama CRM ERROR: SMS for order #{$order_id} ({$meta_key}) skipped - Message for variables '{$message_key}' is empty.");
return ['status' => 'error', 'message' => 'پیام متغیرها خالی است'];
}
if ($meta_key !== 'rahnama_abandoned_cart_sent' && !preg_match('/\{order_id\}/', $message)) {
error_log("Rahnama CRM ERROR: SMS for order #{$order_id} ({$meta_key}) skipped - Missing required {order_id} variable in message");
return ['status' => 'error', 'message' => 'متغیر {order_id} الزامی است'];
}
$pattern_values = rahnama_prepare_pattern_values($message, $variables, $order, $order->get_customer_id());
error_log("Rahnama CRM DEBUG: Pattern values for order #{$order_id} ({$meta_key}): " . json_encode($pattern_values, JSON_UNESCAPED_UNICODE));
// برای پیامکهای با تأخیر (مانند لغو شده یا یادآوری پرداخت)، بررسی متادیتا انجام میشود
if ($delay_hours > 0) {
$meta_exists = get_post_meta($order_id, $meta_key, true);
if ($meta_exists) {
error_log("Rahnama CRM SKIPPED: SMS for order #{$order_id} ({$meta_key}) - Already sent or scheduled.");
return ['status' => 'skipped', 'message' => 'پیامک قبلاً ارسال یا زمانبندی شده است'];
}
wp_schedule_single_event(time() + ($delay_hours * 3600), 'rahnama_send_delayed_sms', [$order_id, $message_key, $normalized_phone, $variables, $pattern_key]);
update_post_meta($order_id, $meta_key, true);
error_log("Rahnama CRM LOG: SMS for order #{$order_id} ({$meta_key}) SCHEDULED for {$delay_hours} hours later to {$normalized_phone}.");
return ['status' => 'scheduled', 'message' => 'پیامک زمانبندی شد'];
}
// برای پیامکهای بدون تأخیر (مانند در حال انجام، تکمیل شده، و ادمینها)، بدون بررسی متادیتا ارسال میشود
$result = rahnama_send_sms($message, $normalized_phone, $variables, $order, $order->get_customer_id(), $pattern_code, true);
error_log("Rahnama CRM LOG: SMS result for order #{$order_id} ({$meta_key}) to {$normalized_phone}: Status: {$result['status']}, Message: " . ($result['message'] ?? 'N/A') . ", Message ID: " . ($result['message_id'] ?? 'N/A'));
if ($result['status'] === 'success') {
update_post_meta($order_id, $meta_key, true);
error_log("Rahnama CRM SUCCESS: SMS for order #{$order_id} ({$meta_key}) sent to {$normalized_phone}. Message ID: " . ($result['message_id'] ?? 'N/A'));
} else {
error_log("Rahnama CRM ERROR: SMS for order #{$order_id} ({$meta_key}) failed to {$normalized_phone}. Reason: " . ($result['message'] ?? 'Unknown error'));
}
return $result;
};
switch ($new_status) {
case 'pending':
// ارسال همزمان برای ادمین ۱ و ادمین ۲
$admin1_result = $send_sms_if_needed('rahnama_pending_admin1_pattern', 'rahnama_pending_admin1_message', get_option('rahnama_admin1_number'), 'rahnama_pending_admin1_sent');
$admin2_result = $send_sms_if_needed('rahnama_pending_admin2_pattern', 'rahnama_pending_admin2_message', get_option('rahnama_admin2_number'), 'rahnama_pending_admin2_sent');
error_log("Rahnama CRM DEBUG: Admin SMS results for order #{$order_id} - Admin 1: " . json_encode($admin1_result, JSON_UNESCAPED_UNICODE) . ", Admin 2: " . json_encode($admin2_result, JSON_UNESCAPED_UNICODE));
break;
case 'processing':
$send_sms_if_needed('rahnama_processing_pattern', 'rahnama_processing_message', $customer_phone, 'rahnama_processing_sent');
break;
case 'completed':
$send_sms_if_needed('rahnama_completed_pattern', 'rahnama_completed_message', $customer_phone, 'rahnama_completed_sent');
break;
case 'cancelled':
$delay = (float) get_option('rahnama_cancelled_delay', 0);
$send_sms_if_needed('rahnama_cancelled_pattern', 'rahnama_cancelled_message', $customer_phone, 'rahnama_cancelled_sent', $delay);
break;
default:
error_log("Rahnama CRM LOG: No SMS action defined for status '{$new_status}' for order #{$order_id}");
break;
}
}
// Handler for payment completion
if (!function_exists('rahnama_on_payment_complete')) {
add_action('woocommerce_payment_complete', 'rahnama_on_payment_complete', 10, 1);
function rahnama_on_payment_complete($order_id) {
error_log("Rahnama CRM LOG: Hook 'woocommerce_payment_complete' triggered for order #{$order_id}. Time: " . current_time('mysql'));
$order = wc_get_order($order_id);
if (!$order) {
error_log("Rahnama CRM ERROR: Could not get order object for order #{$order_id} in payment complete hook. Aborting.");
return;
}
// بررسی وضعیت سفارش
$status = $order->get_status();
error_log("Rahnama CRM DEBUG: Order #{$order_id} status after payment: {$status}");
// آمادهسازی متغیرها
$variables = rahnama_prepare_sms_variables($order, $order->get_customer_id());
error_log("Rahnama CRM DEBUG: Variables for order #{$order_id} in payment complete: " . json_encode($variables, JSON_UNESCAPED_UNICODE));
// تابع کمکی برای ارسال پیامک
$send_sms_if_needed = function($pattern_key, $message_key, $phone_number, $meta_key) use ($order, $order_id, $variables) {
$pattern_code = get_option($pattern_key, '');
$message = get_option($message_key, '');
$normalized_phone = rahnama_normalize_phone_number($phone_number, true, false);
// لاگ دقیق برای بررسی تنظیمات
error_log("Rahnama CRM DEBUG: Attempting SMS for order #{$order_id} ({$meta_key}) - Pattern key: {$pattern_key}, Message key: {$message_key}, Phone raw: {$phone_number}, Normalized: " . ($normalized_phone ?: 'false') . ", Pattern: " . ($pattern_code ?: 'None') . ", Message: " . (strlen($message) > 100 ? substr($message, 0, 100) . '...' : $message));
// بررسی پیشنیازها
if (!$normalized_phone) {
error_log("Rahnama CRM ERROR: SMS for order #{$order_id} ({$meta_key}) skipped - Invalid or empty phone number ('{$phone_number}').");
return ['status' => 'error', 'message' => 'شماره تلفن نامعتبر یا خالی است'];
}
if (empty($pattern_code)) {
error_log("Rahnama CRM ERROR: SMS for order #{$order_id} ({$meta_key}) skipped - Pattern code '{$pattern_key}' is empty.");
return ['status' => 'error', 'message' => 'کد پترن خالی است'];
}
if (empty($message)) {
error_log("Rahnama CRM ERROR: SMS for order #{$order_id} ({$meta_key}) skipped - Message for variables '{$message_key}' is empty.");
return ['status' => 'error', 'message' => 'پیام متغیرها خالی است'];
}
if ($meta_key !== 'rahnama_abandoned_cart_sent' && !preg_match('/\{order_id\}/', $message)) {
error_log("Rahnama CRM ERROR: SMS for order #{$order_id} ({$meta_key}) skipped - Missing required {order_id} variable in message");
return ['status' => 'error', 'message' => 'متغیر {order_id} الزامی است'];
}
$pattern_values = rahnama_prepare_pattern_values($message, $variables, $order, $order->get_customer_id());
error_log("Rahnama CRM DEBUG: Pattern values for order #{$order_id} ({$meta_key}): " . json_encode($pattern_values, JSON_UNESCAPED_UNICODE));
$result = rahnama_send_sms($message, $normalized_phone, $variables, $order, $order->get_customer_id(), $pattern_code, true);
error_log("Rahnama CRM LOG: SMS result for order #{$order_id} ({$meta_key}) to {$normalized_phone}: Status: {$result['status']}, Message: " . ($result['message'] ?? 'N/A') . ", Message ID: " . ($result['message_id'] ?? 'N/A'));
if ($result['status'] === 'success') {
update_post_meta($order_id, $meta_key, true);
error_log("Rahnama CRM SUCCESS: SMS for order #{$order_id} ({$meta_key}) sent to {$normalized_phone}. Message ID: " . ($result['message_id'] ?? 'N/A'));
} else {
error_log("Rahnama CRM ERROR: SMS for order #{$order_id} ({$meta_key}) failed to {$normalized_phone}. Reason: " . ($result['message'] ?? 'Unknown error'));
}
return $result;
};
// اگر وضعیت به processing تغییر کرده یا نیاز به پردازش دارد
if ($status === 'processing' || $order->needs_processing()) {
// ریست متادیتا برای پیامکهای بدون تأخیر
$meta_keys = ['rahnama_processing_sent', 'rahnama_pending_admin1_sent', 'rahnama_pending_admin2_sent'];
foreach ($meta_keys as $meta_key) {
delete_post_meta($order_id, $meta_key);
error_log("Rahnama CRM LOG: Reset meta '$meta_key' for order #{$order_id} in payment complete hook at " . current_time('mysql'));
}
// ارسال پیامک برای مشتری (در حال انجام)
$customer_phone = rahnama_normalize_phone_number($order->get_billing_phone() ?: '', true, false);
if ($customer_phone) {
$send_sms_if_needed('rahnama_processing_pattern', 'rahnama_processing_message', $customer_phone, 'rahnama_processing_sent');
} else {
error_log("Rahnama CRM ERROR: No valid customer phone for order #{$order_id} in payment complete hook. Skipping customer SMS.");
}
// ارسال پیامک برای ادمین ۱ و ادمین ۲
$admin1_number = get_option('rahnama_admin1_number', '');
$admin2_number = get_option('rahnama_admin2_number', '');
$admin1_result = $send_sms_if_needed('rahnama_pending_admin1_pattern', 'rahnama_pending_admin1_message', $admin1_number, 'rahnama_pending_admin1_sent');
$admin2_result = $send_sms_if_needed('rahnama_pending_admin2_pattern', 'rahnama_pending_admin2_message', $admin2_number, 'rahnama_pending_admin2_sent');
error_log("Rahnama CRM DEBUG: Admin SMS results for order #{$order_id} in payment complete - Admin 1: " . json_encode($admin1_result, JSON_UNESCAPED_UNICODE) . ", Admin 2: " . json_encode($admin2_result, JSON_UNESCAPED_UNICODE));
} else {
error_log("Rahnama CRM LOG: Order #{$order_id} not in processing status after payment complete (status: {$status}). Skipping SMS.");
}
}
}
```
برای دیدن محصولاتی که می خواهید، شروع به تایپ کنید.