137 lines
5.0 KiB
PHP
137 lines
5.0 KiB
PHP
<?php declare(strict_types=1);
|
|
/**
|
|
* This file is part of the SplendidBear Websites' projects.
|
|
*
|
|
* Copyright (c) 2026 @ www.splendidbear.org
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace App\Dto;
|
|
|
|
use App\Entity\PlayedGame;
|
|
use App\Entity\RecentBattle;
|
|
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
|
|
|
|
/**
|
|
* Class ProfileGameDtoFactory
|
|
*
|
|
* @package App\Dto
|
|
* @author Lang <https://www.splendidbear.org>
|
|
* @category Class
|
|
* @license https://www.gnu.org/licenses/lgpl-3.0.en.html GNU Lesser General Public License
|
|
* @link www.splendidbear.org
|
|
* @since 2026. 04. 20.
|
|
*/
|
|
final readonly class ProfileGameDtoFactory
|
|
{
|
|
public function __construct(private CacheManager $cacheManager) { }
|
|
|
|
public function create(PlayedGame $game, int $userId): ProfileGameDto
|
|
{
|
|
$isRed = $game->red?->id === $userId;
|
|
$resign = $game->resign;
|
|
$myColor = $isRed ? 'red' : 'blue';
|
|
$oppColor = $isRed ? 'blue' : 'red';
|
|
$myPts = $isRed ? $game->redPoints : $game->bluePoints;
|
|
$oppPts = $isRed ? $game->bluePoints : $game->redPoints;
|
|
|
|
$redAvatarPath = $game->red?->avatarPath;
|
|
$blueAvatarPath = $game->blue?->avatarPath;
|
|
|
|
return new ProfileGameDto(
|
|
id: $game->id,
|
|
uuid: $game->uuid?->toRfc4122(),
|
|
redName: $game->red?->getUsername() ?? $game->redAnon?->userName ?? 'Guest',
|
|
blueName: $game->blue?->getUsername() ?? $game->blueAnon?->userName ?? 'Guest',
|
|
redAvatar: $redAvatarPath ? $this->cacheManager->generateUrl($redAvatarPath, 'avatar_thumb') : null,
|
|
blueAvatar: $blueAvatarPath ? $this->cacheManager->generateUrl($blueAvatarPath, 'avatar_thumb') : null,
|
|
redPoints: $game->redPoints,
|
|
bluePoints: $game->bluePoints,
|
|
redExplodedBomb: $game->redExplodedBomb,
|
|
blueExplodedBomb: $game->blueExplodedBomb,
|
|
resign: $resign,
|
|
created: $game->created?->format('Y-m-d H:i'),
|
|
date: $game->updated?->format('Y-m-d H:i'),
|
|
isRed: $isRed,
|
|
result: $this->resolveResult($resign, $myColor, $oppColor, $myPts, $oppPts),
|
|
myPoints: $myPts,
|
|
oppPoints: $oppPts,
|
|
redBonusPoints: $game->redBonusPoints ?? 0.0,
|
|
blueBonusPoints: $game->blueBonusPoints ?? 0.0,
|
|
redBonusStats: $game->redBonusStats ?? [],
|
|
blueBonusStats: $game->blueBonusStats ?? [],
|
|
bothRegistered: $game->red !== null && $game->blue !== null,
|
|
);
|
|
}
|
|
|
|
private function resolveResult(
|
|
?string $resign,
|
|
string $myColor,
|
|
string $oppColor,
|
|
?int $myPts,
|
|
?int $oppPts,
|
|
): string {
|
|
if ($resign === $myColor) {
|
|
return 'loss';
|
|
}
|
|
|
|
if ($resign === $oppColor) {
|
|
return 'win';
|
|
}
|
|
|
|
if ($myPts !== null && $oppPts !== null) {
|
|
if ($myPts > $oppPts) {
|
|
return 'win';
|
|
}
|
|
|
|
if ($myPts < $oppPts) {
|
|
return 'loss';
|
|
}
|
|
}
|
|
|
|
return 'draw';
|
|
}
|
|
|
|
/**
|
|
* Build a ProfileGameDto directly from the recent_battles materialized view row.
|
|
* Avatar paths are still resolved via LiipImagine (they are stored as storage paths).
|
|
*/
|
|
public function createFromRecentBattle(RecentBattle $battle): ProfileGameDto
|
|
{
|
|
$myPts = $battle->isRed ? $battle->redPoints : $battle->bluePoints;
|
|
$oppPts = $battle->isRed ? $battle->bluePoints : $battle->redPoints;
|
|
|
|
return new ProfileGameDto(
|
|
id: $battle->gameId,
|
|
uuid: $battle->uuid,
|
|
redName: $battle->redName,
|
|
blueName: $battle->blueName,
|
|
redAvatar: $battle->redAvatarPath
|
|
? $this->cacheManager->generateUrl($battle->redAvatarPath, 'avatar_thumb')
|
|
: null,
|
|
blueAvatar: $battle->blueAvatarPath
|
|
? $this->cacheManager->generateUrl($battle->blueAvatarPath, 'avatar_thumb')
|
|
: null,
|
|
redPoints: $battle->redPoints,
|
|
bluePoints: $battle->bluePoints,
|
|
redExplodedBomb: $battle->redExplodedBomb,
|
|
blueExplodedBomb: $battle->blueExplodedBomb,
|
|
resign: $battle->resign,
|
|
created: $battle->created?->format('Y-m-d H:i'),
|
|
date: $battle->updated?->format('Y-m-d H:i'),
|
|
isRed: $battle->isRed,
|
|
result: $battle->result,
|
|
myPoints: $myPts,
|
|
oppPoints: $oppPts,
|
|
redBonusPoints: $battle->redBonusPoints,
|
|
blueBonusPoints: $battle->blueBonusPoints,
|
|
redBonusStats: $battle->redBonusStats,
|
|
blueBonusStats: $battle->blueBonusStats,
|
|
bothRegistered: !$battle->oppIsGuest,
|
|
);
|
|
}
|
|
|
|
}
|