nqueue_script( 'pwsCheckout' ); } // Filters public function add_shipping_method( $methods ) { foreach ( self::$methods as $new_method ) { if ( class_exists( $new_method ) ) { $methods[ $new_method ] = $new_method; } } return $methods; } public function get_settings_general( $settings ) { foreach ( $settings as &$setting ) { if ( $setting['id'] == 'woocommerce_default_country' ) { $setting['type'] = 'pws_single_country'; } } return $settings; } public function iran_states( $states ) { $states['IR'] = PWS()->states(); return $states; } public function edit_state_city_columns_taxonomy( $original_columns ) { unset( $original_columns['posts'] ); $original_columns['city_id'] = "شناسه شهر"; return $original_columns; } public function edit_state_city_rows_taxonomy( $row, $column_name, $term_id ) { if ( 'city_id' === $column_name ) { return $term_id; } return $row; } public function edit_checkout_cities_field( $fields ) { $types = $this->types(); foreach ( $types as $type ) { if ( ! isset( $fields[ $type ][ $type . '_city' ] ) ) { continue; } $fields[ $type ][ $type . '_state' ]['placeholder'] = __( 'استان خود را انتخاب نمایید' ); $default_state_id = apply_filters( 'pws_default_state', 0, $type ); if ( $default_state_id ) { $fields[ $type ][ $type . '_state' ]['default'] = $default_state_id; } $class = is_array( $fields[ $type ][ $type . '_city' ]['class'] ) ? $fields[ $type ][ $type . '_city' ]['class'] : []; $fields[ $type ][ $type . '_city' ] = [ 'type' => $type . '_city', 'label' => __( 'شهر' ), 'placeholder' => __( 'لطفا ابتدا استان خود را انتخاب نمایید' ), 'required' => true, 'id' => $type . '_city', 'class' => apply_filters( 'pws_city_class', $class ), 'default' => apply_filters( 'pws_default_city', 0, $type, null ), 'priority' => apply_filters( 'pws_city_priority', $fields[ $type ][ $type . '_city' ]['priority'] ), ]; if ( ! PWS_Tapin::is_enable() ) { $fields[ $type ][ $type . '_district' ] = [ 'type' => $type . '_district', 'label' => __( 'محله' ), 'placeholder' => __( 'لطفا محله خود را انتخاب نمایید' ), 'required' => false, 'id' => $type . '_district', 'class' => apply_filters( 'pws_district_class', $class ), 'clear' => true, 'default' => apply_filters( 'pws_default_district', 0, $type, null ), 'priority' => apply_filters( 'pws_district_priority', $fields[ $type ][ $type . '_city' ]['priority'] + 1 ), ]; } } return $fields; } public function checkout_update_order_meta( $order_id ) { $order = wc_get_order( $order_id ); $types = $this->types(); $fields = [ 'state', 'city', 'district' ]; foreach ( $types as $type ) { foreach ( $fields as $field ) { $meta_key = "_{$type}_{$field}"; if ( method_exists( $order, "get{$meta_key}" ) ) { $term_id = $order->{"get{$meta_key}"}(); } else { $term_id = $order->get_meta( $meta_key ); } $term = get_term( intval( $term_id ) ); if ( ! is_wp_error( $term ) && ! is_null( $term ) ) { if ( method_exists( $order, "set{$meta_key}" ) ) { $order->{"set{$meta_key}"}( $term->name ); } else { $order->update_meta_data( "_{$type}_{$field}", $term->name ); } $order->update_meta_data( "_{$type}_{$field}_id", $term_id ); } } } if ( wc_ship_to_billing_address_only() ) { foreach ( $fields as $field ) { $meta_key = "_billing_{$field}"; if ( method_exists( $order, "get{$meta_key}" ) ) { $label = $order->{"get{$meta_key}"}(); } else { $label = $order->get_meta( "_billing_{$field}" ); } $id = $order->get_meta( "_billing_{$field}_id" ); $meta_key = "_shipping_{$field}"; if ( method_exists( $order, "set{$meta_key}" ) ) { $order->{"set{$meta_key}"}( $label ); } else { $order->update_meta_data( "_shipping_{$field}", $label ); } $order->update_meta_data( "_shipping_{$field}_id", $id ); } } $order->save(); } public function checkout_process() { $types = $this->types(); $fields = [ 'state' => 'استان', 'city' => 'شهر', 'district' => 'محله', ]; $type_label = [ 'billing' => 'صورتحساب', 'shipping' => 'حمل و نقل', ]; if ( ! isset( $_POST['ship_to_different_address'] ) && count( $types ) == 2 ) { unset( $types[1] ); } foreach ( $types as $type ) { $label = $type_label[ $type ]; foreach ( $fields as $field => $name ) { $key = $type . '_' . $field; if ( isset( $_POST[ $key ] ) && strlen( $_POST[ $key ] ) ) { $term_id = intval( $_POST[ $key ] ); if ( $term_id == 0 ) { $message = sprintf( 'لطفا %s %s خود را انتخاب نمایید.', $name, $label ); wc_add_notice( $message, 'error' ); continue; } /** @var WP_Term $term */ $term = get_term( $term_id, 'state_city' ); if ( is_wp_error( $term ) || is_null( $term ) ) { $message = sprintf( '%s %s انتخاب شده معتبر نمی باشد.', $name, $label ); wc_add_notice( $message, 'error' ); continue; } if ( $field == 'city' ) { $pkey = $type . '_state'; if ( isset( $_POST[ $pkey ] ) && ! empty( $_POST[ $pkey ] ) && $term->parent != $_POST[ $pkey ] ) { $message = sprintf( 'استان با شهر %s انتخاب شده همخوانی ندارند.', $label ); wc_add_notice( $message, 'error' ); continue; } } if ( $field == 'district' ) { $pkey = $type . '_city'; if ( isset( $_POST[ $pkey ] ) && ! empty( $_POST[ $pkey ] ) && $term->parent != $_POST[ $pkey ] ) { $message = sprintf( 'شهر با محله %s انتخاب شده همخوانی ندارند.', $label ); wc_add_notice( $message, 'error' ); } } } } } } public function checkout_cities_field( $field, $key, $args, $value ): string { $field_html = ''; $options = []; [ $type, $name ] = explode( '_', $args['type'] ); if ( $name == 'city' ) { $default_state_id = apply_filters( 'pws_default_state', 0, $type ); $state_id = WC()->checkout()->get_value( $type . '_state' ); if ( $state_id ) { $options = PWS()->cities( $state_id ); } elseif ( $default_state_id ) { $options = PWS()->cities( $default_state_id ); } } elseif ( $name == 'district' ) { $city_id = WC()->checkout()->get_value( $type . '_city' ); if ( $city_id ) { $options = get_terms( [ 'taxonomy' => 'state_city', 'hide_empty' => false, 'child_of' => $city_id, ] ); $options = array_column( $options, 'name', 'term_id' ); } } $ignore_classes = [ 'thwcfd-optional', 'thwcfd-field-wrapper', 'thwcfd-field-text', ]; $args['class'] = array_diff( $args['class'], $ignore_classes ); $args['class'][] = 'validate-required'; $required = ' *'; if ( is_string( $args['label_class'] ) ) { $args['label_class'] = [ $args['label_class'] ]; } if ( is_null( $value ) ) { $value = $args['default']; } $custom_attributes = []; if ( ! empty( $args['custom_attributes'] ) && is_array( $args['custom_attributes'] ) ) { foreach ( $args['custom_attributes'] as $attribute => $attribute_value ) { $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"'; } } if ( ! empty( $args['validate'] ) ) { foreach ( $args['validate'] as $validate ) { $args['class'][] = 'validate-' . $validate; } } $sort = $args['priority'] ? $args['priority'] : ''; $field_container = '

%3$s

'; if ( is_array( $options ) ) { if ( empty( $options ) && $name == 'district' ) { $field_container = ''; } $field .= ''; } if ( $args['label'] ) { $field_html .= ''; } $field_html .= $field; if ( $args['description'] ) { $field_html .= '' . esc_html( $args['description'] ) . ''; } $container_class = 'form-row ' . esc_attr( implode( ' ', $args['class'] ) ); $container_id = esc_attr( $args['id'] ) . '_field'; $after = ! empty( $args['clear'] ) ? '
' : ''; return sprintf( $field_container, $container_class, $container_id, $field_html ) . $after; } public function cart_shipping_packages( $packages ) { $type = 'billing'; if ( isset( $_POST['post_data'] ) ) { parse_str( $_POST['post_data'], $data ); } else { $data = WC()->checkout()->get_posted_data(); } if ( isset( $data['ship_to_different_address'] ) && in_array( 'shipping', $this->types() ) ) { $type = 'shipping'; } for ( $i = 0; $i < count( $packages ); $i ++ ) { $packages[ $i ]['destination']['district'] = strval( $data[ $type . '_district' ] ?? null ); } return $packages; } public function shipping_method_image( $label, $method ) { $method_id = str_replace( ':', '_', $method->id ); $option = get_option( "woocommerce_{$method_id}_settings" ); if ( isset( $option['img_url'] ) && ! empty( $option['img_url'] ) ) { return sprintf( '', $option['img_url'], $method_id, strtok( $method->id, ':' ) ) . $label; } return $label; } public function localisation_address_formats( $formats ) { $formats['IR'] = "{company}\n{first_name} {last_name}\n{country}\n{state}\n{city}\n{district}\n{address_1}\n{address_2}\n{postcode}"; return $formats; } public function order_formatted_shipping_address( $data, WC_Order $order ) { if ( is_array( $data ) ) { $data['district'] = $order->get_meta( '_shipping_district' ); } return $data; } public function order_formatted_billing_address( $data, WC_Order $order ) { if ( is_array( $data ) ) { $data['district'] = $order->get_meta( '_billing_district' ); } return $data; } public function formatted_address_replacements( $replace, $args ) { if ( ctype_alnum( $replace['{state}'] ) && strlen( $replace['{state}'] ) == 2 ) { $state = get_term_by( 'slug', $replace['{state}'], 'state_city' ); $replace['{state}'] = $state == false ? $replace['{state}'] : $state->name; } if ( ctype_alnum( $replace['{state}'] ) && strlen( $replace['{state}'] ) == 3 && function_exists( 'PW' ) ) { $replace['{state}'] = PW()->address->states[ $args['state'] ] ?? $args['state']; } if ( ctype_alnum( $replace['{state}'] ) && strlen( $replace['{state}'] ) == 3 ) { $state = get_term_by( 'slug', $replace['{state}'], 'state_city' ); $replace['{state}'] = $state == false ? $replace['{state}'] : $state->name; } if ( ctype_digit( $args['city'] ) ) { $city = get_term( $args['city'] ); $replace['{city}'] = is_wp_error( $city ) || is_null( $city ) ? $args['city'] : $city->name; } if ( isset( $args['district'] ) ) { $district = get_term( intval( $args['district'] ) ); $replace['{district}'] = is_wp_error( $district ) ? $args['district'] : $district->name; } else { $replace['{district}'] = null; } return $replace; } function my_account_my_address_formatted_address( $args, $customer_id, $name ) { $args['district'] = get_user_meta( $customer_id, $name . '_district', true ); return $args; } public function checkout_get_value( $value, $key ) { if ( ! in_array( $key, [ 'billing_district', 'shipping_district' ] ) ) { return $value; } return WC()->session->get( $key, 0 ); } // Functions public function types() { $types = [ 'billing' ]; if ( ! wc_ship_to_billing_address_only() ) { $types[] = 'shipping'; } return $types; } public static function states() { $states = get_transient( 'pws_states' ); if ( $states === false || count( (array) $states ) == 0 ) { $states = get_terms( [ 'taxonomy' => 'state_city', 'hide_empty' => false, 'parent' => 0, ] ); $states = wp_list_pluck( $states, 'name', 'term_id' ); uasort( $states, [ self::class, 'pws_sort_state' ] ); set_transient( 'pws_states', $states, DAY_IN_SECONDS ); } return apply_filters( 'pws_states', $states ); } public static function get_state( $state_id ) { $states = PWS()->states(); return $states[ $state_id ] ?? null; } public static function cities( $state_id ) { $cities = get_transient( 'pws_cities_' . $state_id ); if ( $cities === false || count( (array) $cities ) == 0 ) { $cities = get_terms( [ 'taxonomy' => 'state_city', 'hide_empty' => false, 'parent' => $state_id, ] ); if ( is_wp_error( $cities ) ) { $cities = []; } else { $cities = array_column( $cities, 'name', 'term_id' ); } set_transient( 'pws_cities_' . $state_id, $cities, DAY_IN_SECONDS ); } return apply_filters( 'pws_cities', $cities, $state_id ); } public static function get_city( $city_id ) { /** @var WP_Term $city */ $city = get_term( $city_id, 'state_city' ); return is_wp_error( $city ) || is_null( $city ) ? null : $city->name; } public function check_states_beside( $source, $destination ) { if ( $source == $destination ) { return 'in'; } $is_beside["AE"]["AW"] = true; $is_beside["AE"]["AR"] = true; $is_beside["AE"]["ZA"] = true; $is_beside["AW"]["AE"] = true; $is_beside["AW"]["KD"] = true; $is_beside["AW"]["ZA"] = true; $is_beside["AR"]["AE"] = true; $is_beside["AR"]["GI"] = true; $is_beside["AR"]["ZA"] = true; $is_beside["IS"]["CM"] = true; $is_beside["IS"]["LO"] = true; $is_beside["IS"]["KB"] = true; $is_beside["IS"]["MK"] = true; $is_beside["IS"]["QM"] = true; $is_beside["IS"]["SM"] = true; $is_beside["IS"]["KJ"] = true; $is_beside["IS"]["YA"] = true; $is_beside["IS"]["FA"] = true; $is_beside["AL"]["TE"] = true; $is_beside["AL"]["MK"] = true; $is_beside["AL"]["QZ"] = true; $is_beside["AL"]["MN"] = true; $is_beside["IL"]["BK"] = true; $is_beside["IL"]["LO"] = true; $is_beside["IL"]["KZ"] = true; $is_beside["BU"]["KB"] = true; $is_beside["BU"]["KZ"] = true; $is_beside["BU"]["FA"] = true; $is_beside["BU"]["HG"] = true; $is_beside["TE"]["AL"] = true; $is_beside["TE"]["MK"] = true; $is_beside["TE"]["QM"] = true; $is_beside["TE"]["MN"] = true; $is_beside["TE"]["SM"] = true; $is_beside["CM"]["KB"] = true; $is_beside["CM"]["KZ"] = true; $is_beside["CM"]["LO"] = true; $is_beside["CM"]["IS"] = true; $is_beside["KJ"]["SB"] = true; $is_beside["KJ"]["KE"] = true; $is_beside["KJ"]["YA"] = true; $is_beside["KJ"]["IS"] = true; $is_beside["KJ"]["SM"] = true; $is_beside["KJ"]["KV"] = true; $is_beside["KV"]["KJ"] = true; $is_beside["KV"]["KS"] = true; $is_beside["KV"]["SM"] = true; $is_beside["KS"]["KV"] = true; $is_beside["KS"]["GO"] = true; $is_beside["KS"]["SM"] = true; $is_beside["KZ"]["IL"] = true; $is_beside["KZ"]["BU"] = true; $is_beside["KZ"]["LO"] = true; $is_beside["KZ"]["KB"] = true; $is_beside["KZ"]["CM"] = true; $is_beside["ZA"]["GI"] = true; $is_beside["ZA"]["AR"] = true; $is_beside["ZA"]["AE"] = true; $is_beside["ZA"]["AW"] = true; $is_beside["ZA"]["KD"] = true; $is_beside["ZA"]["HD"] = true; $is_beside["ZA"]["QZ"] = true; $is_beside["SM"]["MN"] = true; $is_beside["SM"]["TE"] = true; $is_beside["SM"]["QM"] = true; $is_beside["SM"]["IS"] = true; $is_beside["SM"]["KS"] = true; $is_beside["SM"]["KV"] = true; $is_beside["SM"]["KJ"] = true; $is_beside["SB"]["KJ"] = true; $is_beside["SB"]["KE"] = true; $is_beside["SB"]["HG"] = true; $is_beside["FA"]["IS"] = true; $is_beside["FA"]["YA"] = true; $is_beside["FA"]["BU"] = true; $is_beside["FA"]["HG"] = true; $is_beside["FA"]["KB"] = true; $is_beside["FA"]["KE"] = true; $is_beside["QZ"]["ZA"] = true; $is_beside["QZ"]["HD"] = true; $is_beside["QZ"]["MK"] = true; $is_beside["QZ"]["AL"] = true; $is_beside["QZ"]["MN"] = true; $is_beside["QZ"]["GI"] = true; $is_beside["QM"]["TE"] = true; $is_beside["QM"]["MK"] = true; $is_beside["QM"]["SM"] = true; $is_beside["QM"]["IS"] = true; $is_beside["KD"]["AW"] = true; $is_beside["KD"]["BK"] = true; $is_beside["KD"]["HD"] = true; $is_beside["KD"]["ZA"] = true; $is_beside["KE"]["YA"] = true; $is_beside["KE"]["FA"] = true; $is_beside["KE"]["HG"] = true; $is_beside["KE"]["SB"] = true; $is_beside["KE"]["KJ"] = true; $is_beside["BK"]["KD"] = true; $is_beside["BK"]["HD"] = true; $is_beside["BK"]["LO"] = true; $is_beside["BK"]["IL"] = true; $is_beside["KB"]["CM"] = true; $is_beside["KB"]["KZ"] = true; $is_beside["KB"]["BU"] = true; $is_beside["KB"]["FA"] = true; $is_beside["KB"]["IS"] = true; $is_beside["GO"]["MN"] = true; $is_beside["GO"]["KS"] = true; $is_beside["GO"]["SM"] = true; $is_beside["GI"]["MN"] = true; $is_beside["GI"]["AR"] = true; $is_beside["GI"]["ZA"] = true; $is_beside["GI"]["QZ"] = true; $is_beside["LO"]["IL"] = true; $is_beside["LO"]["BK"] = true; $is_beside["LO"]["HD"] = true; $is_beside["LO"]["MK"] = true; $is_beside["LO"]["IS"] = true; $is_beside["LO"]["CM"] = true; $is_beside["LO"]["KZ"] = true; $is_beside["MN"]["GO"] = true; $is_beside["MN"]["SM"] = true; $is_beside["MN"]["TE"] = true; $is_beside["MN"]["AL"] = true; $is_beside["MN"]["IS"] = true; $is_beside["MN"]["QZ"] = true; $is_beside["MN"]["GI"] = true; $is_beside["MK"]["IS"] = true; $is_beside["MK"]["QM"] = true; $is_beside["MK"]["TE"] = true; $is_beside["MK"]["AL"] = true; $is_beside["MK"]["LO"] = true; $is_beside["MK"]["QZ"] = true; $is_beside["MK"]["HD"] = true; $is_beside["HG"]["BU"] = true; $is_beside["HG"]["FA"] = true; $is_beside["HG"]["KE"] = true; $is_beside["HG"]["SB"] = true; $is_beside["HD"]["BK"] = true; $is_beside["HD"]["LO"] = true; $is_beside["HD"]["KD"] = true; $is_beside["HD"]["MK"] = true; $is_beside["HD"]["QZ"] = true; $is_beside["HD"]["ZA"] = true; $is_beside["YA"]["FA"] = true; $is_beside["YA"]["KE"] = true; $is_beside["YA"]["KJ"] = true; $source = get_term( $source, 'state_city' ); $destination = get_term( $destination, 'state_city' ); if ( is_wp_error( $source ) || is_wp_error( $destination ) ) { return false; } $source = strval( $source->slug ?? null ); $destination = strval( $destination->slug ?? null ); return isset( $is_beside[ strtoupper( $source ) ][ strtoupper( $destination ) ] ) && $is_beside[ strtoupper( $source ) ][ strtoupper( $destination ) ] === true ? 'beside' : 'out'; } public function convert_currency_to_IRR( int $price ): int { switch ( get_woocommerce_currency() ) { case 'IRT': $price *= 10; break; case 'IRHR': $price *= 1000; break; case 'IRHT': $price *= 10000; break; } return $price; } public function convert_currency_from_IRR( int $price ): int { switch ( get_woocommerce_currency() ) { case 'IRT': $price /= 10; break; case 'IRHR': $price /= 1000; break; case 'IRHT': $price /= 10000; break; } return ceil( $price ); } // Backward compatibility public function convert_currency( int $price ): int { _doing_it_wrong( 'PWS()->convert_currency', 'Use PWS()->convert_currency_from_IRR', '4.0.0' ); return $this->convert_currency_from_IRR( $price ); } public function get_term_option( $term_id ): array { $option = get_option( 'nabik_taxonomy_' . $term_id, [] ); return apply_filters( 'pws_get_term_option', $option, $term_id ); } public function set_term_option( $term_id, array $option ) { $option = apply_filters( 'pws_set_term_option', $option, $term_id ); update_option( 'nabik_taxonomy_' . $term_id, $option ); } public function delete_term_option( $term_id ) { delete_option( 'nabik_taxonomy_' . $term_id ); } public function get_terms_option( $term_id ) { $options = wp_cache_get( 'get_terms_option_' . $term_id, 'pws' ); if ( false !== $options ) { return $options; } $ancestors = get_ancestors( $term_id, 'state_city' ); if ( empty( $ancestors ) ) { return []; } array_unshift( $ancestors, $term_id ); $options = array_map( [ $this, 'get_term_option' ], $ancestors ); wp_cache_set( 'get_terms_option_' . $term_id, $options, 'pws' ); return $options; } public static function get_option( string $option_name, $default = null ) { [ $section, $option ] = explode( '.', $option_name ); $options = get_option( 'pws_' . $section, [] ); if ( isset( $options[ $option ] ) ) { return $options[ $option ]; } return $default; } public static function set_option( string $option_name, $value ) { [ $section, $option ] = explode( '.', $option_name ); $options = get_option( 'pws_' . $section, [] ); $options = empty( $options ) ? [] : $options; $options[ $option ] = $value; update_option( 'pws_' . $section, $options ); } public function log( ...$params ) { $log = ''; $date = wp_date( 'Y-m-d' ); if ( defined( 'WC_LOG_DIR' ) ) { $log_file = WC_LOG_DIR . "pws-{$date}.log"; } else { $log_file = WP_CONTENT_DIR . "pws-{$date}.log"; } foreach ( $params as $message ) { $log .= wp_date( '[Y-m-d H:i:s] ' ); if ( is_array( $message ) || is_object( $message ) ) { $log .= print_r( $message, true ); } elseif ( is_bool( $message ) ) { $log .= ( $message ? 'true' : 'false' ); } else { $log .= $message; } $log .= PHP_EOL; } file_put_contents( $log_file, $log, FILE_APPEND ); } public static function pws_sort_state( $a, $b ) { if ( $a == $b ) { return 0; } $states = [ 'آذربایجان شرقی', 'آذربایجان غربی', 'اردبیل', 'اصفهان', 'البرز', 'ایلام', 'بوشهر', 'تهران', 'چهارمحال و بختیاری', 'خراسان جنوبی', 'خراسان رضوی', 'خراسان شمالی', 'خوزستان', 'زنجان', 'سمنان', 'سیستان و بلوچستان', 'فارس', 'قزوین', 'قم', 'کردستان', 'کرمان', 'کرمانشاه', 'کهگیلویه و بویراحمد', 'گلستان', 'گیلان', 'لرستان', 'مازندران', 'مرکزی', 'هرمزگان', 'همدان', 'یزد', ]; $a = str_replace( [ 'ي', 'ك', 'ة' ], [ 'ی', 'ک', 'ه' ], $a ); $b = str_replace( [ 'ي', 'ك', 'ة' ], [ 'ی', 'ک', 'ه' ], $b ); $a_key = array_search( trim( $a ), $states ); $b_key = array_search( trim( $b ), $states ); return $a_key < $b_key ? - 1 : 1; } public function pws_pro_url( $source ): string { return 'https://yun.ir/pws-pro?utm_source=' . esc_attr( $source ); } }