plugin = $plugin; $this->pickup_points_manager = $pickup_points_manager; } /** * */ public function hooks() { add_action( 'woocommerce_after_checkout_validation', [ $this, 'validate_selected_point_on_paczkomaty_shipping_method', ], self::PRIORITY_FIRST ); add_action( 'woocommerce_checkout_process', [ $this, 'save_paczkomat_id_in_session_on_checkout' ] ); add_action( 'woocommerce_checkout_update_order_review', [ $this, 'woocommerce_checkout_update_order_review', ] ); add_action( 'woocommerce_checkout_init', [ $this, 'init_checkout_hooks' ] ); add_action( 'woocommerce_checkout_update_order_review', [ $this, 'init_checkout_hooks', ] ); add_action( 'woocommerce-paczkomaty-inpost/pickup-point-selection', [ $this, 'display_choose_machine_field' ] ); add_filter( 'paczkomaty_shipping_method_admin_machines', [ $this, 'paczkomaty_shipping_method_admin_machines', ], 10, 2 ); add_filter( 'paczkomaty_paczkomaty_options_admin', [ $this, 'paczkomaty_paczkomaty_options_admin' ] ); add_filter( 'woocommerce_update_order_review_fragments', [ $this, 'reset_checkout' ], self::PRIORITY_FIRST ); add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); } /** * @internal */ public function enqueue_scripts() { $add_scripts = /** * Filter if add inpost scripts. * * @param bool $add_scripts If should add inpost scripts to page. */ apply_filters( 'woocommerce_paczkomaty_inpost/add_scripts', false ); if ( $add_scripts || is_checkout() ) { $settings = $this->plugin->get_shipping_method_settings(); if ( ! isset( $settings['select_type'] ) ) { $settings['select_type'] = 'select2_ajax'; } wp_register_script( 'paczkomaty_front', trailingslashit( $this->plugin->get_plugin_assets_url() ) . 'dist/js/checkout.js', [ 'selectWoo' ], $this->plugin->scripts_version, false ); $localize_data = $this->plugin->get_localization_script_data(); $localize_data['settings']['select_type'] = $settings['select_type']; wp_localize_script( 'paczkomaty_front', 'paczkomaty', $localize_data ); wp_enqueue_script( 'paczkomaty_front' ); wp_enqueue_style( 'paczkomaty_front', trailingslashit( $this->plugin->get_plugin_assets_url() ) . 'dist/css/checkout.css', [ 'select2' ], $this->plugin->scripts_version ); wp_enqueue_script( 'paczkomaty_geowidget', 'https://geowidget.easypack24.net/js/sdk-for-javascript.js', [], $this->plugin->scripts_version, false ); wp_enqueue_style( 'paczkomaty_geowidget', 'https://geowidget.easypack24.net/css/easypack.css', [], $this->plugin->scripts_version ); } } /** * @param array $fragments * * @return array * @internal */ public function reset_checkout( $fragments ) { $this->already_displayed = false; $this->init_checkout_hooks(); return $fragments; } /** * @return void * * @internal */ public function init_checkout_hooks() { if ( $this->get_select_placement() === WC_Paczkomaty_Shipping_Method::OPTION_INSERT_INTO_SECTION ) { if ( ! has_action( 'woocommerce_after_shipping_rate', [ $this, 'display_choose_machine_field_after_shipping_rate' ] ) ) { add_action( 'woocommerce_after_shipping_rate', [ $this, 'display_choose_machine_field_after_shipping_rate' ], 10, 2 ); } } else { $this->add_actions_for_other_placements(); } } /** * @param array $paczkomaty_options * * @return array */ public function paczkomaty_paczkomaty_options_admin( $paczkomaty_options ) { $this->init_machine_list(); $paczkomaty_options = $this->adminMachines; return $paczkomaty_options; } /** * Validate selected point and how notice on failure. * * @throws Exception . * @throws WPDesk_Paczkomaty_ShipX_Exception . */ public function validate_selected_point_on_paczkomaty_shipping_method() { if ( WC()->cart->needs_shipping() ) { $shipping_methods = $this->flexible_shipping_methods_selected_in_cart( WPDesk_Paczkomaty_FS::SHIPPING_METHOD_INTEGRATION ); foreach ( $shipping_methods as $shipping_method ) { if ( isset( $shipping_method[ self::SHIPPING_METOD_SERVICE ] ) && WC_Paczkomaty_Shipping_Method::USLUGA_PACZKOMATY === $shipping_method[ self::SHIPPING_METOD_SERVICE ] ) { if ( empty( $_POST[ self::FIELD_PACZKOMAT_ID ] ) ) { // phpcs:ignore if ( ! wc_has_notice( __( 'Proszę wybrać paczkomat', 'woocommerce-paczkomaty-inpost' ), 'error' ) ) { wc_add_notice( __( 'Proszę wybrać paczkomat', 'woocommerce-paczkomaty-inpost' ), 'error', array('id' => 'paczkomat_id_field') ); } } else { $paczkomat_id = $_POST[ self::FIELD_PACZKOMAT_ID ]; // phpcs:ignore $this->validate_point_and_add_notice( sanitize_text_field( $paczkomat_id ), $shipping_method ); } } } } } /** * Returns FS methods selected in cart. * * @param string $shipping_method_integration . * * @return array */ private function flexible_shipping_methods_selected_in_cart( $shipping_method_integration ) { $shipping_methods = []; $chosen_shipping_methods = $this->get_filtered_chosen_shipping_methods(); if ( is_array( $chosen_shipping_methods ) ) { $all_shipping_methods = flexible_shipping_get_all_shipping_methods(); $flexible_shipping = $all_shipping_methods['flexible_shipping']; $flexible_shipping_rates = $flexible_shipping->get_all_rates(); foreach ( $chosen_shipping_methods as $id => $shipping ) { if ( isset( $flexible_shipping_rates[ $shipping ] ) ) { $shipping_method = $flexible_shipping_rates[ $shipping ]; if ( $shipping_method['method_integration'] === $shipping_method_integration ) { $shipping_methods[] = $shipping_method; } } } } return $shipping_methods; } /** * Saves paczkomat id in session on checkout process. */ public function save_paczkomat_id_in_session_on_checkout() { if ( isset( $_POST[ self::FIELD_PACZKOMAT_ID ] ) ) { // phpcs:ignore WC()->session->set( self::FIELD_PACZKOMAT_ID, sanitize_text_field( $_POST[ self::FIELD_PACZKOMAT_ID ] ) ); // phpcs:ignore } } /** * . * @param string $parcel_machine_id . * @param array $shipping_method . * * @throws Exception . * @throws WPDesk_Paczkomaty_ShipX_Exception . */ private function validate_point_and_add_notice( $parcel_machine_id, array $shipping_method ) { try { $point = $this->pickup_points_manager->get_point_details( $parcel_machine_id ); $this->validate_point_cod_if_enabled_and_add_notice( $point, $shipping_method ); $this->validate_point_end_of_week_collection_if_enabled_and_add_notice( $point, $shipping_method ); } catch ( Exception $e ) { wc_add_notice( $e->getMessage(), 'error' ); } } /** * Validate point cod if enabled. * * @param PickupPointDetails $point . * @param array $shipping_method . */ private function validate_point_cod_if_enabled_and_add_notice( $point, $shipping_method ) { if ( '1' === $shipping_method[ WPDesk_Paczkomaty_FS::SETTING_COD ] ) { if ( ! $point->is_payment_available() ) { wc_add_notice( __( 'Wybrany punkt nie obsługuje płatności.', 'woocommerce-paczkomaty-inpost' ), 'error' ); } } } /** * Validate end of week collection if enabled. * End of week collection is available only on parcel machines. * * @param PickupPointDetails $point . * @param array $shipping_method . */ private function validate_point_end_of_week_collection_if_enabled_and_add_notice( $point, $shipping_method ) { if ( isset( $shipping_method[ WPDesk_Paczkomaty_FS::SETTING_END_OF_WEEK_COLLECTION ] ) && '1' === $shipping_method[ WPDesk_Paczkomaty_FS::SETTING_END_OF_WEEK_COLLECTION ] ) { if ( ! in_array( 'parcel_locker', $point->get_type(), true ) ) { wc_add_notice( __( 'Paczka w weekend dostępna jest wyłącznie dla przesyłek do paczkomatów.', 'woocommerce-paczkomaty-inpost' ), 'error' ); } } } /** * @param $post_data */ public function woocommerce_checkout_update_order_review( $post_data ) { parse_str( $post_data, $data ); if ( isset( $data[ self::FIELD_PACZKOMAT_ID ] ) ) { WC()->session->set( self::FIELD_PACZKOMAT_ID, $data[ self::FIELD_PACZKOMAT_ID ] ); } } /** * @return array */ public function is_paczkomaty_and_cod_and_eowc_in_selected_shipping_methods() { $paczkomaty = false; $cod = false; $end_of_weekend_collection = false; $shippings = $this->get_filtered_chosen_shipping_methods(); $all_shipping_methods = WC()->shipping()->get_shipping_methods(); if ( empty( $all_shipping_methods ) ) { $all_shipping_methods = WC()->shipping()->load_shipping_methods(); } /** @var WPDesk_Flexible_Shipping $flexible_shipping */ $flexible_shipping = $all_shipping_methods['flexible_shipping']; $flexible_shipping_rates = $flexible_shipping->get_all_rates(); $shipping_methods = []; foreach ( $shippings as $shipping_method_id ) { if ( isset( $flexible_shipping_rates[ $shipping_method_id ] ) ) { $shipping_method = $flexible_shipping_rates[ $shipping_method_id ]; if ( isset( $shipping_method['method_integration'] ) && $shipping_method['method_integration'] == WPDesk_Paczkomaty_FS::SHIPPING_METHOD_INTEGRATION ) { $shipping_methods[] = $shipping_method; } } } foreach ( $shipping_methods as $shipping_method ) { if ( isset( $shipping_method[ self::SHIPPING_METOD_SERVICE ] ) && $shipping_method[ self::SHIPPING_METOD_SERVICE ] == WC_Paczkomaty_Shipping_Method::USLUGA_PACZKOMATY ) { $paczkomaty = true; if ( isset( $shipping_method[ WPDesk_Paczkomaty_FS::SETTING_COD ] ) && $shipping_method[ WPDesk_Paczkomaty_FS::SETTING_COD ] == '1' ) { $cod = true; } if ( isset( $shipping_method[ WPDesk_Paczkomaty_FS::SETTING_END_OF_WEEK_COLLECTION ] ) && $shipping_method[ WPDesk_Paczkomaty_FS::SETTING_END_OF_WEEK_COLLECTION ] == '1' ) { $end_of_weekend_collection = true; } } } return [ 'paczkomaty' => $paczkomaty, 'cod' => $cod, 'end_of_week_collection' => $end_of_weekend_collection, ]; } /** * @param WC_Shipping_Rate $method * @param string $package_id * * @return void */ public function display_choose_machine_field_after_shipping_rate( $method, $package_id ) { if ( $method->get_id() != ( $this->get_filtered_chosen_shipping_methods()[ $package_id ] ?? '' ) ) { return; } if ( ! $this->should_display_paczkomaty_field( $method ) ) { return; } if ( $this->already_displayed_for_package_id === $package_id ) { $this->already_displayed = false; } if ( ! $this->already_displayed ) { echo $this->plugin->load_template( 'pickup-point-selection-after-shipping-rate', '', [] ); $this->already_displayed = true; $this->already_displayed_for_package_id = $package_id; } } private function add_actions_for_other_placements() { if ( $this->get_select_placement() === WC_Paczkomaty_Shipping_Method::OPTION_INSERT_BELOW_SECTION ) { if ( ! has_action( 'woocommerce_review_order_after_shipping', [ $this, 'display_choose_machine_field_after_shipping' ] ) ) { add_action( 'woocommerce_review_order_after_shipping', [ $this, 'display_choose_machine_field_after_shipping' ] ); } if ( ! has_action( 'woocommerce_subscriptions_after_recurring_shipping_rates', [ $this, 'display_choose_machine_field_after_shipping' ] ) ) { add_action( 'woocommerce_subscriptions_after_recurring_shipping_rates', [ $this, 'display_choose_machine_field_after_shipping' ] ); } } if ( $this->get_select_placement() === WC_Paczkomaty_Shipping_Method::OPTION_NEW_SECTION ) { if ( ! has_action( 'woocommerce_review_order_after_order_total', [ $this, 'display_choose_machine_field_after_order_total' ] ) ) { add_action( 'woocommerce_review_order_after_order_total', [ $this, 'display_choose_machine_field_after_order_total' ] ); } if ( ! has_action( 'woocommerce_subscriptions_recurring_subscription_totals', [ $this, 'display_choose_machine_field_after_order_total' ] ) ) { add_action( 'woocommerce_subscriptions_recurring_subscription_totals', [ $this, 'display_choose_machine_field_after_order_total' ], 111 ); } } } /** * @param WC_Shipping_Rate $method * * @return bool */ private function should_display_paczkomaty_field( $method ) { $metadata = $method->get_meta_data(); $fs_method = isset( $metadata['_fs_method'] ) && is_array( $metadata['_fs_method'] ) ? $metadata['_fs_method'] : []; return ( $metadata['_fs_integration'] ?? '' ) === 'paczkomaty' && ( $fs_method['paczkomaty_usluga'] ?? '' ) === 'paczkomaty' && in_array( $method->get_id(), $this->get_filtered_chosen_shipping_methods(), true ); } public function display_choose_machine_field_after_order_total() { if ( $this->already_displayed && current_action() !== $this->already_displayed_on_action ) { return; } echo $this->plugin->load_template( 'pickup-point-selection-after-order-total', '', [] ); $this->already_displayed = true; $this->already_displayed_on_action = current_action(); } public function display_choose_machine_field_after_shipping( $package_id ) { if ( $this->already_displayed && current_action() !== $this->already_displayed_on_action ) { return; } echo $this->plugin->load_template( 'pickup-point-selection-after-shipping', '', [] ); $this->already_displayed = true; $this->already_displayed_on_action = current_action(); } /** * @return void * @internal */ public function display_choose_machine_field() { $this->render_choose_machine_field( $this->get_select_method(), $this->get_select_type(), 'pickup-point-selection' ); } private function get_select_method() { $settings = $this->plugin->get_shipping_method_settings(); return isset( $settings['select_method'] ) ? $settings['select_method'] : 'select_and_map'; } private function get_select_type() { $settings = $this->plugin->get_shipping_method_settings(); return isset( $settings['select_type'] ) ? $settings['select_type'] : 'select2_ajax'; } private function get_select_placement() { $settings = $this->plugin->get_shipping_method_settings(); return isset( $settings[ WC_Paczkomaty_Shipping_Method::SELECT_PLACEMENT ] ) ? $settings[ WC_Paczkomaty_Shipping_Method::SELECT_PLACEMENT ] : WC_Paczkomaty_Shipping_Method::OPTION_INSERT_BELOW_SECTION; } /** * @param string $select_method * @param string $select_type * @param string $template * * @return void */ private function render_choose_machine_field( $select_method, $select_type, $template = 'pickup-point-selection' ) { $args = []; $paczkomaty_and_cod_and_eowc = $this->is_paczkomaty_and_cod_and_eowc_in_selected_shipping_methods(); if ( $paczkomaty_and_cod_and_eowc['paczkomaty'] ) { $args['select_type'] = $select_type; $args['select2'] = apply_filters( 'woocommerce_paczkomaty_inpost_checkout_select2', true ); if ( ! $args['select2'] ) { $args['select_type'] = 'select'; } $args['selected_id'] = WC()->session->get( self::FIELD_PACZKOMAT_ID, '' ); if ( $args['select_type'] === 'select2_ajax' ) { $args['options'] = [ '' => __( 'Wybierz paczkomat...', 'woocommerce-paczkomaty-inpost' ) ]; if ( ! empty( $args['selected_id'] ) ) { try { $point = $this->pickup_points_manager->get_point_details( $args['selected_id'] ); $args['options'][ $point->get_point_id() ] = $point->get_name(); $args['selected_name'] = $point->get_name(); } catch ( Exception $e ) { unset( $args['selected_id'] ); } } } else { $args['options'] = $this->get_parcel_machines( $paczkomaty_and_cod_and_eowc['cod'], $paczkomaty_and_cod_and_eowc['end_of_week_collection'] ); } $args['cod'] = 'FALSE'; if ( $paczkomaty_and_cod_and_eowc['cod'] ) { $args['cod'] = 'TRUE'; } $args['end_of_week_collection'] = 'FALSE'; if ( $paczkomaty_and_cod_and_eowc['end_of_week_collection'] ) { $args['end_of_week_collection'] = 'TRUE'; } $args['select_enabled'] = in_array( $select_method, [ WC_Paczkomaty_Shipping_Method::SELECT_METHOD_SELECT, WC_Paczkomaty_Shipping_Method::SELECT_METHOD_SELECT_AND_MAP ], true ); $args['map_enabled'] = in_array( $select_method, [ WC_Paczkomaty_Shipping_Method::SELECT_METHOD_MAP, WC_Paczkomaty_Shipping_Method::SELECT_METHOD_SELECT_AND_MAP ], true );; echo $this->plugin->load_template( $template, '', $args ); $script_url = trailingslashit( $this->plugin->get_plugin_assets_url() ) . 'dist/js/checkout.js?ver=' . $this->plugin->get_scrips_version(); $css_url = trailingslashit( $this->plugin->get_plugin_assets_url() ) . 'dist/css/checkout.css?ver=' . $this->plugin->get_scrips_version(); $select2_script_url = WC()->plugin_url() . '/assets/js/selectWoo/selectWoo.full.min.js?ver=' . $this->plugin->get_scrips_version(); $select2_css_url = WC()->plugin_url() . '/assets/css/select2.css?ver=' . $this->plugin->get_scrips_version(); $inpost_script_url = 'https://geowidget.easypack24.net/js/sdk-for-javascript.js?ver=' . $this->plugin->get_scrips_version(); $inpost_css_url = 'https://geowidget.easypack24.net/css/easypack.css?ver=' . $this->plugin->get_scrips_version();; $localization_data = $this->plugin->get_localization_script_data(); include __DIR__ . '/views/checkout-script.php'; } } /** * @param bool $cod */ public function init_machine_list( $cod = false, $end_of_week_collection = false ) { $paczkomaty_shipping_method = $this->plugin->paczkomaty->get_shipping_method(); if ( $paczkomaty_shipping_method->get_parcel_lockers_api() === $paczkomaty_shipping_method::API_TYPE_XML ) { if ( empty( $this->allMachines ) ) { $machines = inpost_get_machine_list(); $this->machines = [ '' => '-- ' . __( 'wybierz', 'woocommerce-paczkomaty-inpost' ) . ' --' ]; $this->allMachines = []; foreach ( $machines as $machine ) { if ( $cod === true && $machine['paymentavailable'] != 1 ) { continue; } $this->machines[ $machine['name'] ] = $machine['town'] . ", " . $machine['street'] . " " . $machine['buildingnumber']; $this->adminMachines[ $machine['name'] ] = "[" . $machine['name'] . "] " . $machine['town'] . ", " . $machine['street'] . " " . $machine['buildingnumber']; $this->allMachines[ $machine['name'] ] = $machine['town'] . ", " . $machine['street'] . " " . $machine['buildingnumber']; $this->machinesInfo[ $machine['name'] ] = $machine; } } } else { $points_type = WPDesk_Paczkomaty_ShipX_Cache::PARCEL_LOCKER_AND_POP; if ( $cod || $end_of_week_collection ) { $points_type = WPDesk_Paczkomaty_ShipX_Cache::PARCEL_LOCKER_ONLY; } $this->machines = $this->pickup_points_manager->get_points( $points_type ); $this->allMachines = $this->machines; $this->adminMachines = $this->machines; } } /** * @param bool $cod * @param bool $end_of_week_collection * * @return string[] */ private function get_parcel_machines( bool $cod = false, bool $end_of_week_collection = false ) { $points_type = WPDesk_Paczkomaty_ShipX_Cache::PARCEL_LOCKER_AND_POP; if ( $cod || $end_of_week_collection ) { $points_type = WPDesk_Paczkomaty_ShipX_Cache::PARCEL_LOCKER_ONLY; } return $this->pickup_points_manager->get_points( $points_type ); } /** * Returns list of parcel lockers. * * @param array $admin_machines List of saved options (keys are values). * @param bool $show_all_options Whether to return all options or only selected. * * @return array Updated list of options. */ public function paczkomaty_shipping_method_admin_machines( $admin_machines, $show_all_options = true ) { $default_values = [ '' => __( '-- wybierz --', 'woocommerce-paczkomaty-inpost' ) ]; $selected_values = $admin_machines; try { $this->init_machine_list(); if ( count( $this->adminMachines ) ) { foreach ( $admin_machines as $id => $name ) { if ( ! isset( $this->adminMachines[ $id ] ) ) { $this->adminMachines[ $id ] = $name; } else { $selected_values[ $id ] = $this->adminMachines[ $id ]; } } if ( $show_all_options ) { return $default_values + $this->adminMachines; } else { return $default_values + $selected_values; } } else { return $default_values + $admin_machines; } } catch ( Exception $e ) { return $default_values + $admin_machines; } } /** * @return string[] */ private function get_filtered_chosen_shipping_methods(): array { return $this->get_chosen_shipping_methods(); } /** * @return string[] */ private function get_chosen_shipping_methods(): array { return array_filter( wp_parse_list( WC()->session->get( 'chosen_shipping_methods', [] ) ) ); } }