Work, work, work~~~
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"php": ">=8.3",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"doctrine/dbal": "^3",
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20241210083555 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('DROP SEQUENCE tpait_id_seq CASCADE');
|
||||
$this->addSql('ALTER TABLE item ADD aonprd_id VARCHAR(255) NOT NULL');
|
||||
$this->addSql('ALTER TABLE item_localization ADD locale VARCHAR(10) NOT NULL');
|
||||
$this->addSql('ALTER TABLE tpait ALTER id TYPE VARCHAR(255)');
|
||||
$this->addSql('ALTER TABLE tpait ALTER id DROP DEFAULT');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('CREATE SEQUENCE tpait_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('ALTER TABLE item_localization DROP locale');
|
||||
$this->addSql('ALTER TABLE item DROP aonprd_id');
|
||||
$this->addSql('ALTER TABLE tpait ALTER id TYPE INT');
|
||||
$this->addSql('CREATE SEQUENCE tpait_id_seq');
|
||||
$this->addSql('SELECT setval(\'tpait_id_seq\', (SELECT MAX(id) FROM tpait))');
|
||||
$this->addSql('ALTER TABLE tpait ALTER id SET DEFAULT nextval(\'tpait_id_seq\')');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20241210084313 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('DROP INDEX uniq_1f1b251ed17f50a6');
|
||||
$this->addSql('ALTER TABLE item DROP uuid');
|
||||
$this->addSql('CREATE SEQUENCE item_id_seq');
|
||||
$this->addSql('SELECT setval(\'item_id_seq\', (SELECT MAX(id) FROM item))');
|
||||
$this->addSql('ALTER TABLE item ALTER id SET DEFAULT nextval(\'item_id_seq\')');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_1F1B251EDA27C6FE ON item (aonprd_id)');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('DROP INDEX UNIQ_1F1B251EDA27C6FE');
|
||||
$this->addSql('ALTER TABLE item ADD uuid UUID NOT NULL');
|
||||
$this->addSql('ALTER TABLE item ALTER id DROP DEFAULT');
|
||||
$this->addSql('COMMENT ON COLUMN item.uuid IS \'(DC2Type:uuid)\'');
|
||||
$this->addSql('CREATE UNIQUE INDEX uniq_1f1b251ed17f50a6 ON item (uuid)');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20241210085754 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE item_localization ADD type VARCHAR(255) NOT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE item_localization DROP type');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20241210102535 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE TABLE source (id SERIAL NOT NULL, item_id INT NOT NULL, rarity INT NOT NULL, primary_source_category VARCHAR(255) NOT NULL, primary_source_group VARCHAR(255) NOT NULL, source_category JSON NOT NULL, source_group JSON NOT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE UNIQUE INDEX UNIQ_5F8A7F73126F525E ON source (item_id)');
|
||||
$this->addSql('ALTER TABLE source ADD CONSTRAINT FK_5F8A7F73126F525E FOREIGN KEY (item_id) REFERENCES item (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE source DROP CONSTRAINT FK_5F8A7F73126F525E');
|
||||
$this->addSql('DROP TABLE source');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20241210103436 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('DROP SEQUENCE source_id_seq CASCADE');
|
||||
$this->addSql('ALTER TABLE source ALTER id TYPE VARCHAR(255)');
|
||||
$this->addSql('ALTER TABLE source ALTER id DROP DEFAULT');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('CREATE SEQUENCE source_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('ALTER TABLE source ALTER id TYPE INT');
|
||||
$this->addSql('CREATE SEQUENCE source_id_seq');
|
||||
$this->addSql('SELECT setval(\'source_id_seq\', (SELECT MAX(id) FROM source))');
|
||||
$this->addSql('ALTER TABLE source ALTER id SET DEFAULT nextval(\'source_id_seq\')');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20241210103547 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE source ALTER primary_source_category DROP NOT NULL');
|
||||
$this->addSql('ALTER TABLE source ALTER primary_source_group DROP NOT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE source ALTER primary_source_category SET NOT NULL');
|
||||
$this->addSql('ALTER TABLE source ALTER primary_source_group SET NOT NULL');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20241210103818 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('ALTER TABLE source DROP primary_source_category');
|
||||
$this->addSql('ALTER TABLE source DROP primary_source_group');
|
||||
$this->addSql('ALTER TABLE source ALTER source_category TYPE VARCHAR(255)');
|
||||
$this->addSql('ALTER TABLE source ALTER source_category DROP NOT NULL');
|
||||
$this->addSql('ALTER TABLE source ALTER source_group TYPE VARCHAR(255)');
|
||||
$this->addSql('ALTER TABLE source ALTER source_group DROP NOT NULL');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SCHEMA public');
|
||||
$this->addSql('ALTER TABLE source ADD primary_source_category VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE source ADD primary_source_group VARCHAR(255) DEFAULT NULL');
|
||||
$this->addSql('ALTER TABLE source ALTER source_category TYPE JSON');
|
||||
$this->addSql('ALTER TABLE source ALTER source_category SET NOT NULL');
|
||||
$this->addSql('ALTER TABLE source ALTER source_group TYPE JSON');
|
||||
$this->addSql('ALTER TABLE source ALTER source_group SET NOT NULL');
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use App\Command\Pf2eSchemaGenerator\Schema;
|
||||
use App\Command\Pf2eSchemaGenerator\SchemaItem;
|
||||
use App\Command\Pf2eSchemaGenerator\SchemaType\AbstractSchemaType;
|
||||
use App\Command\Pf2eSchemaGenerator\SchemaType\ObjectSchemaType;
|
||||
use App\Service\AonprdConnectionService;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
@@ -14,7 +15,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
#[AsCommand(
|
||||
name: 'pf2e:generate',
|
||||
description: 'Add a short description for your command',
|
||||
description: 'Get schemas of data',
|
||||
)]
|
||||
class Pf2eGenerateCommand extends Command
|
||||
{
|
||||
@@ -29,57 +30,48 @@ class Pf2eGenerateCommand extends Command
|
||||
->addOption("revision", null, InputOption::VALUE_REQUIRED, "Load index of specific revision. Default value - latest revision.")
|
||||
->addOption('type', null, InputOption::VALUE_REQUIRED, 'Specify types to import schema')
|
||||
->addOption('all', null, InputOption::VALUE_NONE, 'Generate schema for all types')
|
||||
->addOption('limit', null, InputOption::VALUE_REQUIRED, 'Specify number of elements can be listed as possible values')
|
||||
;
|
||||
}
|
||||
|
||||
private int $revision;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private array $types;
|
||||
|
||||
private array $typePages;
|
||||
|
||||
/**
|
||||
* @var array<string, Schema>
|
||||
* @var array<string, ObjectSchemaType>
|
||||
*/
|
||||
private array $schemas = [];
|
||||
|
||||
|
||||
private OutputInterface $output;
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$this->output = $output;
|
||||
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
|
||||
$this->revision = $input->getOption('revision') ?? $this->connectionService->getRevision();
|
||||
if (!is_null($input->getOption('revision'))) {
|
||||
$this->connectionService->setRevision($input->getOption('revision'));
|
||||
}
|
||||
|
||||
if (!is_null($input->getOption('limit'))) {
|
||||
AbstractSchemaType::$elementLimit = $input->getOption('limit');
|
||||
}
|
||||
|
||||
$this->types = $this->processTypes($input);
|
||||
$this->typePages = $this->connectionService->getIndexPageListByType($this->types);
|
||||
|
||||
if ($input->getOption('all')) {
|
||||
$this->types = [];
|
||||
}
|
||||
else if (is_null($input->getOption('type'))) {
|
||||
// $io->error("You must specify --type=[TYPE] or --all");
|
||||
// return Command::INVALID;
|
||||
$this->types = ["class"];
|
||||
}
|
||||
else {
|
||||
$this->types = explode(",", $input->getOption('type'));
|
||||
$this->types = array_keys($this->typePages);
|
||||
}
|
||||
|
||||
$typePages = $this->loadTypePages();
|
||||
|
||||
if ($input->getOption('all')) {
|
||||
$this->types = array_keys($typePages);
|
||||
}
|
||||
|
||||
$pages = [];
|
||||
|
||||
foreach ($this->types as $type) {
|
||||
$pages = [...$pages, ...$typePages[$type]];
|
||||
$this->schemas[$type] = new Schema();
|
||||
}
|
||||
|
||||
$pages = array_unique($pages);
|
||||
|
||||
foreach ($pages as $page) {
|
||||
$this->loadPage($page);
|
||||
}
|
||||
$this->progressBar = new ProgressBar($output);
|
||||
$this->processPages();
|
||||
|
||||
foreach ($this->schemas as $type => $schema) {
|
||||
$io->write("<options=bold,underscore>{$type}</>");
|
||||
@@ -90,45 +82,60 @@ class Pf2eGenerateCommand extends Command
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
protected function loadTypePages(): array
|
||||
public function processTypes(InputInterface $input): array
|
||||
{
|
||||
$typePages = [];
|
||||
if ($input->getOption('all')) {
|
||||
return [];
|
||||
}
|
||||
else if (is_null($input->getOption('type'))) {
|
||||
// throw new \Error("You must specify --type=[TYPE] or --all");
|
||||
|
||||
$index = $this->connectionService->loadCurrentIndex($this->revision);
|
||||
return ["class"];
|
||||
}
|
||||
else {
|
||||
return explode(",", $input->getOption('type'));
|
||||
}
|
||||
}
|
||||
|
||||
public function processPages(): void
|
||||
{
|
||||
$pages = [];
|
||||
|
||||
foreach ($this->types as $type) {
|
||||
$pages = [...$pages, ...$this->typePages[$type]];
|
||||
$this->schemas[$type] = new ObjectSchemaType();
|
||||
}
|
||||
|
||||
$pages = array_unique($pages);
|
||||
|
||||
$countPages = count($pages);
|
||||
$i = 0;
|
||||
|
||||
foreach ($pages as $page) {
|
||||
$i++;
|
||||
|
||||
$elements = $this->connectionService->loadIndexPage($page, $this->types);
|
||||
|
||||
$progressBar = new ProgressBar($this->output, count($elements));
|
||||
$progressBar->setFormat("debug");
|
||||
$progressBar->setMessage("Page {$i}/{$countPages}");
|
||||
$progressBar->start();
|
||||
|
||||
foreach ($index as $page => $elements) {
|
||||
foreach ($elements as $element) {
|
||||
preg_match("#^([a-z\\-]+?)-(\\d.*)$#", $element, $matches);
|
||||
$type = $matches[1];
|
||||
|
||||
if (!empty($targetType) && !in_array($type, $this->types)) {
|
||||
if (array_key_exists("remaster_id", $element)) {
|
||||
$progressBar->advance();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($typePages[$type])) {
|
||||
$typePages[$type] = [];
|
||||
$type = AonprdConnectionService::splitItemFullId($element["id"])["type"];
|
||||
$this->schemas[$type] = $this->schemas[$type]->adapt($element);
|
||||
$this->schemas[$type]->addValue($element);
|
||||
|
||||
$progressBar->advance();
|
||||
}
|
||||
|
||||
if (!in_array($page, $typePages[$type])) {
|
||||
$typePages[$type][] = $page;
|
||||
}
|
||||
}
|
||||
$progressBar->finish();
|
||||
}
|
||||
|
||||
return $typePages;
|
||||
}
|
||||
|
||||
protected function loadPage(string $page): void {
|
||||
$data = $this->connectionService->load("/json-data/{$page}.json");
|
||||
|
||||
foreach ($data as $element) {
|
||||
$type = $element["category"];
|
||||
|
||||
if (!in_array($type, $this->types)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->schemas[$type]->process($element);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
namespace App\Command;
|
||||
|
||||
use App\Entity\Item;
|
||||
use App\Entity\ItemLocalization;
|
||||
use App\Entity\ItemTypeEnum;
|
||||
use App\Service\AonprdConnectionService;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use ReflectionClass;
|
||||
use ReflectionEnum;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
@@ -9,14 +16,18 @@ use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symfony\Component\PropertyAccess\PropertyAccess;
|
||||
|
||||
#[AsCommand(
|
||||
name: 'pf2e:import',
|
||||
description: 'Add a short description for your command',
|
||||
description: 'Import data',
|
||||
)]
|
||||
class Pf2eImportCommand extends Command
|
||||
{
|
||||
public function __construct()
|
||||
public function __construct(
|
||||
private AonprdConnectionService $connectionService,
|
||||
private EntityManagerInterface $em
|
||||
)
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
@@ -30,28 +41,199 @@ class Pf2eImportCommand extends Command
|
||||
;
|
||||
}
|
||||
|
||||
private int $revision;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private array $types;
|
||||
|
||||
private array $typePages;
|
||||
|
||||
private array $convertSchemas;
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$arg1 = $input->getArgument('arg1');
|
||||
|
||||
if ($arg1) {
|
||||
$io->note(sprintf('You passed an argument: %s', $arg1));
|
||||
if (!is_null($input->getOption('revision'))) {
|
||||
$this->connectionService->setRevision($input->getOption('revision'));
|
||||
}
|
||||
|
||||
if ($input->getOption('option1')) {
|
||||
// ...
|
||||
$this->convertSchemas = include(__DIR__ . "/Pf2eSchemaGenerator/EntitySchemas.php");
|
||||
|
||||
$this->types = $this->processTypes($input);
|
||||
$this->typePages = $this->connectionService->getIndexPageListByType($this->types);
|
||||
|
||||
$this->em->beginTransaction();
|
||||
|
||||
try {
|
||||
$this->cleanUp();
|
||||
$this->processPages();
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$io->error($e->getMessage());
|
||||
$io->writeln($e->getTraceAsString());
|
||||
// dump($e->getTrace());
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$io->success('You have a new command! Now make it your own! Pass --help to see your options.');
|
||||
$this->em->commit();
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
public function processTypes(InputInterface $input): array
|
||||
{
|
||||
if ($input->getOption('all')) {
|
||||
return [];
|
||||
}
|
||||
else if (is_null($input->getOption('type'))) {
|
||||
// throw new \Error("You must specify --type=[TYPE] or --all");
|
||||
|
||||
return ["class"];
|
||||
}
|
||||
else {
|
||||
return explode(",", $input->getOption('type'));
|
||||
}
|
||||
}
|
||||
|
||||
public function cleanUp(): void
|
||||
{
|
||||
$connection = $this->em->getConnection();
|
||||
|
||||
// $connection->executeQuery('SET FOREIGN_KEY_CHECKS=0');
|
||||
|
||||
foreach ($this->types as $type) {
|
||||
$connection->executeQuery("DELETE FROM ".$this->getTableName($this->convertSchemas[$type]["class"]));
|
||||
|
||||
$qb = $this->em->createQueryBuilder();
|
||||
$qb->delete(ItemLocalization::class, 'e')
|
||||
->andWhere('e.type = :type')
|
||||
->setParameter('type', $type);
|
||||
$qb->getQuery()->execute();
|
||||
|
||||
$qb = $this->em->createQueryBuilder();
|
||||
$qb->delete(Item::class, 'e')
|
||||
->andWhere('e.type = :type')
|
||||
->setParameter('type', $type);
|
||||
$qb->getQuery()->execute();
|
||||
}
|
||||
|
||||
// $connection->executeQuery('SET FOREIGN_KEY_CHECKS=1');
|
||||
}
|
||||
|
||||
private function getTableName(string $entityClass): string
|
||||
{
|
||||
$cmd = $this->em->getClassMetadata($entityClass);
|
||||
return $cmd->getTableName();
|
||||
}
|
||||
|
||||
public function processPages(): void
|
||||
{
|
||||
$pages = [];
|
||||
|
||||
foreach ($this->types as $type) {
|
||||
$pages = [...$pages, ...$this->typePages[$type]];
|
||||
}
|
||||
|
||||
$pages = array_unique($pages);
|
||||
|
||||
foreach ($pages as $page) {
|
||||
$elements = $this->connectionService->loadIndexPage($page, $this->types);
|
||||
|
||||
foreach ($elements as $element) {
|
||||
$this->processElement($element);
|
||||
|
||||
// return;
|
||||
}
|
||||
// return;
|
||||
}
|
||||
}
|
||||
|
||||
public function processElement(array $element): void
|
||||
{
|
||||
if (array_key_exists("remaster_id", $element)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$type = AonprdConnectionService::splitItemFullId($element["id"])["type"];
|
||||
$schema = $this->convertSchemas[$type];
|
||||
|
||||
$propertyAccessor = PropertyAccess::createPropertyAccessor();
|
||||
$reflection = new ReflectionClass($schema["class"]);
|
||||
|
||||
// Item
|
||||
$item = new Item();
|
||||
$item->setName($element["name"])
|
||||
->setType(static::getEnum(ItemTypeEnum::class, $type))
|
||||
->setAonprdId($element["id"]);
|
||||
|
||||
// Entity
|
||||
$entity = $reflection->newInstance();
|
||||
$propertyAccessor->setValue($entity, "id", $element["id"]);
|
||||
$propertyAccessor->setValue($entity, "item", $item);
|
||||
|
||||
foreach ($schema["schema"] as $field => $elementSchema) {
|
||||
$value = $this->getValue($element, $field, $elementSchema);
|
||||
$propertyAccessor->setValue($entity, $field, $value);
|
||||
}
|
||||
|
||||
// Localization
|
||||
$localization = new ItemLocalization();
|
||||
$localization->setLocale("en")
|
||||
->setItem($item)
|
||||
->setType($item->getType());
|
||||
|
||||
foreach ($schema["localization"] as $field => $elementSchema) {
|
||||
$value = $this->getValue($element, $field, $elementSchema);
|
||||
$propertyAccessor->setValue($localization, $field, $value);
|
||||
}
|
||||
|
||||
// dump($item);
|
||||
// dump($entity);
|
||||
// dump($localization);
|
||||
|
||||
$this->em->persist($item);
|
||||
$this->em->persist($entity);
|
||||
$this->em->persist($localization);
|
||||
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
public function getValue(mixed $element, string $field, mixed $schema)
|
||||
{
|
||||
if ($schema === true) {
|
||||
$schema = $field;
|
||||
}
|
||||
|
||||
if (is_string($schema)) {
|
||||
$schema = [
|
||||
"method" => "value",
|
||||
"field" => $schema,
|
||||
];
|
||||
}
|
||||
|
||||
switch ($schema["method"]) {
|
||||
case "enum":
|
||||
return static::getEnum($schema["enum"], $element[$schema["field"]]);
|
||||
|
||||
default:
|
||||
return $element[$schema["field"]] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
private static function getEnum(string $enum, mixed $value): mixed
|
||||
{
|
||||
$reflection = new ReflectionEnum($enum);
|
||||
|
||||
$cases = $reflection->getCases();
|
||||
|
||||
foreach ($cases as $case) {
|
||||
if ($case->getBackingValue() === $value) {
|
||||
return $case->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
throw new \Error(sprintf('Class "%s" does not have value "%s"', $enum, $value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
// "entity_field" => "index_field",
|
||||
|
||||
return [
|
||||
"trait" => [
|
||||
"class" => \App\Entity\Pf2e\Tpait::class,
|
||||
"schema" => [
|
||||
"rarity" => [
|
||||
"method" => "enum",
|
||||
"field" => "rarity_id",
|
||||
"enum" => \App\Entity\Rarity::class,
|
||||
],
|
||||
],
|
||||
"localization" => [
|
||||
"title" => "name",
|
||||
"markdown" => "markdown",
|
||||
"url" => "url"
|
||||
]
|
||||
],
|
||||
"source" => [
|
||||
"class" => \App\Entity\Pf2e\Source::class,
|
||||
"schema" => [
|
||||
"rarity" => [
|
||||
"method" => "enum",
|
||||
"field" => "rarity_id",
|
||||
"enum" => \App\Entity\Rarity::class,
|
||||
],
|
||||
"source_category" => "primary_source_category",
|
||||
"source_group" => "primary_source_group",
|
||||
|
||||
],
|
||||
"localization" => [
|
||||
"title" => "name",
|
||||
"markdown" => "markdown",
|
||||
"url" => "url"
|
||||
]
|
||||
],
|
||||
"ancestry" => [
|
||||
// "class" => ,
|
||||
"schema" => [
|
||||
"rarity" => [
|
||||
"method" => "enum",
|
||||
"field" => "rarity_id",
|
||||
"enum" => \App\Entity\Rarity::class,
|
||||
],
|
||||
|
||||
],
|
||||
"localization" => [
|
||||
"title" => "name",
|
||||
"markdown" => "markdown",
|
||||
"url" => "url"
|
||||
]
|
||||
],
|
||||
];
|
||||
|
||||
/*
|
||||
"" => [
|
||||
"class" => ,
|
||||
"schema" => [
|
||||
"rarity" => [
|
||||
"method" => "enum",
|
||||
"field" => "rarity_id",
|
||||
"enum" => \App\Entity\Rarity::class,
|
||||
],
|
||||
|
||||
],
|
||||
"localization" => [
|
||||
"title" => "name",
|
||||
"markdown" => "markdown",
|
||||
"url" => "url"
|
||||
]
|
||||
],
|
||||
*/
|
||||
@@ -1,96 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Command\Pf2eSchemaGenerator;
|
||||
|
||||
class Schema
|
||||
{
|
||||
/**
|
||||
* @var SchemaItem[]
|
||||
*/
|
||||
private array $items = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function process(mixed $element): void
|
||||
{
|
||||
$keys = array_keys($element);
|
||||
|
||||
foreach ($this->items as $key => $item) {
|
||||
if (!in_array($key, $keys)) {
|
||||
$item->disableRequired();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if (!array_key_exists($key, $this->items)) {
|
||||
$this->items[$key] = new SchemaItem($key);
|
||||
}
|
||||
|
||||
$this->items[$key]->adapt($element[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
public static function resolveType(mixed $value): string
|
||||
{
|
||||
$type = gettype($value);
|
||||
|
||||
if ($type === "array") {
|
||||
if (empty($value)) {
|
||||
return "empty[]";
|
||||
}
|
||||
|
||||
if (array_is_list($value)) {
|
||||
$elementType = "";
|
||||
foreach ($value as $element) {
|
||||
$elementType = self::mergeTypes($elementType, self::resolveType($element));
|
||||
}
|
||||
|
||||
if (str_contains("|", $elementType)) {
|
||||
return "mixed[]";
|
||||
}
|
||||
|
||||
return $elementType . "[]";
|
||||
}
|
||||
|
||||
return "object";
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
public static function mergeTypes(string $typeList, string $newType): string {
|
||||
if (empty($typeList)) {
|
||||
return $newType;
|
||||
}
|
||||
|
||||
else if (str_contains("|", $typeList)) {
|
||||
$types = explode("|", $typeList);
|
||||
|
||||
if (!in_array($newType, $types, true)) {
|
||||
$types[] = $newType;
|
||||
}
|
||||
|
||||
return implode("|", $types);
|
||||
}
|
||||
else if ($newType !== $typeList) {
|
||||
return $typeList . "|" . $newType;
|
||||
}
|
||||
|
||||
return $typeList;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
$rows = [];
|
||||
|
||||
foreach ($this->items as $item) {
|
||||
$rows = [...$rows, ...$item->strings()];
|
||||
}
|
||||
|
||||
return implode(PHP_EOL, $rows);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Command\Pf2eSchemaGenerator;
|
||||
|
||||
class SchemaItem
|
||||
{
|
||||
public string $name;
|
||||
|
||||
public string $type = "";
|
||||
|
||||
public bool $required = true;
|
||||
|
||||
public ?array $elements = [];
|
||||
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function disableRequired(): void
|
||||
{
|
||||
$this->required = false;
|
||||
}
|
||||
|
||||
public function adapt(mixed $value): void
|
||||
{
|
||||
$type = Schema::resolveType($value);
|
||||
|
||||
$this->type = Schema::mergeTypes($this->type, $type);
|
||||
|
||||
if (!!is_null($this->elements)) {
|
||||
if (str_contains($this->type, "[]")) {
|
||||
foreach ($value as $element) {
|
||||
if (!in_array($element, $this->elements)) {
|
||||
$this->elements[] = $element;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!in_array($value, $this->elements)) {
|
||||
$this->elements[] = $value;
|
||||
}
|
||||
|
||||
if (count($this->elements) > 20) {
|
||||
$this->elements = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function strings(): array {
|
||||
$name = $this->name;
|
||||
|
||||
if (!$this->required) {
|
||||
$name = "[{$name}]";
|
||||
}
|
||||
|
||||
$rows = [
|
||||
sprintf("%s: %s", $name, $this->type),
|
||||
];
|
||||
|
||||
if (!empty($this->elements)) {
|
||||
sort($this->elements);
|
||||
$elements = [];
|
||||
foreach ($this->elements as $element) {
|
||||
$elements[] = is_string($element) ? "\"{$element}\"" : strval($element);
|
||||
}
|
||||
$rows[] = " Elements: [ " . implode(", ", $elements) . " ]";
|
||||
}
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace App\Command\Pf2eSchemaGenerator\SchemaType;
|
||||
|
||||
use SebastianBergmann\CodeCoverage\Report\PHP;
|
||||
|
||||
abstract class AbstractSchemaType
|
||||
{
|
||||
public bool $is_nullable = false;
|
||||
|
||||
public function markNullable(): static
|
||||
{
|
||||
$this->is_nullable = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if type is compatible with current type.
|
||||
*
|
||||
* @param mixed $value Value to be checked
|
||||
* @return bool True if value is compatible with current type
|
||||
*/
|
||||
abstract public function compatibleValue(mixed $value): bool;
|
||||
|
||||
/**
|
||||
* Adapt to new value.
|
||||
* If value is compatible with current type, `$this` will be returned.
|
||||
* If value is not compatible, new type will be created.
|
||||
*
|
||||
* @param mixed $value Value to be checked
|
||||
* @return AbstractSchemaType Compatible type
|
||||
*/
|
||||
public function adapt(mixed $value): static|AbstractSchemaType
|
||||
{
|
||||
if ($this->compatibleValue($value)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new MixedSchemaType($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new possible value.
|
||||
*
|
||||
* @param mixed $value New value
|
||||
*/
|
||||
abstract public function addValue(mixed $value): void;
|
||||
|
||||
/**
|
||||
* String representation of type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract public function __toString(): string;
|
||||
|
||||
/**
|
||||
* Get short name of type
|
||||
* @return string
|
||||
*/
|
||||
abstract public function getTypeName(): string;
|
||||
|
||||
|
||||
public const string TAB = " ";
|
||||
|
||||
public static int $elementLimit = 20;
|
||||
|
||||
public static function createFromValue(mixed $value): AbstractSchemaType
|
||||
{
|
||||
$valueType = static::resolveType($value);
|
||||
|
||||
return match ($valueType) {
|
||||
"null" => new EmptySchemaType(),
|
||||
"array" => new ArraySchemaType(),
|
||||
"object" => new ObjectSchemaType(),
|
||||
default => new StaticSchemaType($valueType),
|
||||
};
|
||||
}
|
||||
|
||||
public static function resolveType(mixed $value): string
|
||||
{
|
||||
$type = gettype($value);
|
||||
|
||||
if ($type === "array") {
|
||||
if (empty($value)) {
|
||||
return "null";
|
||||
}
|
||||
|
||||
if (array_is_list($value)) {
|
||||
return "array";
|
||||
}
|
||||
|
||||
return "object";
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
protected static function indent(string $string): string {
|
||||
return str_replace(PHP_EOL, PHP_EOL . static::TAB, $string);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
namespace App\Command\Pf2eSchemaGenerator\SchemaType;
|
||||
|
||||
class ArraySchemaType extends AbstractSchemaType
|
||||
{
|
||||
/**
|
||||
* Minimal array length
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public int $min_count = PHP_INT_MAX;
|
||||
|
||||
/**
|
||||
* Maximum array length
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public int $max_count = PHP_INT_MIN;
|
||||
|
||||
/**
|
||||
* Type of value
|
||||
*
|
||||
* @var AbstractSchemaType
|
||||
*/
|
||||
private AbstractSchemaType $type;
|
||||
|
||||
/**
|
||||
* Calculation of values
|
||||
*
|
||||
* @var array<mixed, int>
|
||||
*/
|
||||
private array $values = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->type = new EmptySchemaType();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function compatibleValue(mixed $value): bool
|
||||
{
|
||||
if ("none" === static::resolveType($value)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ("array" !== static::resolveType($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($value as $v) {
|
||||
if (!$this->type->compatibleValue($v)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function adapt(mixed $value): static|AbstractSchemaType
|
||||
{
|
||||
if (("null" !== static::resolveType($value)) && ($this->type instanceof EmptySchemaType)) {
|
||||
$this->type = static::createFromValue($value[0]);
|
||||
}
|
||||
|
||||
if ($this->compatibleValue($value)) {
|
||||
foreach ($value as $v) {
|
||||
$this->type = $this->type->adapt($v);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
return new MixedSchemaType($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function addValue(mixed $value): void
|
||||
{
|
||||
$this->min_count = min($this->min_count, count($value));
|
||||
$this->max_count = max($this->max_count, count($value));
|
||||
|
||||
foreach ($value as $element) {
|
||||
$this->type->addValue($element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
$rows = [$this->getTypeName()];
|
||||
|
||||
$rows[] = "Length: min={$this->min_count}, max={$this->max_count}";
|
||||
|
||||
$rows[] = "Value type: " . self::indent($this->type->__toString());
|
||||
|
||||
return implode(PHP_EOL.self::TAB, $rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getTypeName(): string
|
||||
{
|
||||
if ($this->type instanceof StaticSchemaType) {
|
||||
return $this->type->getTypeName() . "[]";
|
||||
}
|
||||
else {
|
||||
return "array of " . $this->type->getTypeName();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Command\Pf2eSchemaGenerator\SchemaType;
|
||||
|
||||
class EmptySchemaType extends AbstractSchemaType
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function compatibleValue(mixed $value): bool
|
||||
{
|
||||
return static::resolveType($value) === "null";
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function adapt(mixed $value): self|AbstractSchemaType
|
||||
{
|
||||
if ($this->compatibleValue($value)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
return AbstractSchemaType::createFromValue($value)->markNullable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function addValue(mixed $value): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return "empty[] -> null";
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getTypeName(): string
|
||||
{
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Command\Pf2eSchemaGenerator\SchemaType;
|
||||
|
||||
class MixedSchemaType extends AbstractSchemaType
|
||||
{
|
||||
/**
|
||||
* List of encountered values
|
||||
*
|
||||
* @var AbstractSchemaType[]
|
||||
*/
|
||||
public array $types;
|
||||
|
||||
public function __construct(AbstractSchemaType $baseType)
|
||||
{
|
||||
$this->types = [$baseType];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new type
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return \App\Command\Pf2eSchemaGenerator\SchemaType\AbstractSchemaType
|
||||
*/
|
||||
public function addType(mixed $value): AbstractSchemaType
|
||||
{
|
||||
$newType = AbstractSchemaType::createFromValue($value);
|
||||
$this->types[] = $newType;
|
||||
return $newType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get compatible type
|
||||
* @param mixed $value
|
||||
* @return null|AbstractSchemaType
|
||||
*/
|
||||
public function getCompatibleType(mixed $value): ?AbstractSchemaType
|
||||
{
|
||||
dd($this->types, $value);
|
||||
|
||||
foreach ($this->types as $type) {
|
||||
if ($type->compatibleValue($value)) {
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function compatibleValue(mixed $value): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function adapt(mixed $value): self|AbstractSchemaType
|
||||
{
|
||||
$type = $this->getCompatibleType($value);
|
||||
|
||||
if ($type === null) {
|
||||
$this->addType($value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function addValue(mixed $value): void
|
||||
{
|
||||
$this->getCompatibleType($value)?->addValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
$result = ["mixed"];
|
||||
|
||||
foreach ($this->types as $type) {
|
||||
$result[] = static::indent($type->__toString());
|
||||
}
|
||||
|
||||
return implode(PHP_EOL.static::TAB, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getTypeName(): string
|
||||
{
|
||||
$parts = [];
|
||||
foreach ($this->types as $type) {
|
||||
$parts[] = $type->getTypeName();
|
||||
}
|
||||
return implode("|", $parts);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace App\Command\Pf2eSchemaGenerator\SchemaType;
|
||||
|
||||
class ObjectSchemaType extends AbstractSchemaType
|
||||
{
|
||||
private bool $fresh = true;
|
||||
|
||||
/**
|
||||
* @var array<string, AbstractSchemaType>
|
||||
*/
|
||||
public array $fields = [];
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function compatibleValue(mixed $value): bool
|
||||
{
|
||||
return (static::resolveType($value) === "object") || (static::resolveType($value) === "null");
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function adapt(mixed $value): static|AbstractSchemaType
|
||||
{
|
||||
if (!$this->compatibleValue($value)) {
|
||||
return new MixedSchemaType($this);
|
||||
}
|
||||
|
||||
foreach ($this->fields as $key => $field) {
|
||||
if (!array_key_exists($key, $value)) {
|
||||
$field->markNullable();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($value as $key => $v) {
|
||||
if (!array_key_exists($key, $this->fields)) {
|
||||
$this->fields[$key] = AbstractSchemaType::createFromValue($v);
|
||||
|
||||
if (!$this->fresh) {
|
||||
$this->fields[$key]->markNullable();
|
||||
}
|
||||
}
|
||||
|
||||
$this->fields[$key] = $this->fields[$key]->adapt($v);
|
||||
}
|
||||
|
||||
$this->fresh = false;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function addValue(mixed $value): void
|
||||
{
|
||||
if (empty($value)) {
|
||||
$this->markNullable();
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->fields as $key => $field) {
|
||||
if (!array_key_exists($key, $value)) {
|
||||
$field->markNullable();
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($value as $key => $v) {
|
||||
$this->fields[$key]->addValue($v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
$rows = [ "object" ];
|
||||
|
||||
foreach ($this->fields as $key => $field) {
|
||||
$rows[] = sprintf("%s<options=bold>%s</>%s: %s",
|
||||
$field->is_nullable ? "[" : "",
|
||||
$key,
|
||||
$field->is_nullable ? "]" : "",
|
||||
static::indent($field->__toString()),
|
||||
);
|
||||
}
|
||||
|
||||
return implode(PHP_EOL.static::TAB, $rows);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getTypeName(): string
|
||||
{
|
||||
return "object";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace App\Command\Pf2eSchemaGenerator\SchemaType;
|
||||
|
||||
class StaticSchemaType extends AbstractSchemaType
|
||||
{
|
||||
/**
|
||||
* Type of value
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $type;
|
||||
|
||||
/**
|
||||
* Calculation of values
|
||||
*
|
||||
* @var array<mixed, int>
|
||||
*/
|
||||
private array $values = [];
|
||||
|
||||
public function __construct(string $type)
|
||||
{
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if type is compatible with current type.
|
||||
*
|
||||
* @param mixed $value Value to be checked
|
||||
* @return bool True if value is compatible with current type
|
||||
*/
|
||||
public function compatibleValue(mixed $value): bool
|
||||
{
|
||||
$valueType = static::resolveType($value);
|
||||
|
||||
return $valueType === $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new possible value.
|
||||
*
|
||||
* @param mixed $value New value
|
||||
*/
|
||||
public function addValue(mixed $value): void
|
||||
{
|
||||
if (!array_key_exists($value, $this->values)) {
|
||||
$this->values[$value] = 0;
|
||||
}
|
||||
|
||||
$this->values[$value]++;
|
||||
}
|
||||
|
||||
/**
|
||||
* String representation of type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
$result = $this->type;
|
||||
|
||||
$countValues = count($this->values);
|
||||
|
||||
$result .= " (different values: {$countValues})";
|
||||
|
||||
if (($countValues > 0) && ($countValues < AbstractSchemaType::$elementLimit)) {
|
||||
$items = [];
|
||||
|
||||
foreach ($this->values as $value => $count) {
|
||||
$items[] = sprintf('%s (x%d)', is_string($value) ? "'{$value}'" : $value, $count);
|
||||
}
|
||||
|
||||
$result .= PHP_EOL . static::TAB . " Possible values: [" . implode(', ', $items) . "]";
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getTypeName(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,8 @@ class Pf2eTypesCommand extends Command
|
||||
}
|
||||
}
|
||||
|
||||
ksort($types);
|
||||
|
||||
if ($full) {
|
||||
$table = [];
|
||||
|
||||
|
||||
+11
-6
@@ -17,10 +17,8 @@ class Item
|
||||
#[ORM\Column]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\Column(type: UuidType::NAME, unique: true)]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
|
||||
private ?Uuid $uuid = null;
|
||||
#[ORM\Column(length: 255, unique: true)]
|
||||
private ?string $aonprdId = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $name = null;
|
||||
@@ -44,9 +42,16 @@ class Item
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getUuid(): ?Uuid
|
||||
public function getAonprdId(): ?string
|
||||
{
|
||||
return $this->uuid;
|
||||
return $this->aonprdId;
|
||||
}
|
||||
|
||||
public function setAonprdId(?string $aonprdId): static
|
||||
{
|
||||
$this->aonprdId = $aonprdId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName(): ?string
|
||||
|
||||
@@ -17,6 +17,12 @@ class ItemLocalization
|
||||
#[ORM\ManyToOne(inversedBy: 'itemLocalizations')]
|
||||
private ?Item $item = null;
|
||||
|
||||
#[ORM\Column(enumType: ItemTypeEnum::class)]
|
||||
private ?ItemTypeEnum $type = null;
|
||||
|
||||
#[ORM\Column(length: 10)]
|
||||
private ?string $locale = null;
|
||||
|
||||
#[ORM\Column(length: 255)]
|
||||
private ?string $title = null;
|
||||
|
||||
@@ -43,6 +49,30 @@ class ItemLocalization
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getType(): ?ItemTypeEnum
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setType(ItemTypeEnum $type): static
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLocale(): ?string
|
||||
{
|
||||
return $this->locale;
|
||||
}
|
||||
|
||||
public function setLocale(?string $locale): static
|
||||
{
|
||||
$this->locale = $locale;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTitle(): ?string
|
||||
{
|
||||
return $this->title;
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity\Pf2e;
|
||||
|
||||
use App\Entity\Item;
|
||||
use App\Entity\Rarity;
|
||||
use App\Repository\Pf2e\SourceRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity(repositoryClass: SourceRepository::class)]
|
||||
class Source
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column]
|
||||
private ?string $id = null;
|
||||
|
||||
#[ORM\OneToOne(cascade: ['persist', 'remove'])]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private ?Item $item = null;
|
||||
|
||||
#[ORM\Column(enumType: Rarity::class)]
|
||||
private ?Rarity $rarity = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $source_category = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: true)]
|
||||
private ?string $source_group = null;
|
||||
|
||||
public function getId(): ?string
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId(string $value): static
|
||||
{
|
||||
$this->id = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getItem(): ?Item
|
||||
{
|
||||
return $this->item;
|
||||
}
|
||||
|
||||
public function setItem(Item $item): static
|
||||
{
|
||||
$this->item = $item;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRarity(): ?Rarity
|
||||
{
|
||||
return $this->rarity;
|
||||
}
|
||||
|
||||
public function setRarity(Rarity $rarity): static
|
||||
{
|
||||
$this->rarity = $rarity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSourceCategory(): ?string
|
||||
{
|
||||
return $this->source_category;
|
||||
}
|
||||
|
||||
public function setSourceCategory(?string $source_category): static
|
||||
{
|
||||
$this->source_category = $source_category;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSourceGroup(): ?string
|
||||
{
|
||||
return $this->source_group;
|
||||
}
|
||||
|
||||
public function setSourceGroup(?string $source_group): static
|
||||
{
|
||||
$this->source_group = $source_group;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,9 +11,8 @@ use Doctrine\ORM\Mapping as ORM;
|
||||
class Tpait
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
private ?int $id = null;
|
||||
private ?string $id = null;
|
||||
|
||||
#[ORM\Column(enumType: Rarity::class)]
|
||||
private ?Rarity $rarity = null;
|
||||
@@ -27,6 +26,13 @@ class Tpait
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function setId(string $value): static
|
||||
{
|
||||
$this->id = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRarity(): ?Rarity
|
||||
{
|
||||
return $this->rarity;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository\Pf2e;
|
||||
|
||||
use App\Entity\Pf2e\Source;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Source>
|
||||
*/
|
||||
class SourceRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Source::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return Source[] Returns an array of Source objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('s')
|
||||
// ->andWhere('s.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('s.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?Source
|
||||
// {
|
||||
// return $this->createQueryBuilder('s')
|
||||
// ->andWhere('s.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
@@ -7,7 +7,20 @@ use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
|
||||
class AonprdConnectionService
|
||||
{
|
||||
public const DATA_LINK = "https://elasticsearch.aonprd.com";
|
||||
public const string DATA_LINK = "https://elasticsearch.aonprd.com";
|
||||
|
||||
public static function testItemTypeFilter(string $type, array $types): bool {
|
||||
return empty($types) || in_array($type, $types);
|
||||
}
|
||||
|
||||
public static function splitItemFullId(string $fullId): array {
|
||||
preg_match("#^([a-z\\-]+?)-(\\d.*)$#", $fullId, $matches);
|
||||
|
||||
return [
|
||||
"type" => $matches[1],
|
||||
"id"=> $matches[2],
|
||||
];
|
||||
}
|
||||
|
||||
private ?int $revision = null;
|
||||
|
||||
@@ -36,14 +49,64 @@ class AonprdConnectionService
|
||||
return $this->revision;
|
||||
}
|
||||
|
||||
public function setRevision(?int $revision): void
|
||||
{
|
||||
$this->revision = $revision;
|
||||
}
|
||||
|
||||
public function loadCurrentIndex(int $revision = null): array
|
||||
{
|
||||
if ($revision === null) {
|
||||
$revision = $this->getRevision();
|
||||
}
|
||||
|
||||
$data = $this->load("/json-data/aon{$revision}-index.json");
|
||||
return $this->load("/json-data/aon{$revision}-index.json");
|
||||
}
|
||||
|
||||
public function loadIndexPage(string $page, array $types = []): array
|
||||
{
|
||||
$data = $this->load("/json-data/{$page}.json");
|
||||
|
||||
if (empty($types)) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
|
||||
foreach ($data as $element) {
|
||||
if (AonprdConnectionService::testItemTypeFilter($element["category"], $types)) {
|
||||
$result[] = $element;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getIndexPageListByType(array $types = []): array
|
||||
{
|
||||
$typePages = [];
|
||||
|
||||
$index = $this->loadCurrentIndex($this->revision);
|
||||
|
||||
foreach ($index as $page => $elements) {
|
||||
foreach ($elements as $element) {
|
||||
$type = self::splitItemFullId($element)["type"];
|
||||
|
||||
if (!AonprdConnectionService::testItemTypeFilter($type, $types)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($typePages[$type])) {
|
||||
$typePages[$type] = [];
|
||||
}
|
||||
|
||||
if (!in_array($page, $typePages[$type])) {
|
||||
$typePages[$type][] = $page;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $typePages;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user