(int) get_option( self::PAGE_OPTION, 0 ), 'tracking_url' => '', 'support_contact' => '', ]; } /** * {@inheritDoc} */ public function settingsSchema(): array { return [ 'page' => [ 'type' => 'select', 'label' => __( 'صفحه پیگیری سفارش', 'rahkar-toolkit' ), 'options' => $this->pageChoices(), 'help' => __( 'برگه‌ای که فرم پیگیری سفارش در آن نمایش داده می‌شود. کافی است یک برگه‌ی خالی بسازید و اینجا انتخابش کنید؛ فرم به‌طور خودکار به محتوای آن افزوده می‌شود. بهتر است نامک این برگه را tracking بگذارید.', 'rahkar-toolkit' ), 'default' => 0, ], 'tracking_url' => [ 'type' => 'text', 'label' => __( 'لینک رهگیری مرسوله پستی', 'rahkar-toolkit' ), 'help' => __( 'الگوی لینک پیگیری روی سایت شرکت پستی یا باربری، با {code} به‌جای کد رهگیری. مثال: https://tracking.post.ir/?id={code}. اگر خالی بماند، کد رهگیری فقط به‌صورت متن نمایش داده می‌شود.', 'rahkar-toolkit' ), 'default' => '', ], 'support_contact' => [ 'type' => 'text', 'label' => __( 'شماره تماس پشتیبانی', 'rahkar-toolkit' ), 'help' => __( 'وقتی سفارشی برای شماره وارد‌شده پیدا نشود، همین شماره به مشتری نشان داده می‌شود. اگر خالی بماند، چیزی نشان داده نمی‌شود.', 'rahkar-toolkit' ), 'default' => '', ], ]; } /** * {@inheritDoc} */ public function settingsSections(): array { return []; } /** * Published pages, for the page picker. Settings screen only. * * @return array */ private function pageChoices(): array { $choices = [ 0 => __( '— غیرفعال —', 'rahkar-toolkit' ) ]; // WooCommerce's shop, cart, checkout and account pages, and the front // and posts pages, already have a job; the form appended to one of them // would sit under a checkout or a product grid. Same list the login page // picker uses — this module requires otp_auth, so it is always there. $reserved = LoginPage::reservedPageIds(); foreach ( get_pages( [ 'post_status' => 'publish' ] ) ?: [] as $page ) { if ( ! in_array( (int) $page->ID, $reserved, true ) ) { $choices[ (int) $page->ID ] = $page->post_title; } } return $choices; } /** * Divert the page out of the settings row and into {@see self::PAGE_OPTION}. * * Runs on the row's own pre-update filter, so the generic settings save * needs no special case: whatever it writes, the page never lands in the * non-autoloaded row, and there is one stored value rather than two that * can disagree. * * @param mixed $value Settings payload about to be written. * * @return mixed */ public static function storePage( mixed $value ): mixed { if ( ! is_array( $value ) || ! array_key_exists( 'page', $value ) ) { return $value; } update_option( self::PAGE_OPTION, max( 0, (int) $value['page'] ), true ); unset( $value['page'] ); return $value; } /** * {@inheritDoc} */ public function register(): void { add_action( 'rest_api_init', static fn() => Plugin::make( TrackEndpoint::class )->registerRoutes() ); if ( ! is_admin() ) { return; } add_filter( 'pre_update_option_' . Settings::PREFIX . self::SLUG, [ self::class, 'storePage' ] ); add_action( 'woocommerce_admin_order_data_after_order_details', static fn( $order ) => Plugin::make( FulfilmentFields::class )->render( $order ) ); add_action( 'woocommerce_process_shop_order_meta', static fn( $orderId ) => Plugin::make( FulfilmentFields::class )->save( $orderId ) ); } }