Das Ergebnis. */ public static function run(): array { $repository = new JobRepository(); $jobs = $repository->all(); $hashes = array(); foreach ( $jobs as $job ) { if ( AivorClient::is_uuid( $job->aivor_job_id ) ) { $hashes[] = $job->aivor_job_id; } } $result = array( 'time' => time(), 'state' => self::STATE_OK, 'code' => 'ok_all', 'error' => '', 'credits' => null, ); try { $status = self::fetch_status( $hashes ); } catch ( ApiException $error ) { if ( $error->is_unknown_action() ) { // Die Key-Pruefung laeuft im Gateway vor der Action-Aufloesung: // Kommt „Action not found", ist der Key gueltig. $result['state'] = self::STATE_WARNING; $result['code'] = 'unknown_action'; } else { $result['state'] = self::STATE_ERROR; $result['code'] = 'error'; $result['error'] = $error->getMessage(); } update_option( self::OPTION, $result, false ); return $result; } $result['credits'] = isset( $status['credits_left'] ) ? (int) $status['credits_left'] : null; $by_hash = array(); foreach ( (array) ( $status['jobs'] ?? array() ) as $item ) { if ( is_array( $item ) && isset( $item['hash'] ) ) { $by_hash[ strtolower( (string) $item['hash'] ) ] = $item; } } $problems = 0; foreach ( $jobs as $job ) { $item = $by_hash[ $job->aivor_job_id ] ?? null; if ( null === $item ) { continue; } $changes = self::job_changes( $item ); $repository->update_fields( $job->id, $changes ); if ( 'ok' !== $changes['remote_status'] ) { ++$problems; } } if ( array() === $hashes ) { $result['code'] = 'ok_no_jobs'; } elseif ( $problems > 0 ) { $result['state'] = self::STATE_WARNING; $result['code'] = 'jobs_need_attention'; } update_option( self::OPTION, $result, false ); return $result; } /** * Fragt den Stand ab, in Bloecken zu je 50 Jobs (Grenze des Servers). * * @param string[] $hashes Import-Job-IDs. * @return array jobs und credits_left wie in einer Antwort. * @throws ApiException Wenn eine Abfrage scheitert. */ private static function fetch_status( array $hashes ): array { $client = AivorClient::from_settings(); $status = array( 'jobs' => array(), 'credits_left' => null, ); // Auch ohne Job einmal fragen: Das ist der eigentliche Verbindungstest. foreach ( array() === $hashes ? array( array() ) : array_chunk( $hashes, 50 ) as $chunk ) { $part = $client->plugin_status( $chunk ); $status['jobs'] = array_merge( $status['jobs'], (array) ( $part['jobs'] ?? array() ) ); $status['credits_left'] = $part['credits_left'] ?? $status['credits_left']; } return $status; } /** * Prueft einen einzelnen Job, etwa direkt nach dem Speichern. * * @param Job $job Der Job. * @return string Status: ok, not_found, forbidden, invalid oder unknown. */ public static function check_job( Job $job ): string { try { $status = AivorClient::from_settings()->plugin_status( array( $job->aivor_job_id ) ); } catch ( ApiException $error ) { return 'unknown'; } foreach ( (array) ( $status['jobs'] ?? array() ) as $item ) { if ( is_array( $item ) && strtolower( (string) ( $item['hash'] ?? '' ) ) === $job->aivor_job_id ) { $changes = self::job_changes( $item ); ( new JobRepository() )->update_fields( $job->id, $changes ); return $changes['remote_status']; } } return 'unknown'; } /** * Die Meldung zum Ergebnis — in der Sprache dessen, der sie liest. * * Gespeichert wird nur der Code; uebersetzt wird beim Anzeigen. Sonst * stuende die Meldung in der Sprache dessen, der zuletzt geprueft hat. * * @param array $result Ergebnis aus last(). * @return string */ public static function message( array $result ): string { switch ( (string) ( $result['code'] ?? '' ) ) { case 'ok_all': return __( 'Connected to Aivor. All content jobs were found.', 'aivor-content-import' ); case 'ok_no_jobs': return __( 'Connected to Aivor. Next, add a content job with the import job ID from Aivor.', 'aivor-content-import' ); case 'jobs_need_attention': return __( 'Connected to Aivor, but at least one content job needs attention. See the list of content jobs.', 'aivor-content-import' ); case 'unknown_action': return __( 'The API key works. This Aivor server does not offer the detailed status check yet, so the content jobs could not be checked.', 'aivor-content-import' ); default: return (string) ( $result['error'] ?? '' ); } } /** * Das Ergebnis der letzten Pruefung. * * @return array */ public static function last(): array { $stored = get_option( self::OPTION, array() ); return is_array( $stored ) ? $stored : array(); } /** * Die Anzeigefelder eines Jobs aus der Serverantwort. * * @param array $item Eintrag aus content/plugin-status. * @return array */ private static function job_changes( array $item ): array { $status = in_array( $item['status'] ?? '', array( 'ok', 'not_found', 'forbidden', 'invalid' ), true ) ? (string) $item['status'] : 'unknown'; $site = isset( $item['site'] ) && is_array( $item['site'] ) ? $item['site'] : array(); return array( 'remote_status' => $status, 'remote_name' => 'ok' === $status ? sanitize_text_field( (string) ( $item['name'] ?? '' ) ) : '', 'remote_site_url' => 'ok' === $status ? esc_url_raw( (string) ( $site['base_url'] ?? '' ) ) : '', 'checked_at' => time(), ); } }