Rapport-Laravel/app/Services/FirebaseQuestionService.php

232 lines
5.9 KiB
PHP

<?php
namespace App\Services;
use Illuminate\Support\Collection;
use Kreait\Firebase\Factory;
use Kreait\Firebase\Database;
class FirebaseQuestionService
{
protected Database $database;
public function __construct()
{
$credentialsPath = (string) config('services.firebase.credentials');
$databaseUrl = config('services.firebase.database_url');
if (!$credentialsPath || !file_exists($credentialsPath)) {
throw new \RuntimeException('Firebase credentials file not found.');
}
$factory = (new Factory())->withServiceAccount($credentialsPath);
if (!empty($databaseUrl)) {
$factory = $factory->withDatabaseUri($databaseUrl);
}
$this->database = $factory->createDatabase();
}
public function getQuestions(string $eventId, string $sessionId): Collection
{
$path = sprintf('events/%s/sessions/%s/questions', $eventId, $sessionId);
$value = $this->database->getReference($path)->getValue();
if (!is_array($value)) {
return collect();
}
return collect($value)
->map(function ($item, $key) {
if (is_array($item)) {
$item['firebase_key'] = $item['firebase_key'] ?? $key;
return $item;
}
return [
'firebase_key' => $key,
'question' => $item,
];
})
->values();
}
public function getTopQuestions(string $eventId, string $sessionId, int $limit = 5): Collection
{
return $this->sortQuestions($this->getQuestions($eventId, $sessionId))
->take($limit)
->values();
}
public function sortQuestions(Collection $questions): Collection
{
return $questions
->sort(function ($a, $b) {
$aScore = $this->score($a);
$bScore = $this->score($b);
if ($aScore === $bScore) {
return $this->timestamp($b) <=> $this->timestamp($a);
}
return $bScore <=> $aScore;
})
->values();
}
protected function score(array $item): int
{
$candidates = [
$item['likes'] ?? null,
$item['upvotes'] ?? null,
$item['votes'] ?? null,
$item['score'] ?? null,
];
foreach ($candidates as $candidate) {
if (is_numeric($candidate)) {
return (int) $candidate;
}
}
return 0;
}
protected function timestamp(array $item): int
{
$raw = $item['created_at'] ?? $item['createdAt'] ?? null;
if (is_numeric($raw)) {
return (int) $raw;
}
if (is_string($raw)) {
$parsed = strtotime($raw);
if ($parsed !== false) {
return $parsed;
}
}
return 0;
}
}
<?php
namespace App\Services;
use Illuminate\Support\Collection;
use Kreait\Firebase\Factory;
use Kreait\Firebase\Database;
class FirebaseQuestionService
{
protected Database $database;
public function __construct()
{
$credentialsPath = (string) config('services.firebase.credentials');
$databaseUrl = config('services.firebase.database_url');
if (!$credentialsPath || !file_exists($credentialsPath)) {
throw new \RuntimeException('Firebase credentials file not found.');
}
$factory = (new Factory())->withServiceAccount($credentialsPath);
if (!empty($databaseUrl)) {
$factory = $factory->withDatabaseUri($databaseUrl);
}
$this->database = $factory->createDatabase();
}
public function getQuestions(string $eventId, string $sessionId): Collection
{
$path = sprintf('events/%s/sessions/%s/questions', $eventId, $sessionId);
$value = $this->database->getReference($path)->getValue();
if (!is_array($value)) {
return collect();
}
return collect($value)
->map(function ($item, $key) {
if (is_array($item)) {
$item['firebase_key'] = $item['firebase_key'] ?? $key;
return $item;
}
return [
'firebase_key' => $key,
'question' => $item,
];
})
->values();
}
public function getTopQuestions(string $eventId, string $sessionId, int $limit = 5): Collection
{
return $this->sortQuestions($this->getQuestions($eventId, $sessionId))
->take($limit)
->values();
}
public function sortQuestions(Collection $questions): Collection
{
return $questions
->sort(function ($a, $b) {
$aScore = $this->score($a);
$bScore = $this->score($b);
if ($aScore === $bScore) {
return $this->timestamp($b) <=> $this->timestamp($a);
}
return $bScore <=> $aScore;
})
->values();
}
protected function score(array $item): int
{
$candidates = [
$item['likes'] ?? null,
$item['upvotes'] ?? null,
$item['votes'] ?? null,
$item['score'] ?? null,
];
foreach ($candidates as $candidate) {
if (is_numeric($candidate)) {
return (int) $candidate;
}
}
return 0;
}
protected function timestamp(array $item): int
{
$raw = $item['created_at'] ?? $item['createdAt'] ?? null;
if (is_numeric($raw)) {
return (int) $raw;
}
if (is_string($raw)) {
$parsed = strtotime($raw);
if ($parsed !== false) {
return $parsed;
}
}
return 0;
}
}