MIF_E31231313/Website/s_gizi/app/Http/Controllers/Api/NewsController.php

126 lines
4.8 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
class NewsController extends Controller
{
public function index(Request $request): JsonResponse
{
$query = trim((string) $request->query('q', 'gizi balita stunting makanan sehat balita'));
$url = 'https://news.google.com/rss/search';
$response = Http::timeout(12)->get($url, [
'q' => $query,
'hl' => 'id',
'gl' => 'ID',
'ceid' => 'ID:id',
]);
if (!$response->ok()) return $this->empty($query);
$xml = @simplexml_load_string($response->body());
if (!$xml || !isset($xml->channel->item)) return $this->empty($query);
$allowedCategories = [
'Stunting',
'MPASI',
'Nutrisi Anak',
'Protein',
'Vitamin',
'Parenting Anak',
'Kesehatan Balita',
];
$articles = collect($xml->channel->item)
->values()
->map(function ($item, $index) {
$rawTitle = trim((string) $item->title);
$description = trim(strip_tags((string) $item->description));
$content = mb_strlen($description) > 320
? mb_substr($description, 0, 320) . '...'
: $description;
$excerpt = mb_strlen($description) > 140
? mb_substr($description, 0, 160) . '...'
: $description;
[$title, $sourceName] = $this->splitTitleSource($rawTitle);
$category = $this->detectCategory($title . ' ' . $description);
return [
'id' => $index + 1,
'title' => $title !== '' ? $title : 'Artikel Gizi Balita',
'image' => $this->extractImageUrl((string) $item->description),
'category' => $category,
'description' => $excerpt !== '' ? $excerpt : 'Informasi terbaru seputar gizi balita dan pencegahan stunting.',
'content' => $content !== '' ? $content : 'Baca artikel lengkap pada sumber berita.',
'created_at' => (string) $item->pubDate,
'source_name' => $sourceName,
'source' => 'google_news',
'country' => 'id',
'url' => (string) $item->link,
];
})
->filter(function ($article) use ($allowedCategories) {
return in_array($article['category'], $allowedCategories, true);
})
->take(12)
->values();
return response()->json([
'source' => 'news_api_filtered',
'country' => 'id',
'query' => $query,
'data' => $articles,
]);
}
private function empty(string $query): JsonResponse
{
return response()->json([
'source' => 'news_api_filtered',
'country' => 'id',
'query' => $query,
'data' => [],
]);
}
private function extractImageUrl(string $descriptionHtml): ?string
{
if (preg_match('/<img[^>]+src="([^">]+)"/i', $descriptionHtml, $match)) {
return trim((string) ($match[1] ?? '')) ?: null;
}
return null;
}
private function detectCategory(string $text): string
{
$value = mb_strtolower($text);
if (str_contains($value, 'stunting')) return 'Stunting';
if (str_contains($value, 'mpasi')) return 'MPASI';
if (str_contains($value, 'protein') || str_contains($value, 'ikan') || str_contains($value, 'telur')) return 'Protein';
if (str_contains($value, 'vitamin') || str_contains($value, 'mineral') || str_contains($value, 'mikronutrien')) return 'Vitamin';
if (str_contains($value, 'parenting') || str_contains($value, 'pola asuh') || str_contains($value, 'orang tua')) return 'Parenting Anak';
if (str_contains($value, 'balita') || str_contains($value, 'tumbuh kembang') || str_contains($value, 'imunisasi')) return 'Kesehatan Balita';
if (str_contains($value, 'gizi') || str_contains($value, 'nutrisi') || str_contains($value, 'who nutrition')) return 'Nutrisi Anak';
return 'Nutrisi Anak';
}
private function splitTitleSource(string $rawTitle): array
{
$title = trim($rawTitle);
$source = null;
if (str_contains($rawTitle, ' - ')) {
$parts = explode(' - ', $rawTitle);
if (count($parts) >= 2) {
$source = trim((string) array_pop($parts));
$title = trim(implode(' - ', $parts));
}
}
return [$title, $source];
}
}