<?php /** * Plugin Name: اس ام اس سبدخرید رها شده * Plugin URI: https://adogen.ir * Description: پلاگینی قدرتمند برای ووکامرس جهت ارسال پیامک‌های یادآوری برای سبدهای خرید رها شده * Version: 1.5 * Author: adogen.ir * Author URI: https://adogen.ir * Text Domain: abandoned-cart-sms * Domain Path: /languages * Requires at least: 5.0 * Tested up to: 6.3 * Requires PHP: 7.4 * WC requires at least: 3.0 * WC tested up to: 8.0 */ // Prevent direct access if (!defined('ABSPATH')) { exit; } // Check if WooCommerce is active if (!in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) { return; } /** * Main Plugin Class */ class Abandoned_Cart_SMS { private static $instance = null; public static function get_instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } private function __construct() { add_action('init', array($this, 'init')); add_action('plugins_loaded', array($this, 'load_textdomain')); } public function init() { // Admin hooks if (is_admin()) { add_action('admin_menu', array($this, 'admin_menu')); add_action('admin_init', array($this, 'admin_init')); add_action('admin_enqueue_scripts', array($this, 'admin_scripts')); } // Frontend hooks for order status changes add_action('woocommerce_order_status_changed', array($this, 'handle_order_status_change'), 10, 3); // Schedule cron for abandoned carts add_action('wp', array($this, 'schedule_cron')); add_action('abandoned_cart_check', array($this, 'check_abandoned_carts')); // AJAX for test SMS add_action('wp_ajax_send_test_sms', array($this, 'send_test_sms')); } public function load_textdomain() { load_plugin_textdomain('abandoned-cart-sms', false, dirname(plugin_basename(__FILE__)) . '/languages'); } public function admin_menu() { add_options_page( __('تنظیمات اس ام اس سبدخرید رها شده', 'abandoned-cart-sms'), __('اس ام اس سبد رها شده', 'abandoned-cart-sms'), 'manage_options', 'abandoned-cart-sms', array($this, 'settings_page') ); } public function admin_init() { register_setting('abandoned_cart_sms_options', 'abandoned_cart_sms_settings'); add_settings_section( 'abandoned_cart_sms_main_section', __('تنظیمات اصلی', 'abandoned-cart-sms'), null, 'abandoned-cart-sms' ); // SMS Panel Settings (Auto-detect) add_settings_field( 'sms_api', __('API Key', 'abandoned-cart-sms'), array($this, 'sms_api_callback'), 'abandoned-cart-sms', 'abandoned_cart_sms_main_section' ); add_settings_field( 'sms_username', __('Username', 'abandoned-cart-sms'), array($this, 'sms_username_callback'), 'abandoned-cart-sms', 'abandoned_cart_sms_main_section' ); add_settings_field( 'sms_password', __('Password', 'abandoned-cart-sms'), array($this, 'sms_password_callback'), 'abandoned-cart-sms', 'abandoned_cart_sms_main_section' ); // Stages Settings add_settings_section( 'abandoned_cart_sms_stages_section', __('مراحل ارسال اس ام اس', 'abandoned-cart-sms'), null, 'abandoned-cart-sms' ); add_settings_field( 'num_stages', __('تعداد مراحل', 'abandoned-cart-sms'), array($this, 'num_stages_callback'), 'abandoned-cart-sms', 'abandoned_cart_sms_stages_section' ); add_settings_field( 'time_interval', __('فاصله زمانی (ساعت)', 'abandoned-cart-sms'), array($this, 'time_interval_callback'), 'abandoned-cart-sms', 'abandoned_cart_sms_stages_section' ); // Order Statuses add_settings_section( 'abandoned_cart_sms_status_section', __('وضعیت‌های سفارش', 'abandoned-cart-sms'), null, 'abandoned-cart-sms' ); add_settings_field( 'order_statuses', __('وضعیت‌های فعال', 'abandoned-cart-sms'), array($this, 'order_statuses_callback'), 'abandoned-cart-sms', 'abandoned_cart_sms_status_section' ); // Messages for each stage add_settings_section( 'abandoned_cart_sms_messages_section', __('متن‌های اس ام اس', 'abandoned-cart-sms'), array($this, 'messages_section_callback'), 'abandoned-cart-sms' ); for ($i = 1; $i <= 5; $i++) { // Up to 5 stages add_settings_field( 'message_stage_' . $i, sprintf(__('مرحله %d', 'abandoned-cart-sms'), $i), array($this, 'message_stage_callback'), 'abandoned-cart-sms', 'abandoned_cart_sms_messages_section', array('stage' => $i) ); } // Test SMS add_settings_field( 'test_phone', __('شماره تست', 'abandoned-cart-sms'), array($this, 'test_phone_callback'), 'abandoned-cart-sms', 'abandoned_cart_sms_messages_section' ); } public function settings_page() { ?> <div class="wrap"> <h1><?php _e('تنظیمات اس ام اس سبدخرید رها شده', 'abandoned-cart-sms'); ?></h1> <form method="post" action="options.php"> <?php settings_fields('abandoned_cart_sms_options'); do_settings_sections('abandoned-cart-sms'); submit_button(); ?> </form> <div id="test-sms-result"></div> </div> <script> jQuery(document).ready(function($) { $('#send-test-sms').on('click', function(e) { e.preventDefault(); var phone = $('#test_phone').val(); if (!phone) { alert('لطفا شماره تلفن تست را وارد کنید.'); return; } $.post(ajaxurl, { action: 'send_test_sms', phone: phone, nonce: '<?php echo wp_create_nonce('send_test_sms'); ?>' }, function(response) { $('#test-sms-result').html(response); }); }); }); </script> <?php } // Auto-detect SMS Panel credentials (assuming a common Iranian SMS provider like FarazSMS or similar; customize as needed) public function detect_sms_credentials() { // This is a placeholder. In reality, you might hook into user meta or a specific SMS plugin. // For example, if using a SMS plugin like WP SMS, retrieve from its options. $options = get_option('wp_sms_options', array()); // Example for WP SMS plugin return array( 'api' => isset($options['api_key']) ? $options['api_key'] : '', 'username' => isset($options['username']) ? $options['username'] : '', 'password' => isset($options['password']) ? $options['password'] : '', ); } public function sms_api_callback() { $settings = get_option('abandoned_cart_sms_settings', array()); $creds = $this->detect_sms_credentials(); echo '<input type="text" name="abandoned_cart_sms_settings[sms_api]" value="' . esc_attr($creds['api']) . '" class="regular-text" readonly />'; echo '<p class="description">' . __('این اطلاعات به طور خودکار از پنل SMS شما دریافت می‌شود.', 'abandoned-cart-sms') . '</p>'; } public function sms_username_callback() { $settings = get_option('abandoned_cart_sms_settings', array()); $creds = $this->detect_sms_credentials(); echo '<input type="text" name="abandoned_cart_sms_settings[sms_username]" value="' . esc_attr($creds['username']) . '" class="regular-text" readonly />'; } public function sms_password_callback() { $settings = get_option('abandoned_cart_sms_settings', array()); $creds = $this->detect_sms_credentials(); echo '<input type="password" name="abandoned_cart_sms_settings[sms_password]" value="' . esc_attr($creds['password']) . '" class="regular-text" readonly />'; } public function num_stages_callback() { $settings = get_option('abandoned_cart_sms_settings', array()); $num = isset($settings['num_stages']) ? $settings['num_stages'] : 3; echo '<input type="number" name="abandoned_cart_sms_settings[num_stages]" value="' . esc_attr($num) . '" min="1" max="5" />'; echo '<p class="description">' . __('تعداد مراحل ارسال اس ام اس (حداکثر 5).', 'abandoned-cart-sms') . '</p>'; } public function time_interval_callback() { $settings = get_option('abandoned_cart_sms_settings', array()); $interval = isset($settings['time_interval']) ? $settings['time_interval'] : 24; echo '<input type="number" name="abandoned_cart_sms_settings[time_interval]" value="' . esc_attr($interval) . '" min="1" />'; echo '<p class="description">' . __('فاصله زمانی بین هر مرحله به ساعت.', 'abandoned-cart-sms') . '</p>'; } public function order_statuses_callback() { $settings = get_option('abandoned_cart_sms_settings', array()); $statuses = isset($settings['order_statuses']) ? $settings['order_statuses'] : array('pending', 'failed', 'cancelled'); $wc_statuses = wc_get_order_statuses(); foreach ($wc_statuses as $status_key => $status_label) { $checked = in_array($status_key, $statuses) ? 'checked' : ''; echo '<label><input type="checkbox" name="abandoned_cart_sms_settings[order_statuses][]" value="' . esc_attr($status_key) . '" ' . $checked . ' /> ' . esc_html($status_label) . '</label><br>'; } echo '<p class="description">' . __('وضعیت‌هایی که در آن‌ها اس ام اس ارسال شود.', 'abandoned-cart-sms') . '</p>'; } public function messages_section_callback() { echo '<p>' . __('برای هر مرحله، متن دلخواه بنویسید. تگ‌های پیشنهادی: {customer_name}, {customer_phone}, {order_id}, {product_name}, {total_amount}, {abandon_time}', 'abandoned-cart-sms') . '</p>'; } public function message_stage_callback($args) { $stage = $args['stage']; $settings = get_option('abandoned_cart_sms_settings', array()); $message = isset($settings['message_stage_' . $stage]) ? $settings['message_stage_' . $stage] : ''; echo '<textarea name="abandoned_cart_sms_settings[message_stage_' . $stage . ']" rows="3" cols="50" class="large-text">' . esc_textarea($message) . '</textarea>'; echo '<p class="description">' . sprintf(__('متن برای مرحله %d', 'abandoned-cart-sms'), $stage) . '</p>'; } public function test_phone_callback() { echo '<input type="text" id="test_phone" placeholder="09xxxxxxxxx" />'; echo '<button type="button" id="send-test-sms" class="button button-primary">' . __('ارسال تست', 'abandoned-cart-sms') . '</button>'; echo '<p class="description">' . __('برای تست ارسال اس ام اس.', 'abandoned-cart-sms') . '</p>'; } public function admin_scripts($hook) { if ($hook !== 'settings_page') return; wp_enqueue_script('jquery'); } // Handle order status change public function handle_order_status_change($order_id, $old_status, $new_status) { $settings = get_option('abandoned_cart_sms_settings', array()); $active_statuses = isset($settings['order_statuses']) ? $settings['order_statuses'] : array(); if (!in_array($new_status, $active_statuses)) return; $order = wc_get_order($order_id); if (!$order) return; // Check if it's abandoned (e.g., pending or failed) if ($order->has_status($active_statuses)) { $this->send_abandonment_sms($order, 1); // Send first stage immediately } } // Schedule cron job public function schedule_cron() { if (!wp_next_scheduled('abandoned_cart_check')) { wp_schedule_event(time(), 'hourly', 'abandoned_cart_check'); } } // Check for abandoned carts and send subsequent stages public function check_abandoned_carts() { $settings = get_option('abandoned_cart_sms_settings', array()); $num_stages = isset($settings['num_stages']) ? (int)$settings['num_stages'] : 3; $interval = isset($settings['time_interval']) ? (int)$settings['time_interval'] * HOUR_IN_SECONDS : 24 * HOUR_IN_SECONDS; $active_statuses = isset($settings['order_statuses']) ? $settings['order_statuses'] : array(); // Query for pending/failed orders older than interval $args = array( 'status' => $active_statuses, 'limit' => -1, 'date_created' => '< ' . (current_time('timestamp') - $interval), 'return' => 'objects', ); $orders = wc_get_orders($args); foreach ($orders as $order) { $order_id = $order->get_id(); $sent_stages = get_post_meta($order_id, '_sms_sent_stages', true); $sent_stages = $sent_stages ? json_decode($sent_stages, true) : array(); $next_stage = count($sent_stages) + 1; if ($next_stage <= $num_stages && !in_array($next_stage, $sent_stages)) { $this->send_abandonment_sms($order, $next_stage); $sent_stages[] = $next_stage; update_post_meta($order_id, '_sms_sent_stages', json_encode($sent_stages)); } } } // Send SMS function (placeholder for actual SMS API) private function send_sms($phone, $message) { $settings = get_option('abandoned_cart_sms_settings', array()); $creds = $this->detect_sms_credentials(); // Or use stored if not auto // Example using a generic SMS API (e.g., for Iranian providers like Kavenegar or FarazSMS) // Replace with actual API call $api_url = 'https://api.smsprovider.com/send'; // Placeholder $response = wp_remote_post($api_url, array( 'body' => array( 'api' => $creds['api'], 'username' => $creds['username'], 'password' => $creds['password'], 'to' => $phone, 'message' => $message, ), )); if (is_wp_error($response)) { error_log('SMS Send Error: ' . $response->get_error_message()); return false; } $body = wp_remote_retrieve_body($response); // Parse response to check success return strpos($body, 'success') !== false; // Placeholder } // Send abandonment SMS private function send_abandonment_sms($order, $stage) { $customer = $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(); $phone = $order->get_billing_phone(); $email = $order->get_billing_email(); $order_id = $order->get_id(); $products = $order->get_items(); $product_names = array(); foreach ($products as $item) { $product_names[] = $item->get_name(); } $product_name = implode(', ', $product_names); $total = $order->get_total(); $abandon_time = $order->get_date_created() ? $order->get_date_created()->format('Y-m-d H:i') : ''; $settings = get_option('abandoned_cart_sms_settings', array()); $message_template = isset($settings['message_stage_' . $stage]) ? $settings['message_stage_' . $stage] : ''; // Replace tags $message = str_replace( array('{customer_name}', '{customer_phone}', '{customer_email}', '{order_id}', '{product_name}', '{total_amount}', '{abandon_time}'), array($customer, $phone, $email, $order_id, $product_name, $total, $abandon_time), $message_template ); if ($this->send_sms($phone, $message)) { // Log success error_log('SMS sent to ' . $phone . ' for order ' . $order_id . ' stage ' . $stage); } } // AJAX handler for test SMS public function send_test_sms() { check_ajax_referer('send_test_sms', 'nonce'); if (!current_user_can('manage_options')) { wp_die('Unauthorized'); } $phone = sanitize_text_field($_POST['phone']); $message = 'این یک پیام تست از پلاگین اس ام اس سبدخرید رها شده است.'; if ($this->send_sms($phone, $message)) { echo '<p class="notice notice-success">' . __('اس ام اس تست با موفقیت ارسال شد.', 'abandoned-cart-sms') . '</p>'; } else { echo '<p class="notice notice-error">' . __('خطا در ارسال اس ام اس تست.', 'abandoned-cart-sms') . '</p>'; } wp_die(); } } // Initialize the plugin Abandoned_Cart_SMS::get_instance(); فروشگاه | بته چی
ورود و عضویت
خوش آمدید
6

مبلغ کل: 26,057,600 تومان

مشاهده سبد خریدتسویه حساب

ورود و عضویت
خوش آمدید
6

مبلغ کل: 26,057,600 تومان

مشاهده سبد خریدتسویه حساب

×
show blocks helper

قیمت

دسته‌های محصولات +

محصول رنگ +

محصول سایز +

فروشگاه

نمایش 181–270 از 1438 نتیجه

show blocks helper

قیمت

دسته‌های محصولات +

محصول رنگ +

محصول سایز +

فیلدهای قابل نمایش را انتخاب کنید. بقیه فیلد ها مخفی خواهند شد
  • تصویر
  • کد محصول
  • نمره
  • قیمت
  • موجود
  • دسترسی
  • توضیح
  • عرض
  • اندازه
  • ویژگی ها
  • فیلد دلخواه
مقایسه
×

به بته چی خوش آمدید

مشاوران آماده راهنمایی شما هستند

×