settings = $settings; $this->repository = $repository; $this->providers = $providers; } public function register() { add_action( 'admin_init', array( $this, 'setting' ) ); add_action( 'admin_post_anar_toolkit_retry', array( $this, 'retry' ) ); add_action( 'admin_post_anar_toolkit_forget', array( $this, 'forget' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'assets' ) ); } public function menu() { add_submenu_page( 'anar-login', __( 'Commerce toolkit', 'anar-toolkit' ), __( 'Commerce toolkit', 'anar-toolkit' ), 'manage_options', 'anar-toolkit-commerce', array( $this, 'render' ) ); } public function setting() { register_setting( 'anar_toolkit_commerce', Settings::OPTION, array( 'type' => 'array', 'sanitize_callback' => array( $this->settings, 'sanitize' ), 'default' => $this->settings->defaults() ) ); } public function assets( $hook ) { if ( false !== strpos( $hook, 'anar-toolkit-' ) ) { wp_enqueue_style( 'anar-toolkit-commerce', ANAR_LOGIN_URL . 'assets/css/commerce-suite.css', array(), ANAR_LOGIN_VERSION ); } } private function guard() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You cannot manage these settings.', 'anar-toolkit' ), '', array( 'response' => 403 ) ); } } public function retry() { $this->guard(); check_admin_referer( 'anar_toolkit_retry' ); $this->repository->retry( isset( $_POST['message_id'] ) ? absint( $_POST['message_id'] ) : 0 ); wp_safe_redirect( admin_url( 'admin.php?page=anar-toolkit-commerce&tab=messages' ) ); exit; } public function forget() { $this->guard(); check_admin_referer( 'anar_toolkit_forget' ); $raw = isset( $_POST['phone'] ) && is_string( $_POST['phone'] ) ? sanitize_text_field( wp_unslash( $_POST['phone'] ) ) : ''; $phone = Identity::normalize( $raw ); if ( ! is_wp_error( $phone ) && 'sms' === $phone['channel'] ) { ( new Privacy( $this->repository, $this->settings ) )->erase_phone( $phone['identity'] ); } wp_safe_redirect( admin_url( 'admin.php?page=anar-toolkit-commerce&tab=privacy' ) ); exit; } private function input( $key, $label, $value, $type = 'text', $help = '' ) { $id = 'anar-commerce-' . sanitize_key( str_replace( array( '[', ']' ), '-', $key ) ); $direction = 'admin_phones' === $key || false !== strpos( $key, '][params' ) || false !== strpos( $key, '][template' ) ? 'ltr' : 'auto'; ?>

>
settings->all(); $flags = \Anar\Login\Infrastructure\Features::all(); $tab = \Anar\Login\Infrastructure\Features::current_tab(); $labels = Dashboard::labels(); ?>
repository ) )->render(); ?>

>

$labels['paid_customer'], 'paid_admin' => $labels['paid_admin'], 'recovery' => __( 'Cart and unpaid-order reminders', 'anar-toolkit' ), 'new_admin' => $labels['new_admin'], 'failed_admin' => $labels['failed_admin'], 'shipment_customer' => $labels['shipment_customer'], 'status_processing' => $labels['status_processing'], 'status_completed' => $labels['status_completed'], 'status_on-hold' => $labels['status_on-hold'], 'status_cancelled' => $labels['status_cancelled'], 'status_refunded' => $labels['status_refunded'] ) as $key => $label ) : if ( 'recovery' === $key ? ! $flags['recovery'] : ! $flags['orders'] ) { continue; } ?>


input( 'admin_phones', __( 'Administrator mobile numbers (maximum 5, one per line)', 'anar-toolkit' ), $value['admin_phones'], 'textarea' ); ?>


esc_attr( Settings::OPTION . '[recovery_page_id]' ), 'id' => 'anar-recovery-page', 'selected' => (int) $value['recovery_page_id'], 'show_option_none' => esc_html__( 'Default WooCommerce cart page', 'anar-toolkit' ), 'option_none_value' => 0, 'echo' => 0 ) ); echo wp_kses( $dropdown, array( 'select' => array( 'name' => true, 'id' => true ), 'option' => array( 'value' => true, 'selected' => true, 'class' => true ) ) ); ?>


input( 'start_hour', __( 'Recovery sending starts at hour (0–23)', 'anar-toolkit' ), $value['start_hour'], 'number' ); $this->input( 'end_hour', __( 'Recovery sending stops at hour (1–24)', 'anar-toolkit' ), $value['end_hour'], 'number' ); $this->input( 'daily_limit', __( 'Maximum reminders per phone in 24 hours (1–10)', 'anar-toolkit' ), $value['daily_limit'], 'number' ); $this->input( 'link_days', __( 'Recovery eligibility after cart activity, days (1–30)', 'anar-toolkit' ), $value['link_days'], 'number' ); $this->input( 'code_minutes', __( 'Recovery code validity, minutes (5–1440)', 'anar-toolkit' ), $value['code_minutes'], 'number' ); $this->input( 'retention', __( 'Local data retention, days (7–90)', 'anar-toolkit' ), $value['retention'], 'number' ); ?>

__( 'Generate recovery discounts', 'anar-toolkit' ), 'coupon_individual' => __( 'Do not combine with other coupons', 'anar-toolkit' ), 'coupon_exclude_sale' => __( 'Exclude sale products', 'anar-toolkit' ) ) as $key => $label ) : ?>

input( 'coupon_amount', __( 'Discount amount', 'anar-toolkit' ), $value['coupon_amount'], 'number' ); $this->input( 'coupon_minimum', __( 'Minimum cart amount', 'anar-toolkit' ), $value['coupon_minimum'], 'number' ); $this->input( 'coupon_stage', __( 'Offer from reminder stage (1–3)', 'anar-toolkit' ), $value['coupon_stage'], 'number' ); $this->input( 'coupon_hours', __( 'Discount validity in hours', 'anar-toolkit' ), $value['coupon_hours'], 'number' ); ?>

input( 'tracking_meta_key', __( 'Additional tracking-number meta key', 'anar-toolkit' ), $value['tracking_meta_key'] ); ?>

>

$event ) : if ( isset( $event['minutes'] ) ? ! $flags['recovery'] : ! $flags['orders'] ) { continue; } ?>

input( 'events][' . $key . '][minutes', __( 'Minutes after the last cart change (0 = disabled)', 'anar-toolkit' ), $event['minutes'], 'number' ); } $this->input( 'events][' . $key . '][message', __( 'Message text for a custom gateway / template reference', 'anar-toolkit' ), $event['message'], 'textarea', __( 'Built-in providers send the approved provider template, not this text. Keep its wording in sync with the approved template.', 'anar-toolkit' ) ); $this->input( 'events][' . $key . '][template', __( 'Approved provider template ID or name', 'anar-toolkit' ), $event['template'] ); $this->input( 'events][' . $key . '][params', __( 'Provider variables — one name={placeholder} per line', 'anar-toolkit' ), $event['params'], 'textarea', __( 'Kavenegar: token, token2, token3, token10, token20. IPPanel/Panelchi/MaxSMS/Faraz/SMS.ir: exact approved variable names. Meli Payamak: variables in template order. Custom gateway: uses the message text and its {message} transport placeholder.', 'anar-toolkit' ) ); ?>

{site} {name} {order_id} {total} {currency} {status} {tracking_number} {carrier} {tracking_url}