true] ); } public static function add_settings_section(array $sections): array { $sections['pickupselect'] = 'PickupSelect'; return $sections; } public static function settings(array $settings, string $section): array { if ($section !== 'pickupselect') { return $settings; } if (PickupSelect_Connection::is_connected()) { return self::connected_settings(); } // kézi beállítás: már megadott kulcsok (pl. lekapcsolás után), vagy a felhasználó ezt választotta // phpcs:ignore WordPress.Security.NonceVerification.Recommended $manual = get_option('pickupselect_api_key', '') !== '' || isset($_GET['pickupselect_manual']); return array_merge([ [ 'title' => 'PickupSelect', 'type' => 'title', 'id' => 'pickupselect_connect', 'desc' => self::connect_box($manual), ], ['type' => 'sectionend', 'id' => 'pickupselect_connect'], ], $manual ? self::manual_settings() : []); } // a Connect gomb: a widget beállításai ezután itt változnak, a PickupSelect dashboardon nem kell semmit beállítani private static function connect_box(bool $manual): string { $html = '

' . esc_html__('Connect this shop to your PickupSelect account (log in or sign up for free). The map\'s look is then set up here, and the carriers and prices in your shipping zones; there is no need to copy keys.', 'pickupselect') . '

' . '

' . esc_html__('Connect to PickupSelect', 'pickupselect') . ''; if (!$manual) { $html .= ' ' . esc_html__('Enter keys manually instead', 'pickupselect') . ''; } return $html . '

'; } private static function connected_settings(): array { $payload = PickupSelect_Widget_Settings::payload(); // a 0.2.0 még szállítónként szűkítette a widgetet: most a szállítók táblázata szűkít, a widget mindenkit enged if (!is_wp_error($payload) && empty($payload['widget']['all_carriers'])) { $updated = PickupSelect_Widget_Settings::put(); $payload = is_wp_error($updated) ? $payload : $updated; } $status = is_wp_error($payload) ? '' : sprintf( /* translators: 1: PickupSelect account email, 2: widget name */ esc_html__('Connected to PickupSelect as %1$s. Widget: %2$s.', 'pickupselect'), '' . esc_html((string) ($payload['connection']['connected_as'] ?? '')) . '', '' . esc_html((string) ($payload['widget']['name'] ?? '')) . '' ) . ' '; $status .= esc_html__('Plan, usage and billing are in the PickupSelect dashboard.', 'pickupselect') . '

' . esc_html__('Disconnect', 'pickupselect') . ''; if (!is_wp_error($payload) && !empty($payload['connection']['dashboard_url'])) { $status .= ' ' . esc_html__('PickupSelect dashboard', 'pickupselect') . ''; } return [ [ 'title' => 'PickupSelect', 'type' => 'title', 'id' => 'pickupselect_connected', 'desc' => $status, ], ['type' => 'sectionend', 'id' => 'pickupselect_connected'], [ 'title' => __('Shipping methods', 'pickupselect'), 'type' => 'title', 'id' => 'pickupselect_methods', 'desc' => self::methods_overview(), ], [ 'title' => __('Shipping address', 'pickupselect'), 'id' => 'pickupselect_point_as_shipping', 'type' => 'checkbox', 'default' => 'yes', 'desc' => __('Use the selected pickup point as the order\'s shipping address', 'pickupselect'), 'desc_tip' => __('The point then appears as the shipping address in emails, the customer\'s account, the admin and exports. The customer\'s name and phone stay; their own shipping address is kept in the order data.', 'pickupselect'), ], ['type' => 'sectionend', 'id' => 'pickupselect_methods'], [ 'title' => __('Appearance', 'pickupselect'), 'type' => 'title', 'id' => 'pickupselect_widget', 'desc' => __('The look of the map. Saved in PickupSelect.', 'pickupselect'), ], ['type' => PickupSelect_Widget_Settings::FIELD_TYPE, 'id' => 'pickupselect_widget_editor'], ['type' => 'sectionend', 'id' => 'pickupselect_widget'], ]; } // kézi beállítás: a PickupSelect dashboardon létrehozott kulcsok; a WordPress csak szűkít (a widgetben engedélyezettek közül) private static function manual_settings(): array { return [ [ 'title' => __('Manual setup', 'pickupselect'), 'type' => 'title', 'id' => 'pickupselect_options', 'desc' => sprintf( /* translators: 1: dashboard link, 2: this shop's origin */ __('Create a widget and an API key in the %1$s. Add this shop\'s address, %2$s, to the API key\'s allowed origins.', 'pickupselect'), '' . esc_html__('PickupSelect dashboard', 'pickupselect') . '', '' . esc_html(self::shop_origin()) . '' ), ], [ 'title' => __('API key', 'pickupselect'), 'id' => 'pickupselect_api_key', 'type' => 'text', 'placeholder' => 'pk_…', 'css' => 'min-width: 420px;', ], [ 'title' => __('Widget key', 'pickupselect'), 'id' => 'pickupselect_widget_key', 'type' => 'text', 'placeholder' => 'wk_…', 'css' => 'min-width: 420px;', ], [ 'title' => __('PickupSelect server', 'pickupselect'), 'id' => 'pickupselect_origin', 'type' => 'url', 'default' => self::DEFAULT_ORIGIN, 'desc' => __('Only change this for testing.', 'pickupselect'), 'css' => 'min-width: 420px;', ], ['type' => 'sectionend', 'id' => 'pickupselect_options'], [ 'title' => __('Shipping methods', 'pickupselect'), 'type' => 'title', 'id' => 'pickupselect_methods', 'desc' => self::methods_overview(), ], [ 'title' => __('Shipping address', 'pickupselect'), 'id' => 'pickupselect_point_as_shipping', 'type' => 'checkbox', 'default' => 'yes', 'desc' => __('Use the selected pickup point as the order\'s shipping address', 'pickupselect'), 'desc_tip' => __('The point then appears as the shipping address in emails, the customer\'s account, the admin and exports. The customer\'s name and phone stay; their own shipping address is kept in the order data.', 'pickupselect'), ], ['type' => 'sectionend', 'id' => 'pickupselect_methods'], [ 'title' => __('Appearance', 'pickupselect'), 'type' => 'title', 'id' => 'pickupselect_appearance', 'desc' => __('Leave empty to use the widget\'s settings from the PickupSelect dashboard.', 'pickupselect'), ], [ 'title' => __('Theme', 'pickupselect'), 'id' => 'pickupselect_theme', 'type' => 'select', 'default' => '', 'options' => [ '' => __('Widget default', 'pickupselect'), 'light' => __('Light', 'pickupselect'), 'dark' => __('Dark', 'pickupselect'), ], ], [ 'title' => __('Primary colour', 'pickupselect'), 'id' => 'pickupselect_primary_color', 'type' => 'color', 'default' => '', 'css' => 'width: 6em;', ], [ 'title' => __('Secondary colour', 'pickupselect'), 'id' => 'pickupselect_secondary_color', 'type' => 'color', 'default' => '', 'css' => 'width: 6em;', ], ['type' => 'sectionend', 'id' => 'pickupselect_appearance'], ]; } /** * A beállított "Pickup point (PickupSelect)" módok zónánként (név, szállítók, díj), és hogyan kell újat felvenni. */ private static function methods_overview(): string { $zonesUrl = admin_url('admin.php?page=wc-settings&tab=shipping'); $html = '

' . esc_html__('Add "Pickup point (PickupSelect)" to your shipping zones once for each carrier you offer, e.g. "GLS parcel locker" and "Packeta pickup point". Each has its own carrier, point types, price, free shipping amount and limits. The customer chooses the method, then a point of that carrier on the map.', 'pickupselect') . '

'; $rows = ''; $zones = WC_Shipping_Zones::get_zones(); $zones[] = ['zone_name' => __('Locations not covered by your other zones', 'pickupselect'), 'shipping_methods' => (new WC_Shipping_Zone(0))->get_shipping_methods(), 'id' => 0]; foreach ($zones as $zone) { foreach ($zone['shipping_methods'] ?? [] as $method) { if ($method->id !== self::METHOD_ID) { continue; } $carriers = (array) $method->get_option('carriers', []); $cost = (string) $method->get_option('cost', ''); $editUrl = add_query_arg(['zone_id' => (int) ($zone['id'] ?? $zone['zone_id'] ?? 0)], $zonesUrl); $rows .= '' . esc_html((string) ($zone['zone_name'] ?? '')) . '' . '' . esc_html($method->get_title()) . '' . ($method->is_enabled() ? '' : ' (' . esc_html__('disabled', 'pickupselect') . ')') . '' . '' . esc_html($carriers ? implode(', ', $carriers) : __('All carriers', 'pickupselect')) . '' . '' . esc_html($cost === '' ? '–' : $cost) . ''; } } if ($rows !== '') { $html .= '' . $rows . '
' . esc_html__('Zone', 'pickupselect') . '' . esc_html__('Shipping method', 'pickupselect') . '' . esc_html__('Carriers', 'pickupselect') . '' . esc_html__('Cost', 'pickupselect') . '
'; } else { $html .= '

' . esc_html__('No pickup point shipping method yet.', 'pickupselect') . '

'; } // a választható szállítók listája 12 óráig tárolt: új szállító vagy widget változás után újratölthető $refreshUrl = wp_nonce_url(admin_url('admin-post.php?action=pickupselect_refresh_catalog'), 'pickupselect_refresh_catalog'); return $html . '

' . esc_html__('Shipping zones', 'pickupselect') . ' ' . '' . esc_html__('Refresh carriers from PickupSelect', 'pickupselect') . '

'; } // a PickupSelect szerver a WordPress szerver felől. A helyi tesztboltban a konténerből a "localhost" nem a PickupSelect, // ezért a PICKUPSELECT_SERVER_ORIGIN (docker-compose.yml) csak helyi című szervernél lép a helyére; az éles // pickupselect.com-ot a szerver is ugyanott éri el, mint a böngésző (különben a böngésző és a szerver más PickupSelectet látna) public static function server_origin(): string { return self::server_origin_for(self::origin()); } public static function server_origin_for(string $origin): string { $host = (string) wp_parse_url($origin, PHP_URL_HOST); $local = in_array($host, ['localhost', '127.0.0.1', '::1'], true) || str_ends_with($host, '.localhost'); return $local && defined('PICKUPSELECT_SERVER_ORIGIN') ? untrailingslashit(PICKUPSELECT_SERVER_ORIGIN) : $origin; } public static function refresh_catalog(): void { if (!current_user_can('manage_woocommerce')) { wp_die(esc_html__('You are not allowed to do this.', 'pickupselect'), 403); } check_admin_referer('pickupselect_refresh_catalog'); PickupSelect_Catalog::forget(); wp_safe_redirect(admin_url('admin.php?page=wc-settings&tab=shipping§ion=pickupselect')); exit; } public static function action_links(array $links): array { $url = admin_url('admin.php?page=wc-settings&tab=shipping§ion=pickupselect'); array_unshift($links, '' . esc_html__('Settings', 'pickupselect') . ''); return $links; } public static function origin(): string { $origin = trim((string) get_option('pickupselect_origin', self::DEFAULT_ORIGIN)); return untrailingslashit($origin !== '' ? $origin : self::DEFAULT_ORIGIN); } // a bolt originje, ahogy a böngésző az Origin fejlécben küldi (ezt kell a PickupSelect API kulcsnál engedélyezni) public static function shop_origin(): string { $parts = wp_parse_url(home_url()); $port = isset($parts['port']) ? ':' . $parts['port'] : ''; return ($parts['scheme'] ?? 'https') . '://' . ($parts['host'] ?? '') . $port; } public static function register_scripts(): void { if (!function_exists('is_checkout') || !is_checkout()) { return; } // a betöltő a saját címéről tölti a widgetet, ezért normál script tagként kell beilleszteni // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- a PickupSelect szolgáltatás betöltője, a szerver gondoskodik a frissességéről wp_register_script('pickupselect-widget', self::origin() . '/map-widget.js', [], null, ['in_footer' => true]); wp_register_script( 'pickupselect-common', PICKUPSELECT_URL . 'assets/js/pickupselect-common.js', ['pickupselect-widget'], PICKUPSELECT_VERSION, ['in_footer' => true] ); wp_localize_script('pickupselect-common', 'pickupselectConfig', self::script_config()); wp_register_style('pickupselect', PICKUPSELECT_URL . 'assets/css/pickupselect.css', [], PICKUPSELECT_VERSION); } public static function script_config(): array { return [ 'apiKey' => (string) get_option('pickupselect_api_key', ''), 'widgetKey' => (string) get_option('pickupselect_widget_key', ''), // szállítási mód példányonként a térkép: országok, szállítók, pont típusok (override-ok) és az országkódok 'instances' => self::instances_config(), 'configOverrides' => self::config_overrides(), // a választott pont a szerverre (a díjhoz), a klasszikus pénztárból 'pointUrl' => PickupSelect_Selection::ajax_url(), 'pointNonce' => PickupSelect_Selection::nonce(), // a munkamenetben lévő pont (pl. az oldal újratöltése után): erre számolódott a díj, a térkép ezt jelöli ki 'selectedPoint' => PickupSelect_Selection::get(), 'methodId' => self::METHOD_ID, 'i18n' => [ 'selected' => __('Selected pickup point:', 'pickupselect'), 'notConfigured' => __('Pickup point selection is not configured yet (missing API key or widget key).', 'pickupselect'), 'pointError' => __('The pickup point could not be saved. Please select it again.', 'pickupselect'), ], ]; } private static function instances_config(): array { $instances = []; foreach (PickupSelect_Carriers::instance_ids() as $id) { $instances[(string) $id] = [ 'overrides' => PickupSelect_Carriers::overrides($id), 'countries' => PickupSelect_Carriers::for_instance($id)['codes'], ]; } return $instances; } // megjelenés: csak a megadott értékek, a többi a widget beállítása marad; kapcsolt boltban a widget saját beállítása érvényes private static function config_overrides(): array { $config = []; if (PickupSelect_Connection::is_connected()) { return $config; } foreach (['theme', 'primary_color', 'secondary_color'] as $key) { $value = (string) get_option('pickupselect_' . $key, ''); if ($value !== '') { $config[$key] = $value; } } return $config; } // a kiválasztott szállítási módok között van-e PickupSelect (rate id: "pickupselect:") public static function is_pickupselect_rate(?string $rateId): bool { return $rateId !== null && str_starts_with($rateId, self::METHOD_ID . ':'); } public static function chosen_rate_is_pickupselect(): bool { $chosen = WC()->session ? (array) WC()->session->get('chosen_shipping_methods', []) : []; foreach ($chosen as $rateId) { if (self::is_pickupselect_rate((string) $rateId)) { return true; } } return false; } public static function order_uses_pickupselect(WC_Order $order): bool { foreach ($order->get_shipping_methods() as $item) { if ($item->get_method_id() === self::METHOD_ID) { return true; } } return false; } }