{name (a PickupSelect országneve), carriers: név => {logo_url, groups (nevek)}}. * @return array|WP_Error */ public static function available() { if (self::$available !== null) { return self::$available; } $catalog = PickupSelect_Catalog::get((string) get_option('pickupselect_widget_key', '')); if (is_wp_error($catalog)) { return $catalog; } $shippingCountries = WC()->countries ? array_keys(WC()->countries->get_shipping_countries()) : []; $countries = []; foreach ($catalog['countries'] ?? [] as $country) { if ($shippingCountries && !in_array($country['code'], $shippingCountries, true)) { continue; } $carriers = []; foreach ($country['carriers'] ?? [] as $carrier) { $carriers[$carrier['name']] = [ 'logo_url' => $carrier['logo_url'] ?? '', 'groups' => array_values(array_map(fn ($group) => $group['name'], $carrier['groups'] ?? [])), ]; } ksort($carriers); $countries[$country['code']] = ['name' => $country['name'], 'carriers' => $carriers]; } uasort($countries, fn ($a, $b) => strcmp($a['name'], $b['name'])); return self::$available = $countries; } /** * A beállítás ablak választói: szállító neve => országok neve; és szállító => pont típusai (az összes országból). * @return array{carriers: array, groups: array}|WP_Error */ public static function choices() { $available = self::available(); if (is_wp_error($available)) { return $available; } $carriers = []; $groups = []; foreach ($available as $country) { foreach ($country['carriers'] as $name => $carrier) { $carriers[$name][] = $country['name']; $groups[$name] = array_values(array_unique(array_merge($groups[$name] ?? [], $carrier['groups']))); } } ksort($carriers); ksort($groups); return ['carriers' => $carriers, 'groups' => array_filter($groups)]; } /** * Egy szállítási mód példány térképe: * - countries: országkód => {name, carriers: név => pont típusok (üres: mind)} * - codes: a térkép országainak ISO kódjai * Országok: a mód zónájának országai (ha a zóna országokból áll), különben ahol a szállító elérhető. * Szállítók: a módnál beállítottak (üres: mind). */ public static function for_instance(int $instanceId): array { if (isset(self::$instances[$instanceId])) { return self::$instances[$instanceId]; } $empty = ['countries' => [], 'codes' => []]; $available = self::available(); $settings = self::instance_settings($instanceId); if (is_wp_error($available) || $settings === null) { return $empty; } $carriers = array_values(array_filter(array_map('strval', (array) ($settings['carriers'] ?? [])))); $groups = []; foreach ((array) ($settings['point_types'] ?? []) as $value) { $parts = explode(self::GROUP_SEPARATOR, (string) $value, 2); if (count($parts) === 2) { $groups[$parts[0]][] = $parts[1]; } } $zoneCountries = self::zone_countries($instanceId); $countries = []; foreach ($available as $code => $country) { if ($zoneCountries !== null && !in_array($code, $zoneCountries, true)) { continue; } foreach ($country['carriers'] as $name => $carrier) { if ($carriers && !in_array($name, $carriers, true)) { continue; } // csak az országban létező típusok; ha a választottak közül egy sincs itt, a szállító minden típusa $types = array_values(array_intersect($groups[$name] ?? [], $carrier['groups'])); $countries[$code]['name'] = $country['name']; $countries[$code]['carriers'][$name] = $types; } } return self::$instances[$instanceId] = ['countries' => $countries, 'codes' => array_keys($countries)]; } // a mód példány mentett beállításai (null: nincs ilyen PickupSelect mód) public static function instance_settings(int $instanceId): ?array { if ($instanceId <= 0) { return null; } $settings = get_option('woocommerce_' . PickupSelect_Plugin::METHOD_ID . '_' . $instanceId . '_settings', null); return is_array($settings) ? $settings : null; } /** * A mód zónájának országai; null, ha a zóna nem országokból áll (pl. "Máshol" zóna, kontinens, csak irányítószám). */ private static function zone_countries(int $instanceId): ?array { $zone = WC_Shipping_Zones::get_zone_by('instance_id', $instanceId); if (!$zone) { return null; } $codes = []; foreach ($zone->get_zone_locations() as $location) { if ($location->type === 'country' || $location->type === 'state') { $codes[] = explode(':', $location->code)[0]; } } return $codes ? array_values(array_unique($codes)) : null; } /** * A widget szűrése (window.PickupSelectOverrides) egy mód példányhoz: országok, szállítók, pont típusok. */ public static function overrides(int $instanceId): array { $map = self::for_instance($instanceId); $overrides = ['allowed_countries' => [], 'allowed_carriers' => []]; foreach ($map['countries'] as $country) { $overrides['allowed_countries'][] = $country['name']; foreach ($country['carriers'] as $name => $types) { $overrides['allowed_carriers'][$country['name']][] = $name; if ($types) { $overrides['allowed_groups'][$country['name']][$name] = $types; } } } return $overrides; } /** * A pont (a PickupSelect szerint megállapított országgal, szállítóval, típussal) választható-e a mód térképén. */ public static function allows(int $instanceId, array $point): bool { $carriers = self::for_instance($instanceId)['countries'][strtoupper((string) ($point['country_code'] ?? ''))]['carriers'] ?? []; if (!array_key_exists((string) ($point['carrier'] ?? ''), $carriers)) { return false; } $types = $carriers[(string) $point['carrier']]; return !$types || in_array((string) ($point['group'] ?? ''), $types, true); } /** * A bekapcsolt PickupSelect mód példányok az összes zónában (a pénztárban minden módhoz a saját térképe). * @return int[] */ public static function instance_ids(): array { $ids = []; $zones = WC_Shipping_Zones::get_zones(); $zones[] = ['shipping_methods' => (new WC_Shipping_Zone(0))->get_shipping_methods()]; foreach ($zones as $zone) { foreach ($zone['shipping_methods'] ?? [] as $method) { if ($method->id === PickupSelect_Plugin::METHOD_ID && $method->is_enabled()) { $ids[] = (int) $method->instance_id; } } } return $ids; } // a rate id-ból ("pickupselect:12") a mód példány public static function instance_from_rate(?string $rateId): int { if (!PickupSelect_Plugin::is_pickupselect_rate($rateId)) { return 0; } return absint(substr((string) $rateId, strlen(PickupSelect_Plugin::METHOD_ID) + 1)); } // a pénztárban kiválasztott PickupSelect mód példány (0: nincs) public static function chosen_instance(): int { $chosen = WC()->session ? (array) WC()->session->get('chosen_shipping_methods', []) : []; foreach ($chosen as $rateId) { $instance = self::instance_from_rate((string) $rateId); if ($instance) { return $instance; } } return 0; } // a rendelés PickupSelect szállítási tételének mód példánya (0: nincs) public static function order_instance(WC_Order $order): int { foreach ($order->get_shipping_methods() as $item) { if ($item->get_method_id() === PickupSelect_Plugin::METHOD_ID) { return (int) $item->get_instance_id(); } } return 0; } }