gamesshop/src/php/Importer/GameImporter.php

165 lines
5 KiB
PHP
Raw Normal View History

2024-07-05 20:29:35 +00:00
<?php
declare(strict_types=1);
namespace GamesShop\Importer;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use GamesShop\Entities\Account\User;
use GamesShop\Entities\Games\Game;
use GamesShop\Entities\Games\Key;
use GamesShop\Entities\Games\KeyAttribute;
use GamesShop\Entities\Games\Store;
use PhpOffice\PhpSpreadsheet\IOFactory;
final class GameImporter
{
private const HEADER_ROW_INDEX = 1;
private const STORE_ADDITIONAL_CASES = [
'epic' => Store::EPICGAMES,
'ea' => Store::ORIGIN,
'eaplay' => Store::ORIGIN,
'ubisoft' => Store::UPLAY,
'activision' => Store::BATTLENET
];
public function __construct(
private readonly EntityManagerInterface $entityManager,
) { }
/**
* @param string $path
* @return ImportColumnInterpretation[]
*/
public function interpret(string $path): array {
$spreadsheet = IOFactory::load($path);
$worksheet = $spreadsheet->getSheet(0);
$result = [];
foreach ($worksheet->getColumnIterator() as $column) {
$columnIndex = $column->getColumnIndex();
$value = $worksheet->getCell(sprintf('%s%d', $columnIndex, self::HEADER_ROW_INDEX))->getValueString();
if (empty(trim($value))) {
continue;
}
$guessedAttribute = $this->guessAttribute($value);
$result[] = new ImportColumnInterpretation(
$columnIndex,
$value,
$guessedAttribute
);
}
return $result;
}
private function guessAttribute(string $value): KeyAttribute|null {
$value = trim($value);
$value = strtolower($value);
$value = str_replace(' ', '_', $value);
$attribute = match($value) {
'key' => KeyAttribute::KEY,
'name', 'game_name', 'game' => KeyAttribute::GAME_NAME,
'from' => KeyAttribute::FROM,
'store', 'for' => KeyAttribute::STORE,
default => null
};
return $attribute;
}
/**
* @param string[] $columnDefinitions
*/
public function import(string $path, array $columnDefinitions, User $contributedUser): array {
$spreadsheet = IOFactory::load($path);
$worksheet = $spreadsheet->getSheet(0);
$totalRows = 0;
$addedAmount = 0;
foreach ($worksheet->getRowIterator(self::HEADER_ROW_INDEX + 1) as $row) {
$totalRows++;
$values = [
'name' => null,
'key' => null,
'from' => null,
'store' => null,
'store_link' => null
];
foreach ($columnDefinitions as $columnIndex => $attribute) {
$value = $worksheet->getCell(sprintf('%s%d', $columnIndex, $row->getRowIndex()))->getValueString();
switch(KeyAttribute::from($attribute)) {
case KeyAttribute::NONE:
break;
case KeyAttribute::GAME_NAME:
$values['name'] = $value;
break;
case KeyAttribute::KEY:
$values['key'] = $value;
break;
case KeyAttribute::FROM:
$values['from'] = $value;
break;
case KeyAttribute::STORE:
$store = $this->interpretStore($value);
$values['store'] = $store;
if ($store === Store::EXTERNAL) {
$values['store_link'] = $value;
}
break;
}
}
if ($values['key'] === null || $values['name'] === null || $values['store'] === null) {
continue;
}
$game = $this->entityManager->getRepository(Game::class)->findOneBy([ 'name' => $values['name'] ]);
if ($game === null) {
$game = new Game($values['name']);
}
$key = new Key(
$game,
$contributedUser,
$values['key'],
$values['store'],
$values['store_link'],
$values['from'],
);
$this->entityManager->persist($game);
$this->entityManager->persist($key);
$addedAmount++;
}
$this->entityManager->flush();
return [$totalRows, $addedAmount];
}
private function interpretStore(string $storeString): Store {
$storeString = trim($storeString);
$storeString = strtolower($storeString);
$storeString = str_replace(' ', '', $storeString);
$triedConversion = Store::tryFrom($storeString);
if ($triedConversion !== null) {
return $triedConversion;
}
if (array_key_exists($storeString, self::STORE_ADDITIONAL_CASES)) {
return self::STORE_ADDITIONAL_CASES[$storeString];
}
return Store::EXTERNAL;
}
}