$title, 'post_content' => json_encode($data, JSON_UNESCAPED_UNICODE), 'post_status' => 'pending', 'post_type' => POLYLAI_POST_TYPE, ]; $post_id = wp_insert_post($post_data); if (is_wp_error($post_id)) { return false; // Errore nella creazione del post } add_post_meta($post_id, POLYLAI_SOURCE_ID, $source_post_id); return $post_id; } public function list_pending($type = null) { $status = 'pending'; $list = get_posts([ 'post_type' => POLYLAI_POST_TYPE, 'posts_per_page' => -1, 'post_status' => $status ]); if (!$type) { return $this->convert($list); } $filtered = []; foreach ($list as $item) { $data = json_decode($item->post_content); if ($data->service == $type) { $filtered[] = $item; } } return $this->convert($filtered); } public function list_pending_translating() { $posts = get_posts([ 'post_type' => POLYLAI_POST_TYPE, 'posts_per_page' => -1, 'post_status' => ['translating', 'pending'] ]); return $this->convert($posts); } /** * Get paginated history of translations * * @param int $page Current page number (starting from 1) * @param int $per_page Number of items per page * @return array An array containing 'items' and 'total_pages' */ public function list_history($page = 1, $per_page = 10) { $args = [ 'post_type' => POLYLAI_POST_TYPE, 'post_status' => ['complete', 'error'], 'posts_per_page' => $per_page, 'paged' => $page, 'orderby' => 'date', 'order' => 'DESC' ]; $query = new WP_Query($args); // Get the total number of posts $total_posts = $query->found_posts; $total_pages = ceil($total_posts / $per_page); return [ 'items' => $this->convert($query->posts), 'total_pages' => $total_pages, 'total_items' => $total_posts, 'current_page' => $page ]; } public function get_health_summary($stuck_threshold_minutes = 30) { $stuck_threshold_minutes = max(1, absint($stuck_threshold_minutes)); $statuses = ['pending', 'translating', 'complete', 'error']; $counts = []; foreach ($statuses as $status) { $counts[$status] = $this->count_jobs_by_status($status); } $stuck_jobs = $this->list_stuck_jobs($stuck_threshold_minutes); $counts['stuck'] = count($stuck_jobs); return [ 'counts' => $counts, 'stuck_threshold_minutes' => $stuck_threshold_minutes, 'stuck_jobs' => $stuck_jobs, ]; } private function count_jobs_by_status($status) { $query = new WP_Query([ 'post_type' => POLYLAI_POST_TYPE, 'post_status' => $status, 'posts_per_page' => 1, 'fields' => 'ids', 'no_found_rows' => false, ]); return (int) $query->found_posts; } private function list_stuck_jobs($stuck_threshold_minutes) { $cutoff = current_time('timestamp', true) - ($stuck_threshold_minutes * MINUTE_IN_SECONDS); $posts = get_posts([ 'post_type' => POLYLAI_POST_TYPE, 'posts_per_page' => -1, 'post_status' => 'translating', ]); $stuck = []; foreach ($posts as $post) { $modified_gmt = $post->post_modified_gmt ?: $post->post_date_gmt; $modified_timestamp = mysql2date('U', $modified_gmt, false); if ($modified_timestamp && $modified_timestamp <= $cutoff) { $stuck[] = [ 'id' => (int) $post->ID, 'title' => $post->post_title, 'modified_gmt' => $modified_gmt, ]; } } return $stuck; } /** * Convert a list of posts to a list of polylai_Translation * @param mixed $posts * @return polylai_Translation[] */ private function convert($posts) { return array_map(function ($item) { return new polylai_Translation($item); }, $posts); } public function set_completed($id) { wp_update_post([ 'ID' => $id, 'post_status' => 'complete' ]); } public function set_translating($id) { wp_update_post([ 'ID' => $id, 'post_status' => 'translating' ]); } public function set_status($id, $status, $error_code, $used_tokens, $fields=[]) { wp_update_post([ 'ID' => $id, 'post_status' => $status ]); polylai_Utils::db_log( 'debug', 'set_status', "$error_code $used_tokens", $id, null, "$used_tokens" ); if ($error_code != null || $used_tokens != null) { polylai_Utils::db_log( 'debug', 'set_status', "change", $id, null, "$used_tokens" ); $post = get_post($id); $data = json_decode($post->post_content); if ($error_code != null) { $data->error_code = $error_code; } if ($used_tokens != null) { $data->used_tokens = $used_tokens; } $data->fields = $fields; $post->post_content = json_encode($data, JSON_UNESCAPED_UNICODE); wp_update_post($post); } } public function get_from_list($list, $guid) { foreach ($list as $item) { if ($item->cloud_guid == $guid) { return $item; } } throw new Exception("guid $guid not found"); } }