芝麻web文件管理V1.00
编辑当前文件:/home/freeclou/optimyar/wp-content/plugins/wp-parsidate/includes/plugins/woocommerce.php
include_files(); add_filter( 'wpp_plugins_compatibility_settings', array( $this, 'add_settings' ) ); add_action( 'before_woocommerce_init', function() { if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) { \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', WP_PARSI_ROOT, true ); } } ); if ( class_exists( 'WooCommerce' ) && get_locale() === 'fa_IR' ) { if ( wpp_is_active( 'woo_per_price' ) ) { add_filter( 'wc_price', 'fix_number' ); add_filter( 'woocommerce_get_price_html', 'fix_number' ); add_filter( 'woocommerce_cart_item_price', 'fix_number' ); add_filter( 'woocommerce_cart_item_subtotal', 'fix_number' ); add_filter( 'woocommerce_cart_subtotal', 'fix_number' ); add_filter( 'woocommerce_cart_totals_coupon_html', 'fix_number' ); add_filter( 'woocommerce_cart_shipping_method_full_label', 'fix_number' ); add_filter( 'woocommerce_cart_total', 'fix_number' ); } if ( wpp_is_active( 'persian_date' ) ) { add_action( 'wp_head', array( $this, 'fix_wc_date_time_direction' ) ); add_filter( 'woocommerce_email_styles', array( $this, 'fix_emails_order_date_direction' ), 9999, 2 ); // Jalali datepicker add_action( 'admin_enqueue_scripts', array( $this, 'wc_jalali_datepicker_assets' ) ); // Convert order_date using js add_action( 'woocommerce_process_shop_order_meta', array( $this, 'change_order_date_on_save_order_object' ), 1000 ); add_filter( 'woocommerce_process_product_meta', array( $this, 'validate_non_variable_product_dates' ), 1000 ); add_action( 'woocommerce_ajax_save_product_variations', array( $this, 'validate_variable_product_dates' ), 1000 ); add_action( 'woocommerce_process_shop_coupon_meta', array( $this, 'validate_wc_coupons_date' ), 1000 ); add_filter( 'get_post_metadata', array( $this, 'change_wc_order_date_and_coupon_expires' ), 10, 4 ); add_filter( 'manage_edit-shop_coupon_columns', array( $this, 'remove_wc_coupon_expiry_date_column' ) ); add_action( 'manage_shop_coupon_posts_custom_column', array( $this, 'add_jalali_expiry_date_column' ), 10, 2 ); add_action( 'admin_footer', array( $this, 'fix_show_created_order_date' ) ); add_action( 'admin_init', array( $this, 'change_wc_report_dates' ), 1000 ); } add_filter( 'woocommerce_checkout_process', array( $this, 'accept_persian_numbers_in_checkout' ), 20 ); add_filter( 'woocommerce_checkout_posted_data', array( $this, 'convert_non_persian_values_in_checkout' ) ); if ( wpp_is_active( 'woo_validate_postcode' ) ) { add_filter( 'woocommerce_validate_postcode', array( $this, 'validate_postcode' ), 10, 3 ); } if ( wpp_is_active( 'woo_validate_phone' ) ) { add_action( 'woocommerce_after_checkout_validation', array( $this, 'validate_phone_number' ), 10, 2 ); } } } /** * Returns an instance of class * * @return WPP_WooCommerce */ public static function getInstance() { if ( self::$instance == null ) { self::$instance = new WPP_WooCommerce(); } return self::$instance; } /** * Includes files for WooCommerce payment gateways * * @return void * @since 4.0.1 */ public function include_files() { if ( wpp_is_active( 'woo_dropdown_cities' ) ) { include_once WP_PARSI_DIR . 'includes/plugins/wc-cities/wc-city-select.php'; } require_once( WP_PARSI_DIR . 'includes/plugins/wc-gateways/wc-gateways.php' ); } /** * Adds settings for toggle fixing * * @param array $old_settings Old settings * * @return array New settings * @since 4.0.0 */ public function add_settings( $old_settings ) { $settings = apply_filters( 'wpp_woocommerce_settings', array( 'woocommerce' => array( 'id' => 'woocommerce', 'name' => __( 'WooCommerce', 'wp-parsidate' ), 'type' => 'header', ), 'woo_per_price' => array( 'id' => 'woo_per_price', 'name' => __( 'Fix prices', 'wp-parsidate' ), 'type' => 'checkbox', 'options' => 1, 'std' => 0, ), 'woo_accept_per_postcode' => array( 'id' => 'woo_accept_per_postcode', 'name' => __( 'Fix persian postcode', 'wp-parsidate' ), 'type' => 'checkbox', 'options' => 1, 'std' => 0, ), 'woo_dropdown_cities' => array( 'id' => 'woo_dropdown_cities', 'name' => __( 'Display cities as a drop-down list', 'wp-parsidate' ), 'type' => 'checkbox', 'options' => 1, 'std' => 0, ), 'woo_accept_per_phone' => array( 'id' => 'woo_accept_per_phone', 'name' => __( 'Fix persian phone', 'wp-parsidate' ), 'type' => 'checkbox', 'options' => 1, 'std' => 0, ), 'woo_validate_postcode' => array( 'id' => 'woo_validate_postcode', 'name' => __( 'Postcode validation', 'wp-parsidate' ), 'type' => 'checkbox', 'options' => 1, 'std' => 0, ), 'woo_validate_phone' => array( 'id' => 'woo_validate_phone', 'name' => __( 'Phone number validation', 'wp-parsidate' ), 'type' => 'checkbox', 'options' => 1, 'std' => 0, ), ) ); return array_merge( $old_settings, $settings ); } /** * enqueue jalali date picker assets * * @since 4.0.0 */ public function wc_jalali_datepicker_assets() { global $wpp_months_name; $screen = get_current_screen(); $current_screen = $screen->id; $suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) || wpp_is_active( 'dev_mode' ) ? '' : '.min'; $allowed_screens = array( 'product', 'shop_order', 'woocommerce_page_wc-orders', 'woocommerce_page_wc-reports', 'shop_coupon', ); if ( wpp_is_active( 'persian_date' ) && in_array( $current_screen, $allowed_screens ) ) { wp_enqueue_script( 'wpp_jalali_datepicker', WP_PARSI_URL . 'assets/js/jalalidatepicker.min.js', array( 'jquery-ui-datepicker' ), WP_PARSI_VER ); wp_enqueue_style( 'wpp_jalali_datepicker', WP_PARSI_URL . "assets/css/jalalidatepicker$suffix.css", null, WP_PARSI_VER ); do_action( 'wpp_jalali_datepicker_enqueued', 'wc' ); } } /** * Convert order date to gregorian before saved at database * * @param $order_id * * @throws WC_Data_Exception * @since 5.0.2 */ public function change_order_date_on_save_order_object( $order_id ) { $order_date = wc_get_post_data_by_key( 'order_date' ); if ( empty( $order_date ) ) { return; } $order = wc_get_order( $order_id ); if ( ! $order ) { return; } $hour = str_pad( (int) wc_get_post_data_by_key( 'order_date_hour' ), 2, '0', STR_PAD_LEFT ); $minute = str_pad( (int) wc_get_post_data_by_key( 'order_date_minute' ), 2, '0', STR_PAD_LEFT ); $second = str_pad( (int) wc_get_post_data_by_key( 'order_date_second' ), 2, '0', STR_PAD_LEFT ); $time_stamp = "$order_date $hour:$minute:$second"; $fixed_date = gregdate( 'Y-m-d H:i:s', $time_stamp ); $date = empty( $order_date ) ? current_time( 'mysql' ) : gmdate( 'Y-m-d H:i:s', strtotime( $fixed_date ) ); $order->set_date_created( $date ); $order->save(); } /** * Changes order_date field in "Edit order" screen using JS * * @since 4.0.0 */ public function fix_show_created_order_date() { $current_screen = $this->get_current_screen(); if ( 'edit_order' === $current_screen ) { if ( ! $this->is_hpos_enabled() ) { global $post; if ( ! $post ) { $jalali_date = parsidate( 'Y-m-d', date( 'Y-m-d' ), 'eng' ); } else { $jalali_date = parsidate( 'Y-m-d', date( 'Y-m-d', strtotime( $post->post_date ) ), 'eng' ); } } else { global $theorder; if ( ! $theorder ) { $jalali_date = parsidate( 'Y-m-d', date( 'Y-m-d' ), 'eng' ); } else { $jalali_date = parsidate( 'Y-m-d', ! is_null( $theorder->get_date_created() ) ? $theorder->get_date_created()->getOffsetTimestamp() : '', 'eng' ); } } wc_enqueue_js( '$("input[name=order_date]").val("' . $jalali_date . '")' ); } elseif ( 'legacy_report' === $current_screen ) { $jalali_start_date = ! empty( $_GET['start_date'] ) ? parsidate( 'Y-m-d', date( 'Y-m-d', strtotime( $_GET['start_date'] ) ), 'eng' ) : ''; $jalali_end_date = ! empty( $_GET['end_date'] ) ? parsidate( 'Y-m-d', date( 'Y-m-d', strtotime( $_GET['end_date'] ) ), 'eng' ) : ''; wc_enqueue_js( '$("input[name=start_date]").val("' . $jalali_start_date . '");$("input[name=end_date]").val("' . $jalali_end_date . '");' ); } elseif ( 'product' === $current_screen ) { global $post; if ( ! $post ) { return; } $product = wc_get_product( $post->ID ); if ( ! $product ) { return; } if ( ! $product->is_type( 'variable' ) ) { $sale_price_dates_from_timestamp = $product->get_date_on_sale_from( 'edit' ) ? $product->get_date_on_sale_from( 'edit' )->getOffsetTimestamp() : false; $sale_price_dates_to_timestamp = $product->get_date_on_sale_to( 'edit' ) ? $product->get_date_on_sale_to( 'edit' )->getOffsetTimestamp() : false; $sale_price_dates_from = $sale_price_dates_from_timestamp ? eng_number( date_i18n( 'Y-m-d', $sale_price_dates_from_timestamp ) ) : ''; $sale_price_dates_to = $sale_price_dates_to_timestamp ? eng_number( date_i18n( 'Y-m-d', $sale_price_dates_to_timestamp ) ) : ''; wc_enqueue_js( '$("#_sale_price_dates_from").val("' . $sale_price_dates_from . '");$("#_sale_price_dates_to").val("' . $sale_price_dates_to . '");' ); } else { $dates = array(); $loop = 0; $available_variations = $product->get_available_variations(); foreach ( $available_variations as $variation ) { $variation_id = $variation['variation_id']; $variation_obj = new WC_Product_Variation( $variation_id ); $sale_price_dates_from_timestamp = $variation_obj->get_date_on_sale_from( 'edit' ) ? $variation_obj->get_date_on_sale_from( 'edit' )->getOffsetTimestamp() : false; $sale_price_dates_to_timestamp = $variation_obj->get_date_on_sale_to( 'edit' ) ? $variation_obj->get_date_on_sale_to( 'edit' )->getOffsetTimestamp() : false; $sale_price_dates_from = $sale_price_dates_from_timestamp ? eng_number( date_i18n( 'Y-m-d', $sale_price_dates_from_timestamp ) ) : ''; $sale_price_dates_to = $sale_price_dates_to_timestamp ? eng_number( date_i18n( 'Y-m-d', $sale_price_dates_to_timestamp ) ) : ''; $dates[ $loop ] = array( 'start' => esc_attr( $sale_price_dates_from ), 'end' => esc_attr( $sale_price_dates_to ), ); $loop ++; } if ( ! empty( $dates ) ) { wc_enqueue_js( 'const wppVariationsDates = ' . wp_json_encode( $dates ) . ' $("#woocommerce-product-data").on("woocommerce_variations_loaded", function(e) { wppVariationsDates.forEach((date, index) => { $(`input[name="variable_sale_price_dates_from[${index}]"]`).val(date.start) $(`input[name="variable_sale_price_dates_to[${index}]"]`).val(date.end) }) })' ); } } } } /** * Convert selected Jalali dates to gregorian on woocommerce save non-variable products * * @param $product_id $ * * @return void * @since 4.0.0 */ public function validate_non_variable_product_dates( $product_id ) { $props = array(); if ( isset( $_POST['_sale_price_dates_from'] ) ) { $date_on_sale_from = eng_number( wc_get_post_data_by_key( '_sale_price_dates_from' ) ); if ( ! empty( $date_on_sale_from ) ) { $props['date_on_sale_from'] = date( 'Y-m-d 00:00:00', strtotime( gregdate( 'Y-m-d', $date_on_sale_from ) ) ); } } if ( isset( $_POST['_sale_price_dates_to'] ) ) { $date_on_sale_to = eng_number( wc_get_post_data_by_key( '_sale_price_dates_to' ) ); if ( ! empty( $date_on_sale_to ) ) { $props['date_on_sale_to'] = date( 'Y-m-d 23:59:59', strtotime( gregdate( 'Y-m-d', $date_on_sale_to ) ) ); } } if ( empty( $props ) ) { return; } $product = wc_get_product( $product_id ); $product->set_props( $props ); $product->save(); } /** * Changes coupon expire date on load coupon data * We use $wpdb to avoid creating an infinite loop * * @param $metadata * @param $object_id * @param $meta_key * @param $single * * @return int|mixed|string * * @since 4.0.0 */ public function change_wc_order_date_and_coupon_expires( $metadata, $object_id, $meta_key, $single ) { global $wpdb; $post_type = get_post_type( $object_id ); $action = isset( $_GET['action'] ) && $_GET['action'] === 'edit'; if ( $action && 'shop_coupon' === $post_type && 'date_expires' === $meta_key ) { $metadata = $wpdb->get_var( $wpdb->prepare( " SELECT meta_value From $wpdb->postmeta WHERE post_id = %d AND meta_key = '%s' ", $object_id, $meta_key ) ); if ( ! empty( $metadata ) ) { return parsidate( 'Y-m-d', $metadata, 'eng' ); } } return $metadata; } /** * Changes gregorian dates to Jalali date on wc report screen * * @since 4.0.0 */ public function change_wc_report_dates() { if ( ! empty( $_GET['page'] ) && 'wc-reports' === esc_attr( $_GET['page'] ) ) { if ( ! empty( $_GET['start_date'] ) ) { $_GET['start_date'] = gregdate( 'Y-m-d', eng_number( wc_clean( wp_unslash( $_GET['start_date'] ) ) ) ); } if ( ! empty( $_GET['end_date'] ) ) { $_GET['end_date'] = gregdate( 'Y-m-d', eng_number( wc_clean( wp_unslash( $_GET['end_date'] ) ) ) ); } } } /** * Converts variations selected Jalali dates to gregorian * * @param $product_id * * @since 4.0.0 */ public function validate_variable_product_dates( $product_id ) { if ( ! isset( $_POST['variable_post_id'] ) ) { return; } $max_loop = max( array_keys( wp_unslash( $_POST['variable_post_id'] ) ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $parent = wc_get_product( $product_id ); $data_store = $parent->get_data_store(); $data_store->sort_all_product_variations( $parent->get_id() ); for ( $i = 0; $i <= $max_loop; $i ++ ) { if ( ! isset( $_POST['variable_post_id'][ $i ] ) ) { continue; } $variation_id = absint( $_POST['variable_post_id'][ $i ] ); $variation = wc_get_product_object( 'variation', $variation_id ); $props = array(); if ( isset( $_POST['variable_sale_price_dates_from'][ $i ] ) ) { $date_on_sale_from = eng_number( wc_clean( wp_unslash( $_POST['variable_sale_price_dates_from'][ $i ] ) ) ); if ( ! empty( $date_on_sale_from ) ) { $props['date_on_sale_from'] = gregdate( 'Y-m-d 00:00:00', $date_on_sale_from ); } } if ( isset( $_POST['variable_sale_price_dates_to'][ $i ] ) ) { $date_on_sale_to = eng_number( wc_clean( wp_unslash( $_POST['variable_sale_price_dates_to'][ $i ] ) ) ); if ( ! empty( $date_on_sale_to ) ) { $props['date_on_sale_to'] = gregdate( 'Y-m-d 23:59:59', $date_on_sale_to ); } } if ( empty( $props ) ) { continue; } $variation->set_props( $props ); $variation->save(); } } public function validate_wc_coupons_date( $coupon_id ) { $expiry_date = eng_number( wc_get_post_data_by_key( 'expiry_date' ) ); if ( empty( $expiry_date ) ) { return; } $coupon = new WC_Coupon( $coupon_id ); $fixed_expiry_date = strtotime( gregdate( 'Y-m-d 23:59:59', $expiry_date ) ); $coupon->set_props( array( 'date_expires' => $fixed_expiry_date ) ); $coupon->save(); } /** * Remove default wc expire date column in coupons screen and add our custom column * * @param $columns * * @return mixed * @since 4.0.0 */ public function remove_wc_coupon_expiry_date_column( $columns ) { unset( $columns['expiry_date'] ); $columns['wpp_expiry_date'] = __( 'Expiry date', 'woocommerce' ); return $columns; } /** * Fill our custom date expires column value * * @param $column * @param $postid * * @since 4.0.0 */ public function add_jalali_expiry_date_column( $column, $postid ) { if ( $column === 'wpp_expiry_date' ) { $date = get_post_meta( $postid, 'date_expires', true ); echo ! empty( $date ) ? parsidate( 'Y-m-d', $date ) : '–'; } } /** * Convert Non-Persian Values in checkout to Persian * * @method convert_non_persian_values_in_checkout * @param array $data * * @return array modified $data * @version 1.0.0 * @since 4.0.1 */ public function convert_non_persian_values_in_checkout( $data ) { $persian_fields = array( 'billing_postcode', 'billing_city', 'billing_address_1', 'billing_address', 'billing_address_2', 'billing_state', 'shipping_postcode', 'shipping_city', 'shipping_address_1', 'shipping_address', 'shipping_address_2', 'shipping_state', 'billing_first_name', 'billing_last_name', 'billing_company', 'billing_email', 'shipping_first_name', 'shipping_last_name', 'shipping_company', ); /** * here we pass those fields we want to convert from arabic to persian * other developers can hook into this filter and add their fields too * * @var array $persian_fields */ $supported_persian_fields = apply_filters( "wpp_woocommerce_checkout_persian_fields", $persian_fields ); foreach ( $supported_persian_fields as $field ) { if ( isset( $data[ $field ] ) ) { $data[ $field ] = $this->fix_persian_characters( $data[ $field ] ); } } return apply_filters( "wpp_woocommerce_checkout_modified_persian_fields", $data ); } /** * replace Arabic characters with equivalent character in Persian * * @method fix_persian_characters * @param string $string * * @return string filtered $string * @version 1.0.0 * @since 4.0.1 */ public static function fix_persian_characters( $string ) { $characters = array( 'ك' => 'ک', 'دِ' => 'د', 'بِ' => 'ب', 'زِ' => 'ز', 'ذِ' => 'ذ', 'شِ' => 'ش', 'سِ' => 'س', 'ى' => 'ی', 'ي' => 'ی', '١' => '۱', '٢' => '۲', '٣' => '۳', '٤' => '۴', '٥' => '۵', '٦' => '۶', '٧' => '۷', '٨' => '۸', '٩' => '۹', '٠' => '۰', ); $characters = apply_filters( "wpp_arabic_persian_characters_list", $characters ); return str_replace( array_keys( $characters ), array_values( $characters ), $string ); } /** * Fix persian postal code & phone numbers in WooCommerce checkout * * @since 4.1.0 */ public function accept_persian_numbers_in_checkout() { if ( wpp_is_active( 'woo_accept_per_postcode' ) ) { if ( isset( $_POST['billing_postcode'] ) ) { $_POST['billing_postcode'] = eng_number( wc_get_post_data_by_key( 'billing_postcode' ) ); } if ( isset( $_POST['shipping_postcode'] ) ) { $_POST['shipping_postcode'] = eng_number( wc_get_post_data_by_key( 'shipping_postcode' ) ); } } if ( wpp_is_active( 'woo_accept_per_phone' ) ) { if ( isset( $_POST['billing_phone'] ) ) { $_POST['billing_phone'] = eng_number( wc_get_post_data_by_key( 'billing_phone' ) ); } if ( isset( $_POST['shipping_phone'] ) ) { $_POST['shipping_phone'] = eng_number( wc_get_post_data_by_key( 'shipping_phone' ) ); } } } /** * Validate Iranian customer postal code * * @param $valid * @param $postcode * @param $country * * @return bool|mixed */ public function validate_postcode( $valid, $postcode, $country ) { if ( 'IR' !== $country ) { return $valid; } // based on https://github.com/VahidN/DNTPersianUtils.Core/blob/34b9ae00ad3584bc9ef34033c6402d1b8ae7a148/src/DNTPersianUtils.Core/Validators/IranCodesUtils.cs#L13 return (bool) preg_match( '/\b(?!(\d)\1{3})[13-9]{4}[1346-9][013-9]{5}\b/', $postcode ); } /** * @param $data * @param $errors * * @return false|void */ public function validate_phone_number( $data, $errors ) { // This pattern ensures the phone number follows the specified structure for both mobile and landline numbers if ( preg_match( '/^(0|0098|\+98)?(9\d{9}|[1-8]\d{9,10})$/', eng_number( wc_get_post_data_by_key( 'billing_phone' ) ) ) ) { return false; } $errors->add( 'validation', __( '
Phone number
is invalid.', 'wp-parsidate' ) ); } /** * Fixes jalali order date direction in WooCommerce emails (Issue: https://github.com/wordpress-parsi/wp-parsidate/issues/154) * * @param $style * @param $email * * @return string * @since 5.0.0 */ public function fix_emails_order_date_direction( $style, $email ) { return $style . 'time{unicode-bidi:embed!important}'; } /** * Fixes jalali order date direction in WooCommerce my-account endpoints (Issue: https://github.com/wordpress-parsi/wp-parsidate/issues/154) * * @return void * @since 5.0.0 */ public function fix_wc_date_time_direction() { if ( is_woocommerce() || is_wc_endpoint_url() || is_cart() || is_checkout() ) { echo ''; } } /** * Check WooCommerce HPOS enabled or not * * @return bool */ private function is_hpos_enabled() { return class_exists( '\Automattic\WooCommerce\Utilities\OrderUtil' ) && \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled(); } /** * Check the current screen is the WooCommerce order edit page * * @return string */ private function get_current_screen() { if ( 'woocommerce_before_order_object_save' === current_action() ) { global $pagenow; if ( $this->is_hpos_enabled() ) { return isset( $_POST['post_ID'] ) && 'shop_order' === get_post_type( $_POST['post_ID'] ) && ! empty( $_POST['order_date'] ) ? 'edit_order' : ''; } return is_admin() && 'post.php' === $pagenow && isset( $_POST['post_type'] ) && 'shop_order' === $_POST['post_type'] && ! empty( $_POST['order_date'] ) ? 'edit_order' : ''; } elseif ( 'admin_footer' === current_action() ) { $screen = get_current_screen(); $current_screen = $screen->id; if ( in_array( $current_screen, array( 'shop_order', 'woocommerce_page_wc-orders' ) ) ) { return 'edit_order'; } elseif ( 'woocommerce_page_wc-reports' === $current_screen ) { return 'legacy_report'; } return $current_screen; } return null; } } return WPP_WooCommerce::getInstance(); }