session ? WC()->session->get(self::SESSION_KEY) : null; return is_array($point) ? $point : null; } /** * A böngészőből jövő pont ellenőrzése és tárolása. null: törlés (pl. másik szállítási mód). * @return array|WP_Error|null */ public static function set($raw) { if (!WC()->session) { return new WP_Error('pickupselect_session', __('The checkout session has expired. Please reload the page.', 'pickupselect')); } if ($raw === null || $raw === '') { WC()->session->set(self::SESSION_KEY, null); return null; } $point = PickupSelect_Point::sanitize($raw); if (!$point) { return new WP_Error('pickupselect_invalid_point', __('Please select a pickup point on the map.', 'pickupselect')); } $info = self::lookup((string) $point['id'], (string) ($point['country_code'] ?? '')); if (is_wp_error($info)) { WC()->session->set(self::SESSION_KEY, null); return $info; } $point = self::with_info($point, $info); // a térkép is csak ezeket mutatja, de a böngészőből bármi jöhet: csak a kiválasztott szállítási mód // szállítója, pont típusa és országa $instance = PickupSelect_Carriers::chosen_instance(); if (!$instance || !PickupSelect_Carriers::allows($instance, $point)) { WC()->session->set(self::SESSION_KEY, null); return new WP_Error('pickupselect_not_offered', __('This pickup point cannot be used with the selected shipping method. Please select another one.', 'pickupselect')); } $point['instance'] = $instance; WC()->session->set(self::SESSION_KEY, $point); return $point; } // a szállító, a pont típus és az ország a PickupSelect szerint (a böngészőből jövő érték helyett) private static function with_info(array $point, array $info): array { $point['carrier'] = (string) $info['carrier']; $point['group'] = (string) ($info['group'] ?? ''); $point['country_code'] = strtoupper((string) ($info['country_code'] ?? ($point['country_code'] ?? ''))); return $point; } // a pont szállítója a PickupSelect szerint (csak a widgetben engedélyezett pont) public static function lookup(string $id, string $country) { $transient = 'pickupselect_point_' . md5(PickupSelect_Plugin::origin() . '|' . get_option('pickupselect_widget_key', '') . '|' . $id); $cached = get_transient($transient); if (is_array($cached)) { return $cached; } $url = add_query_arg(array_map('rawurlencode', array_filter([ 'apiKey' => (string) get_option('pickupselect_api_key', ''), 'widgetKey' => (string) get_option('pickupselect_widget_key', ''), 'point' => $id, 'country' => $country, ])), PickupSelect_Plugin::server_origin() . '/api/catalog/point'); $response = wp_remote_get($url, ['timeout' => 10, 'redirection' => 0, 'headers' => ['Accept' => 'application/json']]); $status = is_wp_error($response) ? 0 : (int) wp_remote_retrieve_response_code($response); $body = is_wp_error($response) ? null : json_decode(wp_remote_retrieve_body($response), true); if ($status !== 200 || !is_array($body) || empty($body['carrier'])) { return new WP_Error('pickupselect_lookup', $status === 404 ? __('This pickup point cannot be used. Please select another one.', 'pickupselect') : __('The pickup point could not be checked right now. Please try again.', 'pickupselect')); } set_transient($transient, $body, self::LOOKUP_TTL); return $body; } // klasszikus pénztár: a pont mentése, utána a pénztár update_checkout-tal újraszámol public static function ajax_set(): void { check_ajax_referer(self::AJAX_ACTION, 'security'); // a PickupSelect_Point::sanitize() szűri, és a JSON szöveget maga unslash-eli (kétszer nem szabad) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash $result = self::set($_POST['point'] ?? null); if (is_wp_error($result)) { wp_send_json_error(['message' => $result->get_error_message()]); } wp_send_json_success(['point' => $result]); } public static function nonce(): string { return wp_create_nonce(self::AJAX_ACTION); } // blokkos pénztár: extensionCartUpdate({ namespace: 'pickupselect', data: { point } }); a válasz a frissített kosár public static function register_store_api_callback(): void { if (!function_exists('woocommerce_store_api_register_update_callback')) { return; } woocommerce_store_api_register_update_callback([ 'namespace' => 'pickupselect', 'callback' => function ($data) { $result = self::set($data['point'] ?? null); if (is_wp_error($result)) { // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- a Store API JSON-ként adja vissza, a pénztár szövegként jeleníti meg throw new \Automattic\WooCommerce\StoreApi\Exceptions\RouteException($result->get_error_code(), $result->get_error_message(), 400); } }, ]); } public static function add_to_packages(array $packages): array { $point = self::get(); foreach ($packages as $key => $package) { // a díj nem a ponttól függ, de a szállítási tételen a "Carrier" a választott pont szállítója $packages[$key]['pickupselect_point'] = $point ? $point['id'] . '|' . $point['carrier'] . '|' . ($point['instance'] ?? '') : ''; } return $packages; } /** * Az admin pont cseréjéhez: a pont szállítója, pont típusa és országa a PickupSelect szerint, és hogy a rendelés * szállítási módjához tartozik-e (ha a mód azóta törölve lett, bármely szállító). A kosár korlátait nem nézi. * @return array|WP_Error */ public static function check_for_admin($raw, int $instance = 0) { $point = PickupSelect_Point::sanitize($raw); if (!$point) { return new WP_Error('pickupselect_invalid_point', __('Please select a pickup point on the map.', 'pickupselect')); } $info = self::lookup((string) $point['id'], (string) ($point['country_code'] ?? '')); if (is_wp_error($info)) { return $info; } $point = self::with_info($point, $info); if (PickupSelect_Carriers::instance_settings($instance) !== null && !PickupSelect_Carriers::allows($instance, $point)) { return new WP_Error('pickupselect_not_offered', __('This carrier or point type does not belong to the order\'s shipping method.', 'pickupselect')); } if ($instance) { $point['instance'] = $instance; } return $point; } /** * Rendeléskor: a beküldött pont az, amire a díj számolódott (a munkamenetben lévő), különben hiba. * @return array|WP_Error a rendeléshez mentendő pont */ public static function confirm($submitted) { $point = PickupSelect_Point::sanitize($submitted); $stored = self::get(); if (!$point) { return new WP_Error('pickupselect_missing_point', __('Please select a pickup point on the map.', 'pickupselect')); } if (!$stored || (string) $stored['id'] !== (string) $point['id']) { return new WP_Error('pickupselect_point_changed', __('The selected pickup point changed. Please select it again and place the order.', 'pickupselect')); } // a pont kiválasztása óta másik PickupSelect módra válthatott: a pont annak a szállítójáé legyen $instance = PickupSelect_Carriers::chosen_instance(); if ((int) ($stored['instance'] ?? 0) !== $instance || !PickupSelect_Carriers::allows($instance, $stored)) { return new WP_Error('pickupselect_point_unavailable', __('The selected pickup point does not belong to the selected shipping method. Please choose a point on the map.', 'pickupselect')); } return $stored; } }