result( false, __( 'کد اتصال درست نیست. شکلش این است: RF1-XXXX-XXXX-XXXX', 'rahkar-toolkit' ) ); } $response = ( new HubClient() )->postUnsigned( 'connect', [ 'pairing_code' => $code, 'site' => [ 'url' => home_url(), 'name' => (string) get_bloginfo( 'name' ), 'platform' => 'woocommerce', 'platform_version' => defined( 'WC_VERSION' ) ? (string) WC_VERSION : 'unknown', 'wp_version' => (string) get_bloginfo( 'version' ), 'php_version' => PHP_VERSION, 'plugin_version' => RAHKAR_WP_VERSION, 'pro_version' => defined( 'RAHKAR_WP_PRO_VERSION' ) ? (string) RAHKAR_WP_PRO_VERSION : null, 'currency' => function_exists( 'get_woocommerce_currency' ) ? (string) get_woocommerce_currency() : 'IRT', 'timezone' => wp_timezone_string(), ], ] ); if ( 201 !== $response->status ) { return $this->result( false, $this->connectError( $response ) ); } $storeId = is_string( $response->body['store_id'] ?? null ) ? $response->body['store_id'] : ''; $secret = is_string( $response->body['secret'] ?? null ) ? $response->body['secret'] : ''; if ( '' === $storeId || '' === $secret ) { return $this->result( false, __( 'پاسخ هاب کامل نبود. دوباره امتحان کنید.', 'rahkar-toolkit' ) ); } Credentials::save( $storeId, $secret ); State::reset(); $limits = is_array( $response->body['limits'] ?? null ) ? $response->body['limits'] : []; ( new State() )->update( [ 'status' => State::OK, 'max_events' => max( 1, (int) ( $limits['max_events'] ?? 500 ) ), 'clock_offset' => null !== $response->hubTime() ? $response->hubTime() - time() : 0, ] ); Settings::set( self::SWITCH, true ); Manifest::rebuild(); // History first, then everything new as it happens; and the daily safety net. Backfill::start(); Reconciler::schedule(); Logger::info( 'hub', 'Connected to the hub.', [ 'store' => $storeId ] ); return $this->result( true, __( 'اتصال برقرار شد. ارسال سفارش‌های قبلی در پس‌زمینه شروع شد.', 'rahkar-toolkit' ) ); } /** * Disconnect: forget the key and drop everything unsent. * * @return array{ok: bool, message: string} */ public function disconnect(): array { $credentials = Credentials::load(); // Best effort: tell the hub to revoke the key now. If it is unreachable the // key is forgotten here anyway, and nothing more is sent. if ( null !== $credentials ) { ( new HubClient() )->signed( 'POST', 'disconnect', '', $credentials, ( new State() )->clockOffset() ); } self::forgetLocally(); Logger::info( 'hub', 'Disconnected from the hub by an administrator.', [] ); return $this->result( true, __( 'اتصال قطع شد و چیزی از این سایت به هاب فرستاده نمی‌شود.', 'rahkar-toolkit' ) ); } /** * Clear every trace of the connection on this site. */ public static function forgetLocally(): void { Credentials::forget(); State::reset(); Outbox::clear(); Settings::set( self::SWITCH, false ); Manifest::rebuild(); } /** * Ask the hub how it sees this store. * * @return array|null Null when not connected or unreachable. */ public function remoteStatus(): ?array { $credentials = Credentials::load(); if ( null === $credentials ) { return null; } $response = ( new HubClient() )->signed( 'GET', 'status', '', $credentials, ( new State() )->clockOffset() ); return 200 === $response->status ? $response->body : null; } /** * A message for a failed pairing. * * @param HubResponse $response The answer. */ private function connectError( HubResponse $response ): string { switch ( $response->code() ) { case 'pairing_invalid': return __( 'این کد نامعتبر، منقضی یا قبلاً استفاده‌شده است. از پنل راهکار فروش یک کد تازه بگیرید.', 'rahkar-toolkit' ); case 'site_mismatch': return __( 'این کد برای فروشگاهی با آدرس دیگری صادر شده است.', 'rahkar-toolkit' ); } if ( 429 === $response->status ) { return __( 'تلاش زیاد بود. یک دقیقه دیگر دوباره امتحان کنید.', 'rahkar-toolkit' ); } if ( 0 === $response->status ) { /* translators: %s: transport error */ return sprintf( __( 'به هاب وصل نشد: %s', 'rahkar-toolkit' ), $response->message() ); } /* translators: %s: hub answer */ return sprintf( __( 'هاب اتصال را نپذیرفت: %s', 'rahkar-toolkit' ), $response->message() ); } /** * Result shape. * * @param bool $ok Success. * @param string $message Message for the admin. * * @return array{ok: bool, message: string} */ private function result( bool $ok, string $message ): array { return [ 'ok' => $ok, 'message' => $message, ]; } }