shipping_dhl_settings = PR_DHL()->get_shipping_dhl_settings(); $this->init_hooks(); $this->preferred_services = [ 'pr_dhl_preferred_day' => esc_html__('Delivery Day', 'dhl-for-woocommerce'), 'pr_dhl_preferred_location_neighbor' => esc_html__('Preferred Location or Neighbor', 'dhl-for-woocommerce'), 'pr_dhl_preferred_location' => esc_html__('Preferred Location Address', 'dhl-for-woocommerce'), 'pr_dhl_preferred_neighbour_name' => esc_html__('Preferred Neighbor Name', 'dhl-for-woocommerce'), 'pr_dhl_preferred_neighbour_address' => esc_html__('Preferred Neighbor Address', 'dhl-for-woocommerce'), ]; $this->preferred_location_neighbor = [ 'preferred_location' => esc_html__('Location', 'dhl-for-woocommerce'), 'preferred_neighbor' => esc_html__('Neighbor', 'dhl-for-woocommerce'), ]; $this->cdp_service = [ 'pr_dhl_cdp_delivery' => esc_html__('Delivery option', 'dhl-for-woocommerce'), ]; } public function init_hooks() { add_action('wp_enqueue_scripts', [$this, 'load_styles_scripts']); if ($this->is_tracking_enabled() && ($this->is_preferredservice_enabled() || $this->is_parcelfinder_enabled() || $this->is_cdp_enabled())) { // Add DHL meta tag add_action('wp_head', [$this, 'dhl_add_meta_tags']); } if ($this->is_cdp_enabled()) { add_action('woocommerce_review_order_after_shipping', [$this, 'add_cdp_fields']); add_action('woocommerce_checkout_order_processed', [$this, 'process_cdp_fields'], 10, 2); } if ($this->is_preferredservice_enabled()) { add_action('woocommerce_review_order_after_shipping', [$this, 'add_preferred_fields']); add_action('woocommerce_cart_calculate_fees', [$this, 'add_cart_fees']); add_action('woocommerce_checkout_process', [$this, 'verify_preferred_services_fields']); add_action('woocommerce_checkout_order_processed', [$this, 'process_dhl_preferred_fields'], 10, 2); add_filter('woocommerce_get_order_item_totals', [$this, 'display_dhl_preferred_free_services_values'], 10, 2); } // Parcel finder hooks if ($this->is_parcelfinder_enabled()) { // add_action( 'woocommerce_after_checkout_billing_form', array( $this, 'add_parcel_finder_btn' ) ); add_action('woocommerce_before_checkout_shipping_form', [$this, 'add_registration_text_above_shipping_fields']); add_action('woocommerce_before_checkout_shipping_form', [$this, 'add_parcel_finder_btn']); add_action('woocommerce_after_checkout_form', [$this, 'add_parcel_finder_form']); add_action('wp_ajax_wc_shipment_dhl_parcelfinder_search', [$this, 'call_parcel_finder']); add_action('wp_ajax_nopriv_wc_shipment_dhl_parcelfinder_search', [$this, 'call_parcel_finder']); add_filter('woocommerce_checkout_fields', [$this, 'add_postnum_field'], 101); add_action('woocommerce_checkout_process', [$this, 'validate_post_number']); add_action('woocommerce_checkout_order_processed', [$this, 'clear_post_number_for_regular_address'], 10, 2); // add_action( 'woocommerce_process_checkout_field_shipping_dhl_postnum_ps', array( $this, 'validate_post_number_required' ) ); add_filter('woocommerce_order_formatted_shipping_address', [$this, 'display_post_number'], 10, 2); add_filter('woocommerce_localisation_address_formats', [$this, 'set_format_post_number']); add_filter('woocommerce_formatted_address_replacements', [$this, 'add_format_post_number'], 10, 2); add_filter('woocommerce_admin_shipping_fields', [$this, 'admin_order_add_postnum_field'], 10); } if ($this->is_email_notification_enabled()) { $pos = apply_filters('pr_shipping_dhl_email_notification_position', 'woocommerce_review_order_before_submit'); add_action($pos, [$this, 'add_email_notification_checkbox'], 10); add_action('woocommerce_checkout_order_processed', [$this, 'process_email_notification_fields'], 30, 2); } } /** * Add DHL registration link above the shipping fields. */ public function add_registration_text_above_shipping_fields(): void { $link = DHL_GERMAN_REGISTRATION_LINK; if (get_locale() === 'en_US') { $link = DHL_ENGLISH_REGISTRATION_LINK; } echo '
'; echo sprintf(esc_html__('For deliveries to DHL Parcel Lockers you have to %1screate a DHL account%2s and get a Post Number.', 'dhl-for-woocommerce'), '', ''); echo '
'; } /** * is_using_checkout_block * * @param array is_using_checkout_block local fields. * @return bool */ protected function is_using_checkout_block() { $checkout_page_id = wc_get_page_id('checkout'); $has_block_checkout = $checkout_page_id && has_block('woocommerce/checkout', $checkout_page_id); if ($has_block_checkout) { $is_using_checkout_block = true; } else { $is_using_checkout_block = false; } return $is_using_checkout_block; } protected function is_tracking_enabled() { return false; } protected function is_preferredservice_enabled() { if ((isset($this->shipping_dhl_settings['dhl_preferred_day']) && ($this->shipping_dhl_settings['dhl_preferred_day'] == 'yes')) || (isset($this->shipping_dhl_settings['dhl_preferred_location']) && ($this->shipping_dhl_settings['dhl_preferred_location'] == 'yes')) || (isset($this->shipping_dhl_settings['dhl_preferred_neighbour']) && ($this->shipping_dhl_settings['dhl_preferred_neighbour'] == 'yes'))) { return true; } else { return false; } } protected function is_cdp_enabled() { if (isset($this->shipping_dhl_settings['dhl_closest_drop_point']) && ($this->shipping_dhl_settings['dhl_closest_drop_point'] === 'yes')) { return true; } return false; } public function dhl_add_meta_tags() { echo ''; } /** * Localization for NL address fields. * * @param array $checkout_fields Checkout fields. * @return array */ public function get_country_locale($checkout_fields) { if ($this->is_using_checkout_block()) { $fields_to_order = [ 'pr-dhl/address_type' => ['priority' => 1], 'first_name' => ['priority' => 3], 'last_name' => ['priority' => 4], 'company' => ['priority' => 5], 'country' => ['priority' => 6], 'postcode' => ['priority' => 7], 'shipping_pr_dhl/postnum' => ['priority' => 8], ]; } foreach ($fields_to_order as $field_key => $field) { foreach ($field as $override => $value) { $checkout_fields['DE'][$field_key][$override] = $value; } } /** * Hide extra fields from the other countries . */ $countries_codes = array_keys(WC()->countries->get_countries()); foreach ($countries_codes as $country_code) { if ($country_code !== 'DE') { $checkout_fields[$country_code]['pr-dhl/address_type']['hidden'] = true; $checkout_fields[$country_code]['pr-dhl/address_type']['required'] = false; $checkout_fields[$country_code]['pr-dhl/postnum']['hidden'] = true; $checkout_fields[$country_code]['pr-dhl/postnum']['required'] = false; } } return $checkout_fields; } public function load_styles_scripts() { $is_parcelfinder_enabled = $this->is_parcelfinder_enabled(); if ($this->is_tracking_enabled() && ($this->is_preferredservice_enabled() || $is_parcelfinder_enabled)) { wp_enqueue_script('pr-dhl-frontend-pixel', PR_DHL_PLUGIN_DIR_URL.'/assets/js/pr-dhl-frontend-pixel.js', [], PR_DHL_VERSION, true); } // load scripts on checkout page only if (! is_checkout()) { return; } $frontend_data = [ 'ajax_url' => admin_url('admin-ajax.php'), 'packstation_icon' => PR_DHL_PLUGIN_DIR_URL.'/assets/img/packstation.png', 'parcelshop_icon' => PR_DHL_PLUGIN_DIR_URL.'/assets/img/parcelshop.png', 'post_office_icon' => PR_DHL_PLUGIN_DIR_URL.'/assets/img/post_office.png', 'opening_times' => esc_html__('Opening Times', 'dhl-for-woocommerce'), 'monday' => esc_html__('Monday', 'dhl-for-woocommerce'), 'tueday' => esc_html__('Tuesday', 'dhl-for-woocommerce'), 'wednesday' => esc_html__('Wednesday', 'dhl-for-woocommerce'), 'thrusday' => esc_html__('Thursday', 'dhl-for-woocommerce'), 'friday' => esc_html__('Friday', 'dhl-for-woocommerce'), 'satuday' => esc_html__('Saturday', 'dhl-for-woocommerce'), 'sunday' => esc_html__('Sunday', 'dhl-for-woocommerce'), 'services' => esc_html__('Services', 'dhl-for-woocommerce'), 'yes' => esc_html__('Yes', 'dhl-for-woocommerce'), 'no' => esc_html__('No', 'dhl-for-woocommerce'), 'parking' => esc_html__('Parking', 'dhl-for-woocommerce'), 'handicap' => esc_html__('Handicap Accessible', 'dhl-for-woocommerce'), 'packstation' => PR_DHL_PACKSTATION, 'parcelShop' => PR_DHL_PARCELSHOP, 'postoffice' => PR_DHL_POST_OFFICE, 'branch' => esc_html__('Branch', 'dhl-for-woocommerce'), 'select' => esc_html__('Select ', 'dhl-for-woocommerce'), 'select_drop' => esc_html__('Select a drop-off point', 'dhl-for-woocommerce'), 'post_number' => esc_html__('Post Number ', 'dhl-for-woocommerce'), 'post_number_tip' => esc_html__('?', 'dhl-for-woocommerce'), // Translators: %1$s is an opening HTML tag and %2$s is a closing HTML tag for styling the error message. 'no_api_key' => sprintf(esc_html__('%1$sPlease insert an API Key to enable the display of locations in the frontend on a map.%2$s', 'dhl-for-woocommerce'), '
', '
'), 'post_code_error' => esc_html__('Please enter a postcode to search locations.', 'dhl-for-woocommerce'), ]; if (! empty($this->shipping_dhl_settings['dhl_payment_gateway'])) { $frontend_data['cod_enabled'] = true; } else { $frontend_data['cod_enabled'] = false; } if ($this->is_preferredservice_enabled() || $is_parcelfinder_enabled) { $frontend_data['map_type'] = $this->get_map_type(); $frontend_data['ship_to_different_address_text'] = esc_html__('Ship to a different address or Packstation/Branch?', 'dhl-for-woocommerce'); // Register and load our styles and scripts wp_register_script('pr-dhl-checkout-frontend', PR_DHL_PLUGIN_DIR_URL.'/assets/js/pr-dhl-checkout-frontend.js', ['jquery', 'wc-checkout'], PR_DHL_VERSION, true); wp_localize_script('pr-dhl-checkout-frontend', 'pr_dhl_checkout_frontend', $frontend_data); wp_enqueue_script('pr-dhl-checkout-frontend'); wp_enqueue_style('pr-dhl-checkout-frontend', PR_DHL_PLUGIN_DIR_URL.'/assets/css/pr-dhl-frontend.css', [], PR_DHL_VERSION); } if ($this->is_preferredservice_enabled()) { // jquery UI for tool tip wp_enqueue_style('pr-dhl-jquery-ui-style', PR_DHL_PLUGIN_DIR_URL.'/assets/css/jquery-ui-tooltip.css', [], '1.0'); wp_enqueue_script('jquery-effects-core'); wp_enqueue_script('jquery-ui-tooltip'); } if ($is_parcelfinder_enabled && $this->is_map_enabled()) { // Enqueue Fancybox wp_enqueue_script('pr-dhl-fancybox-js', PR_DHL_PLUGIN_DIR_URL.'/assets/js/jquery.fancybox.min.js', ['jquery']); wp_enqueue_style('pr-dhl-fancybox-css', PR_DHL_PLUGIN_DIR_URL.'/assets/css/jquery.fancybox.min.css', '', PR_DHL_VERSION); if ($this->get_map_type() === 'osm') { // Enqueue Leaflet wp_enqueue_style('leaflet_css', 'https://unpkg.com/leaflet/dist/leaflet.css', '', PR_DHL_VERSION); wp_enqueue_script('leaflet_js', 'https://unpkg.com/leaflet/dist/leaflet.js', '', PR_DHL_VERSION); } else { // Enqueue Google Maps wp_enqueue_script('pr-dhl-google-maps', 'https://maps.googleapis.com/maps/api/js?key='.$this->shipping_dhl_settings['dhl_google_maps_api_key']); } } } protected function validate_is_german_customer() { $billing_country = WC()->customer ? WC()->customer->get_billing_country() : ''; $shipping_country = WC()->customer ? WC()->customer->get_shipping_country() : ''; $base_country_code = PR_DHL()->get_base_country(); $display_preferred = false; // Preferred options are only for Germany customers if ($base_country_code == 'DE' && ($shipping_country == 'DE' || $billing_country == 'DE')) { return true; } else { return false; } } public function validate_extra_services_available($check_day_transfer = false) { // woocommerce_form_field('pr_dhl_paket_preferred_location'); $chosen_shipping_methods = WC()->session->get('chosen_shipping_methods'); $chosen_payment_method = WC()->session->get('chosen_payment_method'); $display_preferred = false; // Preferred options are only for Germany customers if ($this->validate_is_german_customer()) { if ($check_day_transfer) { foreach (WC()->cart->get_cart() as $cart_item_key => $values) { $same_day_transfer = get_post_meta($values['product_id'], '_dhl_no_same_day_transfer', true); // If one of the products cannot be transferred same day then don't show preferred services if ($same_day_transfer == 'yes') { return false; } } } if (! isset($this->shipping_dhl_settings) || empty($this->shipping_dhl_settings['dhl_shipping_methods'])) { throw new Exception(esc_html__('No shipping method enabled.', 'dhl-for-woocommerce')); } $wc_methods_dhl = $this->shipping_dhl_settings['dhl_shipping_methods']; if (isset($chosen_shipping_methods)) { if (is_array($chosen_shipping_methods)) { foreach ($chosen_shipping_methods as $key => $value) { $ship_method_slug = $this->get_shipping_method_slug($value); if (in_array($ship_method_slug, $wc_methods_dhl)) { $display_preferred = true; break; } } } else { $ship_method_slug = $this->get_shipping_method_slug($chosen_shipping_methods); if (in_array($ship_method_slug, $wc_methods_dhl)) { $display_preferred = true; } } } $wc_payment_dhl = $this->shipping_dhl_settings['dhl_payment_gateway']; if (isset($chosen_payment_method) && ! empty($wc_payment_dhl)) { if (is_array($chosen_payment_method)) { foreach ($chosen_payment_method as $key => $value) { // $ship_method_slug = $this->get_shipping_method_slug( $value ); if (in_array($value, $wc_payment_dhl)) { throw new Exception(esc_html__('Payment gateway excluded.', 'dhl-for-woocommerce')); } } } else { // $ship_method_slug = $this->get_shipping_method_slug( $chosen_payment_method ); if (in_array($chosen_payment_method, $wc_payment_dhl)) { throw new Exception(esc_html__('Payment gateway excluded.', 'dhl-for-woocommerce')); } } } } // if reached here and not enabled then it's due to the selected shipping method not being set for DHL services if (! $display_preferred) { throw new Exception(esc_html__('Not enabled for selected shipping method.', 'dhl-for-woocommerce')); } return $display_preferred; } protected function validate_cdp_available() { $shipping_country = WC()->customer->get_shipping_country(); $valid_countries = ['SE', 'FI', 'BE', 'AT', 'FR']; if (in_array($shipping_country, $valid_countries)) { // Check if COD payment gateway selected $wc_payment_dhl = $this->shipping_dhl_settings['dhl_payment_gateway']; $chosen_payment_method = WC()->session->get('chosen_payment_method'); if (isset($chosen_payment_method) && ! empty($wc_payment_dhl)) { if (is_array($chosen_payment_method)) { foreach ($chosen_payment_method as $key => $value) { if (in_array($value, $wc_payment_dhl)) { return false; } } } elseif (in_array($chosen_payment_method, $wc_payment_dhl)) { return false; } } return true; } return false; } public function add_preferred_fields() { try { $display_preferred = $this->validate_extra_services_available(true); if ($display_preferred == true) { $template_args = []; if (isset($_POST['post_data'])) { parse_str($_POST['post_data'], $post_data); foreach ($this->preferred_services as $key => $value) { if (isset($post_data[$key])) { // array_push($template_args, $post_data[ $key ] ); $template_args[$key.'_selected'] = wc_clean($post_data[$key]); } } } if (isset($this->shipping_dhl_settings['dhl_preferred_day']) && ($this->shipping_dhl_settings['dhl_preferred_day'] == 'yes')) { if (isset($_POST['s_postcode'])) { $shipping_postcode = wc_clean($_POST['s_postcode']); $template_args['preferred_day_time'] = PR_DHL()->get_dhl_preferred_day_time($shipping_postcode); // Place preferred day and time in session, as to not call the API after placing an order unnecessarily WC()->session->set('dhl_preferred_day_time', $template_args['preferred_day_time']); } } wc_get_template('checkout/dhl-preferred-services.php', $template_args, '', PR_DHL_PLUGIN_DIR_PATH.'/templates/'); } } catch (Exception $e) { // do nothing } } public function add_cdp_fields() { if ($this->validate_cdp_available()) { wc_get_template('checkout/dhl-closest-drop-point.php', [], '', PR_DHL_PLUGIN_DIR_PATH.'/templates/'); } } public function add_cart_fees($cart) { if (! $_POST || (is_admin() && ! is_ajax())) { return; } // POST information is either in a query string-like variable called 'post_data'... if (isset($_POST['post_data'])) { parse_str($_POST['post_data'], $post_data); } else { $post_data = $_POST; // ... else it is in the POST variable itself } try { if (! isset($this->shipping_dhl_settings)) { return; } if (! empty($post_data['pr_dhl_preferred_day'])) { if (! empty($this->shipping_dhl_settings['dhl_preferred_day_cost'])) { $cart->add_fee(esc_html__('DHL Delivery Day', 'dhl-for-woocommerce'), wc_format_decimal($this->shipping_dhl_settings['dhl_preferred_day_cost'])); } } /* if( ! empty( $this->shipping_dhl_settings['dhl_cod_fee'] ) && $this->shipping_dhl_settings['dhl_cod_fee'] == 'yes' && isset( $post_data['payment_method'] ) && $post_data['payment_method'] == 'cod' ) { // Add €2 fee to COD usage (Euro is being assumed as currency) $cart->add_fee( esc_html__('DHL COD fee', 'dhl-for-woocommerce'), 2 ); }*/ } catch (Exception $e) { // do nothing } } public function verify_preferred_services_fields() { // save the posted preferences to the order so can be used when generating label $dhl_label_options = []; if (! isset($_POST)) { return $dhl_label_options; } foreach ($this->preferred_services as $key => $value) { if (! empty($_POST[$key])) { $dhl_label_options[$key] = wc_clean($_POST[$key]); } } if (isset($dhl_label_options)) { if (isset($dhl_label_options['pr_dhl_preferred_location_neighbor'])) { if (($dhl_label_options['pr_dhl_preferred_location_neighbor'] == 'preferred_location') && (! isset($dhl_label_options['pr_dhl_preferred_location']))) { throw new Exception(esc_html__('Please enter the preferred location.', 'dhl-for-woocommerce')); } if (($dhl_label_options['pr_dhl_preferred_location_neighbor'] == 'preferred_neighbor') && (! isset($dhl_label_options['pr_dhl_preferred_neighbour_name']) || ! isset($dhl_label_options['pr_dhl_preferred_neighbour_address']))) { throw new Exception(esc_html__('Please enter the preferred neighbor name and address.', 'dhl-for-woocommerce')); } } } return $dhl_label_options; } public function process_dhl_preferred_fields($order_id, $posted) { // save the posted preferences to the order so can be used when generating label $dhl_label_options = $this->verify_preferred_services_fields(); if (! empty($dhl_label_options)) { PR_DHL()->get_pr_dhl_wc_order()->save_dhl_label_items($order_id, $dhl_label_options); } } public function prepare_cdp_fields() { // save the posted preferences to the order so can be used when generating label $dhl_label_options = []; if (! isset($_POST)) { return $dhl_label_options; } foreach ($this->cdp_service as $key => $value) { if (! empty($_POST[$key])) { $dhl_label_options[$key] = wc_clean($_POST[$key]); } } return $dhl_label_options; } public function process_cdp_fields($order_id, $posted) { // save the posted preferences to the order so can be used when generating label $dhl_label_options = $this->prepare_cdp_fields(); if (! empty($dhl_label_options)) { PR_DHL()->get_pr_dhl_wc_order()->save_dhl_label_items($order_id, $dhl_label_options); } } private function get_shipping_method_slug($ship_method) { if (empty($ship_method)) { return $ship_method; } // Assumes format 'name:id' $new_ship_method = explode(':', $ship_method); $new_ship_method = isset($new_ship_method[0]) ? $new_ship_method[0] : $ship_method; return $new_ship_method; } public function display_dhl_preferred_free_services_values($total_rows, $order) { $order_id = $order->get_id(); $dhl_label_options = PR_DHL()->get_pr_dhl_wc_order()->get_dhl_label_items($order_id); if (isset(WC()->session)) { $preferred_day_time = WC()->session->get('dhl_preferred_day_time'); $new_rows = []; foreach ($this->preferred_services as $key => $value) { if (! empty($dhl_label_options[$key])) { // NEED TO PLACE THESE ROWS BEFORE THE PAYMENT METHOD $new_rows[$key]['label'] = $value.':'; if (isset($this->preferred_location_neighbor[$dhl_label_options[$key]])) { $new_rows[$key]['value'] = $this->preferred_location_neighbor[$dhl_label_options[$key]]; } else { $new_rows[$key]['value'] = $dhl_label_options[$key]; } } } if (! empty($new_rows)) { // Instert before payment method $insert_before = array_search('payment_method', array_keys($total_rows)); // If no payment method, insert before order total if (empty($insert_before)) { $insert_before = array_search('order_total', array_keys($total_rows)); } if (empty($insert_before)) { $total_rows += $new_rows; } else { $this->array_insert($total_rows, $insert_before, $new_rows); } } } return $total_rows; } private function array_insert(&$array, $position, $insert_array) { $first_array = array_splice($array, 0, $position); $array = array_merge($first_array, $insert_array, $array); } public function add_parcel_finder_btn() { if (! $this->is_map_enabled()) { return; } $dhl_logo = PR_DHL_PLUGIN_DIR_URL.'/assets/img/dhl-official.png'; echo ''.$this->get_branch_location_text().''; } protected function get_branch_location_text() { $button_text = ''; if ($this->is_parcelshop_enabled() || $this->is_post_office_enabled()) { // $button_text = esc_html__('Search Packstation / Branch', 'dhl-for-woocommerce') $button_text = esc_html__('Branch', 'dhl-for-woocommerce'); } if ($this->is_packstation_enabled()) { if (! empty($button_text)) { $button_text = esc_html__(' / ', 'dhl-for-woocommerce').$button_text; } $button_text = esc_html__('Packstation', 'dhl-for-woocommerce').$button_text; } $button_text = esc_html__('Search ', 'dhl-for-woocommerce').$button_text; return $button_text; } public function add_parcel_finder_form() { $template_args = []; $template_args['packstation_img'] = PR_DHL_PLUGIN_DIR_URL.'/assets/img/packstation.png'; $template_args['parcelshop_img'] = PR_DHL_PLUGIN_DIR_URL.'/assets/img/parcelshop.png'; $template_args['post_office_img'] = PR_DHL_PLUGIN_DIR_URL.'/assets/img/post_office.png'; $template_args['packstation_enabled'] = $this->is_packstation_enabled(); $template_args['parcelshop_enabled'] = $this->is_parcelshop_enabled(); $template_args['post_office_enabled'] = $this->is_post_office_enabled(); wc_get_template('checkout/dhl-parcel-finder.php', $template_args, '', PR_DHL_PLUGIN_DIR_PATH.'/templates/'); } public function call_parcel_finder() { check_ajax_referer('dhl_parcelfinder', 'security'); $parcelfinder_country = isset($_POST['parcelfinder_country']) ? wc_clean(wp_unslash($_POST['parcelfinder_country'])) : ''; $parcelfinder_postcode = isset($_POST['parcelfinder_postcode']) ? wc_clean(wp_unslash($_POST['parcelfinder_postcode'])) : ''; $parcelfinder_city = isset($_POST['parcelfinder_city']) ? wc_clean(wp_unslash($_POST['parcelfinder_city'])) : ''; $parcelfinder_address = isset($_POST['parcelfinder_address']) ? wc_clean(wp_unslash($_POST['parcelfinder_address'])) : ''; $packstation_filter = isset($_POST['packstation_filter']) ? wc_clean(wp_unslash($_POST['packstation_filter'])) : ''; $branch_filter = isset($_POST['branch_filter']) ? wc_clean(wp_unslash($_POST['branch_filter'])) : ''; try { $dhl_obj = PR_DHL()->get_dhl_factory(); $args['dhl_settings']['api_user'] = $this->shipping_dhl_settings['dhl_api_user']; $args['dhl_settings']['api_pwd'] = $this->shipping_dhl_settings['dhl_api_pwd']; $args['dhl_settings']['sandbox'] = $this->shipping_dhl_settings['dhl_sandbox']; $args['shipping_address']['address'] = $parcelfinder_address; $args['shipping_address']['postcode'] = $parcelfinder_postcode; $args['shipping_address']['city'] = $parcelfinder_city; $args['shipping_address']['country'] = $parcelfinder_country; $args['dhl_parcel_limit'] = $this->shipping_dhl_settings['dhl_parcel_limit']; $args['dhl_packstation_filter'] = $packstation_filter; $args['dhl_branch_filter'] = $branch_filter; $parcel_res = $dhl_obj->get_parcel_location($args); if (! isset($parcel_res->locations)) { throw new Exception(esc_html__('No parcel shops found', 'dhl-for-woocommerce')); } $res_count = 0; $parcel_res_filtered = []; foreach ($parcel_res->locations as $key => $value) { if (($this->is_packstation_enabled() && ($packstation_filter == 'true') && ($value->location->type == 'locker')) || ($this->is_parcelshop_enabled() && ($branch_filter == 'true') && ($value->location->type == 'servicepoint')) || ($this->is_post_office_enabled() && ($branch_filter == 'true') && ($value->location->type == 'postoffice' || $value->location->type == 'postbank'))) { if ($value->serviceTypes) { if (is_array($value->serviceTypes)) { foreach ($value->serviceTypes as $service_type) { // Only display shops that accept parcels. // Not needed 'parcelacceptance' if (in_array($service_type, ['parcel:pick-up', 'parcel:pick-up-unregistered', 'parcel:pick-up-registered'])) { array_push($parcel_res_filtered, $value); $res_count++; break; } } } elseif (in_array($value->serviceTypes, ['parcel:pick-up', 'parcel:pick-up-unregistered', 'parcel:pick-up-registered'])) { array_push($parcel_res_filtered, $value); $res_count++; } } } if ($res_count == $this->shipping_dhl_settings['dhl_parcel_limit']) { break; } } if (empty($parcel_res_filtered)) { throw new Exception(esc_html__('No Parcel Shops found. Ensure "Packstation" or Branch" filter is checked ', 'dhl-for-woocommerce')); } wp_send_json( [ 'parcel_res' => $parcel_res_filtered, // 'tracking_note' => $tracking_note ] ); } catch (Exception $e) { wp_send_json(['error' => $e->getMessage()]); } wp_die(); } protected function is_parcelfinder_enabled() { if ($this->is_packstation_enabled() || $this->is_parcelshop_enabled() || $this->is_post_office_enabled()) { return true; } else { return false; } } /** * Is Location Finder map enabled? * * @return bool */ protected function is_map_enabled() { if ((isset($this->shipping_dhl_settings['dhl_display_google_maps']) && ($this->shipping_dhl_settings['dhl_display_google_maps'] == 'yes'))) { return true; } return false; } /** * Get Location Finder map type. * * @return string */ protected function get_map_type() { if ((isset($this->shipping_dhl_settings['dhl_map_type']) && ($this->shipping_dhl_settings['dhl_map_type'] === 'osm'))) { return 'osm'; } return 'gmaps'; } protected function is_packstation_enabled() { if ((isset($this->shipping_dhl_settings['dhl_display_packstation']) && ($this->shipping_dhl_settings['dhl_display_packstation'] == 'yes'))) { return true; } else { return false; } } protected function is_parcelshop_enabled() { if ((isset($this->shipping_dhl_settings['dhl_display_parcelshop']) && ($this->shipping_dhl_settings['dhl_display_parcelshop'] == 'yes'))) { return true; } else { return false; } } protected function is_post_office_enabled() { if ((isset($this->shipping_dhl_settings['dhl_display_post_office']) && ($this->shipping_dhl_settings['dhl_display_post_office'] == 'yes'))) { return true; } else { return false; } } protected function is_email_notification_enabled() { if ((isset($this->shipping_dhl_settings['dhl_email_notification']) && ($this->shipping_dhl_settings['dhl_email_notification'] == 'yes'))) { return true; } else { return false; } } public function add_postnum_field($checkout_fields) { $types = [ 'normal' => esc_html__('Regular Address', 'dhl-for-woocommerce'), ]; if ($this->is_packstation_enabled()) { $types['dhl_packstation'] = esc_html__('DHL Packstation', 'dhl-for-woocommerce'); } if ($this->is_post_office_enabled()) { $types['dhl_branch'] = esc_html__('DHL Branch', 'dhl-for-woocommerce'); } $points = [ '' => esc_html__('Select a drop-off point', 'dhl-for-woocommerce'), ]; $shipping_dhl_address_type = [ 'label' => esc_html__('Address Type', 'dhl-for-woocommerce'), 'required' => true, 'type' => 'select', 'class' => ['form-row-first shipping-dhl-address-type'], 'input_class' => ['select2-full-width'], 'clear' => true, 'default' => 'normal', 'options' => $types, ]; $shipping_dhl_postnum_branch = [ 'label' => esc_html__('Post Number', 'dhl-for-woocommerce'), 'required' => false, 'type' => 'text', 'class' => ['shipping-dhl-postnum'], 'clear' => true, ]; $shipping_dhl_drop_off = [ 'label' => __('Drop off points', 'dhl-for-woocommerce'), 'required' => false, 'type' => 'select', 'class' => ['form-row-last shipping-dhl-drop-off-points'], 'input_class' => ['select2-full-width'], 'clear' => true, 'default' => 'normal', 'options' => $points, ]; $new_shipping_fields = []; foreach ($checkout_fields['shipping'] as $key => $field) { if ($key === 'shipping_first_name') { $new_shipping_fields['shipping_dhl_address_type'] = $shipping_dhl_address_type; $new_shipping_fields['shipping_dhl_drop_off'] = $shipping_dhl_drop_off; } if ($key === 'shipping_address_1') { $new_shipping_fields['shipping_dhl_postnum'] = $shipping_dhl_postnum_branch; } $new_shipping_fields[$key] = $field; } if (empty($new_shipping_fields)) { $new_shipping_fields['shipping_dhl_address_type'] = $shipping_dhl_address_type; $new_shipping_fields['shipping_dhl_drop_off'] = $shipping_dhl_drop_off; $new_shipping_fields['shipping_dhl_postnum'] = $shipping_dhl_postnum_branch; $new_shipping_fields = array_merge($new_shipping_fields, $checkout_fields['shipping']); } // Update the checkout fields array $checkout_fields['shipping'] = $new_shipping_fields; return $checkout_fields; } public function admin_order_add_postnum_field($fields) { $shipping_dhl_postnum_branch = [ 'label' => esc_html__('Post Number', 'dhl-for-woocommerce'), 'required' => false, 'type' => 'text', 'class' => 'shipping-dhl-postnum', 'clear' => true, 'show' => false, ]; if ($new_shipping_fields = $this->array_insert_before('address_1', $fields, 'dhl_postnum', $shipping_dhl_postnum_branch)) { $fields = $new_shipping_fields; } return $fields; } public function add_email_notification_checkbox() { if ($this->validate_is_german_customer()) { woocommerce_form_field( 'pr_dhl_email_notification', [ 'type' => 'checkbox', 'class' => ['pr-dhl-email-notification form-row-wide'], 'label' => esc_html__('Activate Shipment Notification. When activated DHL will inform you via email about the shipment status of your order.', 'dhl-for-woocommerce'), ], 'yes' ); } } public function process_email_notification_fields($order_id, $posted) { $dhl_label_items = PR_DHL()->get_pr_dhl_wc_order()->get_dhl_label_items($order_id); if (isset($_POST['pr_dhl_email_notification'])) { if (! is_array($dhl_label_items)) { $dhl_label_items = []; } $dhl_label_items['pr_dhl_email_notification'] = $_POST['pr_dhl_email_notification']; PR_DHL()->get_pr_dhl_wc_order()->save_dhl_label_items($order_id, $dhl_label_items); } } /* * Inserts a new key/value before the key in the array. * * @param $key * The key to insert before. * @param $array * An array to insert in to. * @param $new_key * The key to insert. * @param $new_value * An value to insert. * * @return * The new array if the key exists, FALSE otherwise. * * @see array_insert_after() */ private function array_insert_before($key, array &$array, $new_key, $new_value) { if (array_key_exists($key, $array)) { $new = []; foreach ($array as $k => $value) { if ($k === $key) { $new[$new_key] = $new_value; } $new[$k] = $value; } return $new; } return false; } public function validate_post_number() { // Validate input only if "ship to different address" flag is set if (! isset($_POST['ship_to_different_address'])) { return; } $shipping_dhl_address_type = wc_clean(wp_unslash($_POST['shipping_dhl_address_type'] ?? '')); $shipping_address_1 = wc_clean(wp_unslash($_POST['shipping_address_1'] ?? '')); $shipping_dhl_postnum = wc_clean(wp_unslash($_POST['shipping_dhl_postnum'] ?? '')); $pos_ps = PR_DHL()->is_packstation($shipping_address_1); $pos_rs = PR_DHL()->is_parcelshop($shipping_address_1); $pos_po = PR_DHL()->is_post_office($shipping_address_1); if (! empty($shipping_dhl_address_type) && $shipping_dhl_address_type != 'normal') { // check shipping method and payment gateway first try { $this->validate_extra_services_available(); } catch (Exception $e) { wc_add_notice(esc_html__('"DHL Locations" cannot be used - ', 'dhl-for-woocommerce').$e->getMessage(), 'error'); return; } } if ($shipping_dhl_address_type == 'dhl_packstation') { if (empty($shipping_dhl_postnum)) { wc_add_notice(esc_html__('Post Number is mandatory for a Packstation location.', 'dhl-for-woocommerce'), 'error'); return; } if (! $pos_ps) { // Translators: %s is the text that must be included in the address (e.g., a specific keyword or phrase). wc_add_notice(sprintf(esc_html__('The text "%s" must be included in the address.', 'dhl-for-woocommerce'), PR_DHL_PACKSTATION), 'error'); return; } } elseif ($shipping_dhl_address_type == 'dhl_branch') { if (! $pos_rs) { // Translators: %s is the text that must be included in the address (e.g., a specific keyword or phrase). wc_add_notice(sprintf(esc_html__('The text "%s" must be included in the address.', 'dhl-for-woocommerce'), PR_DHL_PARCELSHOP), 'error'); return; } if (! $pos_po) { // Translators: %s is the text that must be included in the address (e.g., a specific keyword or phrase). wc_add_notice(sprintf(esc_html__('The text "%s" must be included in the address.', 'dhl-for-woocommerce'), PR_DHL_POST_OFFICE), 'error'); return; } } // Post Number only applies to Packstation / Postfiliale, not a Regular Address. if (! empty($shipping_dhl_postnum) && PR_DHL()->is_droppoint_address_type($shipping_dhl_address_type)) { if (! is_numeric($shipping_dhl_postnum)) { wc_add_notice(esc_html__('Post Number must be a number.', 'dhl-for-woocommerce'), 'error'); return; } $post_num_len = strlen($shipping_dhl_postnum); if ($post_num_len < 6 || $post_num_len > 12) { wc_add_notice(esc_html__('The post number you entered is not valid. Please correct the number.', 'dhl-for-woocommerce'), 'error'); return; } } } /** * Clear a stale DHL Post Number when a Regular Address is selected. * * The Post Number only applies to Packstation / Parcelshop / Postfiliale deliveries. * If a customer entered one and then switched to a Regular Address, drop the value so * it is not persisted on the order or sent to the DHL API. Mirrors the Blocks checkout, * which clears the field client-side on the same switch. The value is kept whenever * either the selected address type or the shipping address itself is a droppoint, since * that is how it is consumed downstream. * * @param int $order_id Order ID. * @param array $posted Sanitized posted checkout data. */ public function clear_post_number_for_regular_address($order_id, $posted) { // An absent or empty address type means Regular Address — e.g. when shipping to the // billing address, the shipping_* fields are not posted — so still treat it as a clear // candidate (the droppoint-address check below protects values the label still needs). $address_type = isset($posted['shipping_dhl_address_type']) ? $posted['shipping_dhl_address_type'] : ''; $order = wc_get_order($order_id); if (! $order) { return; } // Keep the Post Number for droppoints — by the selected address type or by the shipping // address itself, which is how it is consumed downstream — so a value the label still // needs is never dropped, even if the address-type field says otherwise. if (PR_DHL()->is_droppoint($address_type, $order->get_shipping_address_1())) { return; } if (! empty($order->get_meta('_shipping_dhl_postnum'))) { $order->delete_meta_data('_shipping_dhl_postnum'); $order->save(); } } public function display_post_number($address, $order) { if (PR_DHL()->is_droppoint_address($address['address_1']) && (! empty($shipping_dhl_postnum = $order->get_meta('_shipping_dhl_postnum')))) { $address['dhl_postnum'] = $shipping_dhl_postnum; } return $address; } public function set_format_post_number($formats) { $is_store_api = defined('REST_REQUEST') && REST_REQUEST && ! empty($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '/wc/store/') !== false; $is_blocks_checkout = function_exists('is_checkout') && is_checkout() && method_exists($this, 'is_using_checkout_block') && $this->is_using_checkout_block(); if ($is_store_api || $is_blocks_checkout) { return $formats; } foreach ($formats as $key => $value) { $count = 0; // use double quotes to find "\n" othewise treated as 2 chars $format_replaced = str_replace("\n{address_1}", "\n{dhl_postnum}\n{address_1}", $value, $count); // Only change format if "address_1 found" if ($count) { $formats[$key] = $format_replaced; } } return $formats; } public function add_format_post_number($address_format, $args) { // $address_format['{dhl_postnum}'] must be set, even if empty as to not display on the frontend as '{dhl_postnum}' if (isset($args['dhl_postnum'])) { $address_format['{dhl_postnum}'] = $args['dhl_postnum']; } else { $address_format['{dhl_postnum}'] = ''; } return $address_format; } } }