// ============================= // 3. Fetch & Save News Logic // ============================= /** * Fetches news from SerpAPI based on configured project types and country, * then saves them as draft posts, preventing duplicates. * The fetch is strictly limited to the last 24 hours. * * @return array An array of status/error messages for display. */ function serpapi_fetch_and_save_energy_news() { $status = []; $api_key = get_option('serpapi_api_key'); if (!$api_key) { $status[] = ['type' => 'error', 'message' => 'SerpAPI Key is missing in settings. Please configure it.']; error_log('SerpAPI News Importer: API key is missing. Skipping fetch.'); return $status; } $project_types = get_option('serpapi_project_types', 'affordable housing, stadium, arena, solar, wind, airport, seaport, BESS, datacenters'); $types_array = array_map('trim', explode(',', $project_types)); if (empty(array_filter($types_array))) { $status[] = ['type' => 'notice', 'message' => 'Project Types are empty. Please specify comma-separated project types in settings.']; return $status; } // Wrap each type in quotes for exact phrase matching $quoted_types = array_map(function($type) { $sanitized_type = sanitize_text_field($type); return !empty($sanitized_type) ? '"' . $sanitized_type . '"' : ''; }, $types_array); $quoted_types = array_filter($quoted_types); if (empty($quoted_types)) { $status[] = ['type' => 'notice', 'message' => 'No valid project types found after sanitization.']; return $status; } $query = '(' . implode(' OR ', $quoted_types) . ') project'; $country = sanitize_text_field(get_option('serpapi_country', '')); if (!empty($country)) { $query .= ' "' . $country . '"'; } // 1. API Level Filter: Add '&tbs=qdr:d' to instruct Google News to only return results from the last day. // Also add '&num=100' to instruct SerpAPI to return 100 results. $url = "https://serpapi.com/search?engine=google_news&q=" . urlencode($query) . "&tbs=qdr:d&num=100&hl=en&lr=lang_en&api_key=$api_key"; // DEBUG: Add the query URL to the status messages $status[] = ['type' => 'query_url', 'message' => $url]; $response = wp_remote_get($url, ['timeout' => 30]); if (is_wp_error($response)) { $status[] = ['type' => 'error', 'message' => 'WordPress HTTP Error: Could not connect to SerpAPI. Message: ' . $response->get_error_message()]; error_log('SerpAPI News Importer: WP_Error encountered: ' . $response->get_error_message()); return $status; } $http_status = wp_remote_retrieve_response_code($response); if ($http_status !== 200) { $status[] = ['type' => 'error', 'message' => "SerpAPI HTTP Error: Request failed with status code $http_status. Check API key validity."]; error_log("SerpAPI News Importer: HTTP Error: $http_status. URL: $url"); return $status; } $body = wp_remote_retrieve_body($response); $data = json_decode($body, true); if (isset($data['error'])) { $status[] = ['type' => 'error', 'message' => 'SerpAPI returned an error: ' . $data['error']]; error_log('SerpAPI News Importer: API Error: ' . $data['error']); return $status; } if (!isset($data['news_results']) || !is_array($data['news_results'])) { $status[] = ['type' => 'notice', 'message' => 'SerpAPI returned no news results for the current query/settings.']; return $status; } $total_articles_fetched = count($data['news_results']); $filtered_by_time = 0; $filtered_by_duplicate = 0; $cutoff = strtotime('-1 day'); $post_count = 0; $max_posts = 100; // 🎯 CHANGED FROM 50 TO 100 foreach ($data['news_results'] as $article) { if ($post_count >= $max_posts) break; if (!isset($article['title']) || !isset($article['link'])) continue; $title = sanitize_text_field($article['title']); $link = esc_url_raw($article['link']); $summary = isset($article['snippet']) ? wp_strip_all_tags($article['snippet']) : 'No summary available.'; $published_str = isset($article['date']) ? $article['date'] : ''; if (empty($title) || empty($link)) continue; // --- ROBUST DATE PARSING AND SECONDARY PHP TIME CHECK --- // Date format from SerpAPI is "MM/DD/YYYY, HH:MM PM/AM, +0000 UTC" $date_format = 'm/d/Y, h:i A, P T'; $datetime_obj = DateTime::createFromFormat($date_format, $published_str); $published_time = false; if ($datetime_obj) { // Get the Unix timestamp from the successfully parsed object $published_time = $datetime_obj->getTimestamp(); } // If parsing failed (returns false) OR the date is older than 24 hours, skip. if (!$published_time || $published_time < $cutoff) { $filtered_by_time++; continue; } // -------------------------------- // Prevent duplicate via URL meta key $existing = get_posts([ 'meta_key' => 'serpapi_source_url', 'meta_value' => $link, 'post_type' => 'post', 'fields' => 'ids', 'posts_per_page' => 1 ]); if ($existing) { $filtered_by_duplicate++; continue; } // Construct the post content $post_content = wpautop( 'Summary: ' . esc_html($summary) . '

' . 'Source: ' . esc_html($link) . '' ); $author_id = intval(get_option('serpapi_post_author', get_current_user_id())); $post_id = wp_insert_post([ 'post_title' => $title, 'post_content' => $post_content, 'post_status' => 'draft', // Save as draft for review 'post_author' => $author_id, ], true); if (!is_wp_error($post_id)) { update_post_meta($post_id, 'serpapi_source_url', $link); $post_count++; } else { $status[] = ['type' => 'error', 'message' => 'Error inserting post into database: ' . $post_id->get_error_message()]; error_log('SerpAPI News Importer: Error inserting post: ' . $post_id->get_error_message()); } } // UPDATED: Include filtering counts in the success message $status[] = ['type' => 'success', 'message' => "News import process completed. Fetched {$total_articles_fetched} articles from API. Imported {$post_count} posts as Drafts. Filtered {$filtered_by_time} by age and {$filtered_by_duplicate} as duplicates."]; return $status; } KURA signs US $132m deal for stalled roads projects
Last Updated: Aug 15, 2021
Home » Transport » Roads » KURA signs US $132m deal for stalled roads projects

KURA signs US $132m deal for stalled roads projects

Home » Transport » Roads » KURA signs US $132m deal for stalled roads projects

The Kenya Urban Roads Authority has signed a US $132m deal with a consortium of Lee Construction Limited, Cape Construction and Moto Engil Africa for the construction and maintenance of stalled roads in Western and Central Kenya.

KURA Director General, Silas Kinoti  said that the deal breathes a new lease of life for the Roads Annuity Program which has been facing a number of interlocking challenges mainly defined by inadequacy of financing partners.

Also Read:Nigeria set to reconstruct Oko-Oba GRA roads

Roads projects

The two Private Public Partnership (PPP) agreements will oversee the construction and maintenance of roads across ten counties. Under the new deal are Riamukurwe-Gatitu road in Nyeri County, Kanjuki-Mauktano road in Tharaka-Nithi and the Busia-Alupe bypass in Western Kenya.

The project that will cover 80-kilometres of road will continue for the next decade. The government had an initial plan of completing 2000 kilometers of road within the 2014/15 financial year.

Other key road projects highlighted under the Road Annuity Project include the dual-ling of the Nairobi-Mombasa highway with the commercial contract already in place, the second Nyali Bridge in Mombasa and the Nairobi-Narok-Mau Summit highway.

A further 8000 kilometers of road was to be revamped in subsequent years only for the project to run into financing headwinds. The challenges were inflated costs, credit-worthiness queries by lenders and the snail-pace of contracts approvals.

“Roads under construction currently stand at 6,400 kilometers. Once we start the construction of a road; we are due to finish it. We hope to get to the 10,000 kilometers stock over the next two years,” said Transport CS James Macharia.

Partnerships with the private sector

Cognizant of the dependency of infrastructure financing on the annual budget, the Cabinet approved partnerships with the private sector in March 2015. This was done with the objective of developing and rehabilitating 10,000 kilometers of road through long-term contracts.

“Despite of the evolving challenges, KURA remains keen on the private-public initiated financing reading benefits for contractors, bankers, consultants and equipment suppliers. We are confident that the lot of annuity projects will result in greater economic benefits to the beneficiary urban counties,” said Silas Kinoti.

 

Leave a Comment