Allow moving gpus into a 'previously owned' category

This commit is contained in:
Timothy Warren 2024-03-20 14:21:40 -04:00
parent c6a9690942
commit 44579bb859
24 changed files with 2157 additions and 1370 deletions

2361
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -3,5 +3,5 @@
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
return static function (RoutingConfigurator $routingConfigurator): void {
$routingConfigurator->import('../../src/Controller/', 'annotation');
$routingConfigurator->import('../../src/Controller/', 'attribute');
};

View File

@ -7,7 +7,9 @@ use App\Enum\SlotKey;
use App\Form\GpuType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\{Request, Response};
use Symfony\Component\HttpFoundation\
{RedirectResponse, Request, Response};
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Routing\Annotation\Route;
#[Route('/gpu')]
@ -73,4 +75,26 @@ class GpuController extends AbstractController {
{
return $this->deleteCSRF($request, $gpu);
}
/**
* Moves a gpu to the previouslyOwned table
*
* @throws LogicException
* @throws ORMInvalidArgumentException
*/
#[Route(path: '/{id}/deacquire', name: 'gpu_deacquire', methods: ['POST'])]
public function reacquireAction(Request $request, Gpu $gpu): RedirectResponse
{
return $this->itemDeacquire($request, $gpu, 'previously-owned-gpu_index');
}
/**
* Creates a form to move
*
* @param gpu $gpu The gpu entity
*/
private function createDeacquireForm(gpu $gpu): FormInterface
{
return $this->buildForm($gpu, 'gpu_deacquire');
}
}

View File

@ -0,0 +1,88 @@
<?php declare(strict_types=1);
namespace App\Controller;
use App\Entity\PreviouslyOwnedGpu;
use App\Enum\SlotKey;
use App\Form\PreviouslyOwnedGpuType;
use Doctrine\ORM\{EntityManagerInterface, ORMInvalidArgumentException};
use LogicException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\{RedirectResponse, Request, Response};
use Symfony\Component\Routing\Annotation\Route;
use UnexpectedValueException;
/**
* PreviouslyownedGpu controller.
*/
#[Route(path: 'previously-owned-gpu')]
class PreviouslyOwnedGpuController extends AbstractController {
use FormControllerBase;
protected const ENTITY = PreviouslyOwnedGpu::class;
protected const TEMPLATE_PATH = 'previouslyownedgpu/';
protected const ROUTE_PREFIX = 'previously-owned-gpu_';
protected const FORM = PreviouslyOwnedGpuType::class;
public function __construct(private readonly EntityManagerInterface $entityManager)
{
}
/**
* Lists all previouslyOwnedGpu entities.
*
* @throws UnexpectedValueException
*/
#[Route(path: '/', name: 'previously-owned-gpu_index', methods: ['GET'])]
public function indexAction(): Response
{
$items = $this->entityManager->getRepository(self::ENTITY)->findAll();
return $this->render('previouslyownedgpu/index.html.twig', [
'gpus' => $items,
]);
}
/**
* Finds and displays a previouslyOwnedGpu entity.
*/
#[Route(path: '/{id}', name: 'previously-owned-gpu_show', methods: ['GET'])]
public function showAction(PreviouslyOwnedGpu $previouslyOwnedGpu): Response
{
return $this->itemView($previouslyOwnedGpu, 'previouslyOwnedGpu');
}
/**
* Displays a form to edit an existing previouslyOwnedGpu entity.
*
* @throws LogicException
*/
#[Route(path: '/{id}/edit', name: 'previously-owned-gpu_edit', methods: ['GET', 'POST'])]
public function editAction(Request $request, PreviouslyOwnedGpu $previouslyOwnedGpu): RedirectResponse|Response
{
return $this->itemUpdate($request, $previouslyOwnedGpu, 'previouslyOwnedGpu');
}
/**
* Moves a Gpu to the previouslyOwned table
*
* @throws LogicException
* @throws ORMInvalidArgumentException
*/
#[Route(path: '/{id}/reacquire', name: 'previously-owned-gpu_reacquire', methods: ['POST'])]
public function reacquireAction(Request $request, PreviouslyOwnedGpu $Gpu): RedirectResponse
{
return $this->itemReacquire($request, $Gpu, 'gpu_index');
}
/**
* Creates a form to move
*
* @param PreviouslyOwnedGpu $Gpu The Gpu entity
*/
private function createReacquireForm(PreviouslyOwnedGpu $Gpu): FormInterface
{
return $this->buildForm($Gpu, 'previously-owned-gpu_reacquire', 'POST');
}
}

View File

@ -2,165 +2,18 @@
namespace App\Entity;
use App\Enum\{CardBus, SlotKey};
use App\Repository\GpuRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Table(name: 'gpu', schema: 'collection')]
#[ORM\Entity]
#[ORM\Entity(repositoryClass: GpuRepository::class)]
class Gpu {
use GetSet;
use GpuBase;
#[ORM\Column(name: 'id', type: 'integer', nullable: FALSE)]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')]
private int $id;
#[ORM\ManyToOne(targetEntity: 'Brand', fetch: 'EAGER')]
#[ORM\OrderBy(['name' => 'asc'])]
#[ORM\JoinColumn(name: 'gpu_brand_id', referencedColumnName: 'id', nullable: FALSE)]
private Brand $gpuBrand;
#[ORM\ManyToOne(targetEntity: 'GpuCore', fetch: 'EAGER')]
#[ORM\OrderBy(['brand' => 'asc', 'name' => 'asc'])]
#[ORM\JoinColumn(name: 'gpu_core_id', referencedColumnName: 'id', nullable: TRUE)]
private ?GpuCore $gpuCore = NULL;
#[ORM\Column(name: 'reference_model_name', nullable: FALSE)]
private string $modelName;
#[ORM\ManyToOne(targetEntity: 'Brand', fetch: 'EAGER')]
#[ORM\OrderBy(['name' => 'asc'])]
#[ORM\JoinColumn(name: 'board_brand_id', referencedColumnName: 'id', nullable: TRUE)]
private ?Brand $boardBrand = NULL;
#[ORM\Column(name: 'alternate_model_name', nullable: TRUE)]
private ?string $alternateModelName = '';
#[ORM\Column(
name: 'card_key',
type: 'string',
enumType: SlotKey::class,
options: [
'comment' => 'The shape of the card connector',
'default' => 'PCIe x16',
]
)]
private SlotKey $cardKey = SlotKey::PCIE_X16;
#[ORM\Column(
name: 'bus_interface',
type: 'string',
nullable: TRUE,
enumType: CardBus::class,
options: ['comment' => 'The type of electrical bus this card uses']
)]
private ?CardBus $busInterface;
#[ORM\Column(
name: 'slot_span',
options: [
'comment' => 'How many expansion slots the card occupies',
'default' => 1,
],
)]
private int $slotSpan = 1;
#[ORM\Column(name: 'molex_power', options: ['default' => 0])]
private int $molexPower = 0;
#[ORM\Column(name: 'pcie_6_pin', options: ['default' => 0])]
private int $pcie6power = 0;
#[ORM\Column(name: 'pcie_8_pin', options: ['default' => 0])]
private int $pcie8power = 0;
#[ORM\Column(
name: 'tdp',
nullable: TRUE,
options: ['comment' => 'Thermal Design Power (in Watts)']
)]
private ?int $tdp = 0;
#[ORM\Column(
name: 'base_clock',
nullable: TRUE,
options: ['comment' => 'Base speed of the gpu core, in MHz']
)]
private ?int $baseClock;
#[ORM\Column(
name: 'boost_clock',
nullable: TRUE,
options: ['comment' => 'GPU core boost clock, in MHz']
)]
private ?int $boostClock;
#[ORM\Column(
name: 'memory_clock',
nullable: TRUE,
options: ['comment' => 'Clock speed of the VRAM, in MHz']
)]
private ?int $memoryClock;
#[ORM\Column(
name: 'memory_size',
nullable: TRUE,
options: ['comment' => 'VRAM size, in MiB']
)]
private ?int $memorySize;
#[ORM\Column(
name: 'memory_bus',
nullable: TRUE,
options: ['comment' => 'The width of the memory bus in bits']
)]
private ?int $memoryBus;
#[ORM\Column(name: 'memory_type', nullable: TRUE)]
private ?string $memoryType;
#[ORM\Column(name: 'shading_units', nullable: TRUE)]
private ?int $shadingUnits;
#[ORM\Column(name: 'tmus', nullable: TRUE)]
private ?int $tmus;
#[ORM\Column(name: 'rops', nullable: TRUE)]
private ?int $rops;
#[ORM\Column(name: 'compute_units', nullable: TRUE)]
private ?int $computeUnits;
#[ORM\Column(name: 'l1_cache', nullable: TRUE)]
private ?string $l1cache;
#[ORM\Column(name: 'l2_cache', nullable: TRUE)]
private ?string $l2cache;
#[ORM\Column(name: 'direct_x_support', nullable: TRUE)]
private ?string $directXSupport;
#[ORM\Column(name: 'opengl_support', nullable: TRUE)]
private ?string $openGLSupport;
#[ORM\Column(name: 'opencl_support', nullable: TRUE)]
private ?string $openCLSupport;
#[ORM\Column(name: 'vulkan_support', nullable: TRUE)]
private ?string $vulkanSupport;
#[ORM\Column(name: 'shader_model', nullable: TRUE)]
private ?string $shaderModel;
#[ORM\Column(name: 'link', nullable: TRUE)]
private ?string $link;
#[ORM\Column(name: 'count', nullable: FALSE, options: ['default' => 1])]
private int $count = 1;
#[ORM\Column(name: 'acquired', nullable: FALSE, options: ['default' => TRUE])]
private bool $acquired;
#[ORM\Column(name: 'notes', type: 'text', nullable: TRUE)]
private ?string $notes = '';
}

157
src/Entity/GpuBase.php Normal file
View File

@ -0,0 +1,157 @@
<?php declare(strict_types=1);
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use App\Enum\{CardBus, SlotKey};
trait GpuBase {
#[ORM\ManyToOne(targetEntity: 'Brand', fetch: 'EAGER')]
#[ORM\OrderBy(['name' => 'asc'])]
#[ORM\JoinColumn(name: 'gpu_brand_id', referencedColumnName: 'id', nullable: FALSE)]
private Brand $gpuBrand;
#[ORM\ManyToOne(targetEntity: 'GpuCore', fetch: 'EAGER')]
#[ORM\OrderBy(['brand' => 'asc', 'name' => 'asc'])]
#[ORM\JoinColumn(name: 'gpu_core_id', referencedColumnName: 'id', nullable: TRUE)]
private ?GpuCore $gpuCore = NULL;
#[ORM\Column(name: 'reference_model_name', nullable: FALSE)]
private string $modelName;
#[ORM\ManyToOne(targetEntity: 'Brand', fetch: 'EAGER')]
#[ORM\OrderBy(['name' => 'asc'])]
#[ORM\JoinColumn(name: 'board_brand_id', referencedColumnName: 'id', nullable: TRUE)]
private ?Brand $boardBrand = NULL;
#[ORM\Column(name: 'alternate_model_name', nullable: TRUE)]
private ?string $alternateModelName = '';
#[ORM\Column(
name: 'card_key',
type: 'string',
enumType: SlotKey::class,
options: [
'comment' => 'The shape of the card connector',
'default' => 'PCIe x16',
]
)]
private SlotKey $cardKey = SlotKey::PCIE_X16;
#[ORM\Column(
name: 'bus_interface',
type: 'string',
nullable: TRUE,
enumType: CardBus::class,
options: ['comment' => 'The type of electrical bus this card uses']
)]
private ?CardBus $busInterface;
#[ORM\Column(
name: 'slot_span',
options: [
'comment' => 'How many expansion slots the card occupies',
'default' => 1,
],
)]
private int $slotSpan = 1;
#[ORM\Column(name: 'molex_power', options: ['default' => 0])]
private int $molexPower = 0;
#[ORM\Column(name: 'pcie_6_pin', options: ['default' => 0])]
private int $pcie6power = 0;
#[ORM\Column(name: 'pcie_8_pin', options: ['default' => 0])]
private int $pcie8power = 0;
#[ORM\Column(
name: 'tdp',
nullable: TRUE,
options: ['comment' => 'Thermal Design Power (in Watts)']
)]
private ?int $tdp = 0;
#[ORM\Column(
name: 'base_clock',
nullable: TRUE,
options: ['comment' => 'Base speed of the gpu core, in MHz']
)]
private ?int $baseClock;
#[ORM\Column(
name: 'boost_clock',
nullable: TRUE,
options: ['comment' => 'GPU core boost clock, in MHz']
)]
private ?int $boostClock;
#[ORM\Column(
name: 'memory_clock',
nullable: TRUE,
options: ['comment' => 'Clock speed of the VRAM, in MHz']
)]
private ?int $memoryClock;
#[ORM\Column(
name: 'memory_size',
nullable: TRUE,
options: ['comment' => 'VRAM size, in MiB']
)]
private ?int $memorySize;
#[ORM\Column(
name: 'memory_bus',
nullable: TRUE,
options: ['comment' => 'The width of the memory bus in bits']
)]
private ?int $memoryBus;
#[ORM\Column(name: 'memory_type', nullable: TRUE)]
private ?string $memoryType;
#[ORM\Column(name: 'shading_units', nullable: TRUE)]
private ?int $shadingUnits;
#[ORM\Column(name: 'tmus', nullable: TRUE)]
private ?int $tmus;
#[ORM\Column(name: 'rops', nullable: TRUE)]
private ?int $rops;
#[ORM\Column(name: 'compute_units', nullable: TRUE)]
private ?int $computeUnits;
#[ORM\Column(name: 'l1_cache', nullable: TRUE)]
private ?string $l1cache;
#[ORM\Column(name: 'l2_cache', nullable: TRUE)]
private ?string $l2cache;
#[ORM\Column(name: 'direct_x_support', nullable: TRUE)]
private ?string $directXSupport;
#[ORM\Column(name: 'opengl_support', nullable: TRUE)]
private ?string $openGLSupport;
#[ORM\Column(name: 'opencl_support', nullable: TRUE)]
private ?string $openCLSupport;
#[ORM\Column(name: 'vulkan_support', nullable: TRUE)]
private ?string $vulkanSupport;
#[ORM\Column(name: 'shader_model', nullable: TRUE)]
private ?string $shaderModel;
#[ORM\Column(name: 'link', nullable: TRUE)]
private ?string $link;
#[ORM\Column(name: 'count', nullable: FALSE, options: ['default' => 1])]
private int $count = 1;
#[ORM\Column(name: 'acquired', nullable: FALSE, options: ['default' => TRUE])]
private bool $acquired;
#[ORM\Column(name: 'notes', type: 'text', nullable: TRUE)]
private ?string $notes = '';
}

View File

@ -27,16 +27,16 @@ class GpuCore implements Stringable {
private ?string $variant;
#[ORM\Column(name: 'generation_name', nullable: TRUE)]
private string $generationName;
private ?string $generationName = '';
#[ORM\Column(name: 'generation_link', nullable: TRUE)]
private ?string $generationLink = '';
#[ORM\Column(name: 'architecture', nullable: TRUE)]
private string $architecture;
private ?string $architecture = '';
#[ORM\Column(name: 'architecture_link', nullable: TRUE)]
private string $architectureLink;
private ?string $architectureLink = '';
#[ORM\Column(name: 'process_node', nullable: TRUE)]
private ?int $processNode;

View File

@ -26,7 +26,7 @@ class Motherboard {
/**
* @var Collection<int, Socket>
*/
#[ORM\ManyToMany(targetEntity: Socket::class, inversedBy: 'cpus', fetch: 'LAZY')]
#[ORM\ManyToMany(targetEntity: Socket::class, inversedBy: 'motherboards', fetch: 'LAZY')]
#[ORM\JoinTable('collection.motherboard_socket_link')]
#[ORM\JoinColumn('motherboard_id', referencedColumnName: 'id')]
#[ORM\InverseJoinColumn('socket_id', referencedColumnName: 'id')]

View File

@ -0,0 +1,23 @@
<?php declare(strict_types=1);
namespace App\Entity;
use App\Repository\GpuRepository;
use Doctrine\ORM\Mapping as ORM;
/**
* Gpu.previouslyOwnedGpu
*/
#[ORM\Table(name: 'previously_owned_gpu', schema: 'collection')]
#[ORM\Entity(repositoryClass: GpuRepository::class)]
class PreviouslyOwnedGpu {
use GetSet;
use GpuBase;
#[ORM\Column(name: 'id', type: 'integer', nullable: FALSE)]
#[ORM\Id]
#[ORM\GeneratedValue(strategy: 'IDENTITY')]
#[ORM\SequenceGenerator(sequenceName: 'prevously_owned_gpu_id_seq', allocationSize: 1, initialValue: 1)]
private int $id;
}

View File

@ -0,0 +1,85 @@
<?php declare(strict_types=1);
namespace App\Form;
use App\Entity\
{Brand, Gpu, GpuCore, PreviouslyOwnedGpu};
use App\Enum\{CardBus, SlotKey};
use Doctrine\ORM\EntityRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\
{AbstractType, Extension\Core\Type\EnumType, FormBuilderInterface};
use Symfony\Component\OptionsResolver\OptionsResolver;
use UnitEnum;
class PreviouslyOwnedGpuType extends AbstractType {
use BrandCategoryTrait;
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('gpuBrand', EntityType::class, [
'class' => Brand::class,
'query_builder' => self::filterBrands('gpu_core'),
])
->add('modelName')
->add('gpuCore', EntityType::class, [
'class' => GpuCore::class,
'query_builder' => static fn (EntityRepository $e) => $e->createQueryBuilder('gc')->orderBy('gc.brand', 'ASC')->orderBy('gc.name', 'ASC'),
'placeholder' => 'Unknown',
'empty_data' => NULL,
'required' => FALSE,
])
->add('boardBrand', EntityType::class, [
'class' => Brand::class,
'query_builder' => self::filterBrands('graphics_card'),
'empty_data' => NULL,
'placeholder' => 'Unknown',
'required' => FALSE,
])
->add('alternateModelName')
->add('cardKey', EnumType::class, [
'class' => SlotKey::class,
'choices' => SlotKey::getGroups(),
'choice_label' => static fn (UnitEnum $choice): string => $choice->value,
])
->add('busInterface', EnumType::class, [
'class' => CardBus::class,
'choices' => CardBus::getGroups(),
'choice_label' => static fn (UnitEnum $choice): string => $choice->value,
])
->add('slotSpan')
->add('molexPower', NULL, ['label' => 'Molex Power Connectors'])
->add('pcie6power', NULL, ['label' => 'PCIe 6-pin Power Connectors'])
->add('pcie8power', NULL, ['label' => 'PCIe 8-pin Power Connectors'])
->add('tdp', NULL, ['label' => 'TDP (Watts)', 'empty_data' => '0'])
->add('baseClock', NULL, ['label' => 'GPU Base Clock (MHz)'])
->add('boostClock', NULL, ['label' => 'GPU Boost Clock (MHz)'])
->add('memoryClock', NULL, ['label' => 'Memory Speed (MHz)'])
->add('memorySize', NULL, ['label' => 'Memory Size (MB)'])
->add('memoryBus', NULL, ['label' => 'Memory Bus Size (bits)'])
->add('memoryType')
->add('shadingUnits')
->add('tmus', NULL, ['label' => 'TMUs'])
->add('rops', NULL, ['label' => 'ROPs'])
->add('computeUnits')
->add('l1cache', NULL, ['label' => 'L1 Cache'])
->add('l2cache', NULL, ['label' => 'L2 Cache'])
->add('directXSupport', NULL, ['label' => 'DirectX Support'])
->add('openGLSupport', NULL, ['label' => 'OpenGL Support'])
->add('openCLSupport', NULL, ['label' => 'OpenCL Support'])
->add('vulkanSupport')
->add('shaderModel')
->add('link')
->add('count')
->add('acquired')
->add('notes');
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => PreviouslyOwnedGpu::class,
]);
}
}

View File

@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace App\Migrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240320173628 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 collection.previously_owned_gpu (id SERIAL NOT NULL, gpu_brand_id INT NOT NULL, gpu_core_id INT DEFAULT NULL, board_brand_id INT DEFAULT NULL, reference_model_name VARCHAR(255) NOT NULL, alternate_model_name VARCHAR(255) DEFAULT NULL, card_key VARCHAR(255) DEFAULT \'PCIe x16\' NOT NULL, bus_interface VARCHAR(255) DEFAULT NULL, slot_span INT DEFAULT 1 NOT NULL, molex_power INT DEFAULT 0 NOT NULL, pcie_6_pin INT DEFAULT 0 NOT NULL, pcie_8_pin INT DEFAULT 0 NOT NULL, tdp INT DEFAULT NULL, base_clock INT DEFAULT NULL, boost_clock INT DEFAULT NULL, memory_clock INT DEFAULT NULL, memory_size INT DEFAULT NULL, memory_bus INT DEFAULT NULL, memory_type VARCHAR(255) DEFAULT NULL, shading_units INT DEFAULT NULL, tmus INT DEFAULT NULL, rops INT DEFAULT NULL, compute_units INT DEFAULT NULL, l1_cache VARCHAR(255) DEFAULT NULL, l2_cache VARCHAR(255) DEFAULT NULL, direct_x_support VARCHAR(255) DEFAULT NULL, opengl_support VARCHAR(255) DEFAULT NULL, opencl_support VARCHAR(255) DEFAULT NULL, vulkan_support VARCHAR(255) DEFAULT NULL, shader_model VARCHAR(255) DEFAULT NULL, link VARCHAR(255) DEFAULT NULL, count INT DEFAULT 1 NOT NULL, acquired BOOLEAN DEFAULT true NOT NULL, notes TEXT DEFAULT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_5B0869044561DE01 ON collection.previously_owned_gpu (gpu_brand_id)');
$this->addSql('CREATE INDEX IDX_5B08690487059374 ON collection.previously_owned_gpu (gpu_core_id)');
$this->addSql('CREATE INDEX IDX_5B086904D402D3B1 ON collection.previously_owned_gpu (board_brand_id)');
$this->addSql('COMMENT ON COLUMN collection.previously_owned_gpu.card_key IS \'The shape of the card connector\'');
$this->addSql('COMMENT ON COLUMN collection.previously_owned_gpu.bus_interface IS \'The type of electrical bus this card uses\'');
$this->addSql('COMMENT ON COLUMN collection.previously_owned_gpu.slot_span IS \'How many expansion slots the card occupies\'');
$this->addSql('COMMENT ON COLUMN collection.previously_owned_gpu.tdp IS \'Thermal Design Power (in Watts)\'');
$this->addSql('COMMENT ON COLUMN collection.previously_owned_gpu.base_clock IS \'Base speed of the gpu core, in MHz\'');
$this->addSql('COMMENT ON COLUMN collection.previously_owned_gpu.boost_clock IS \'GPU core boost clock, in MHz\'');
$this->addSql('COMMENT ON COLUMN collection.previously_owned_gpu.memory_clock IS \'Clock speed of the VRAM, in MHz\'');
$this->addSql('COMMENT ON COLUMN collection.previously_owned_gpu.memory_size IS \'VRAM size, in MiB\'');
$this->addSql('COMMENT ON COLUMN collection.previously_owned_gpu.memory_bus IS \'The width of the memory bus in bits\'');
$this->addSql('ALTER TABLE collection.previously_owned_gpu ADD CONSTRAINT FK_5B0869044561DE01 FOREIGN KEY (gpu_brand_id) REFERENCES collection.brand (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE collection.previously_owned_gpu ADD CONSTRAINT FK_5B08690487059374 FOREIGN KEY (gpu_core_id) REFERENCES collection.gpu_core (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE collection.previously_owned_gpu ADD CONSTRAINT FK_5B086904D402D3B1 FOREIGN KEY (board_brand_id) REFERENCES collection.brand (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 collection.previously_owned_gpu DROP CONSTRAINT FK_5B0869044561DE01');
$this->addSql('ALTER TABLE collection.previously_owned_gpu DROP CONSTRAINT FK_5B08690487059374');
$this->addSql('ALTER TABLE collection.previously_owned_gpu DROP CONSTRAINT FK_5B086904D402D3B1');
$this->addSql('DROP TABLE collection.previously_owned_gpu');
}
}

View File

@ -0,0 +1,19 @@
<?php declare(strict_types=1);
namespace App\Repository;
use App\Entity\{Gpu, PreviouslyOwnedGpu};
class GpuRepository extends AcquireRepository {
public function deacquire(mixed $currentRecord): void
{
$currentRecord->setAcquired(TRUE);
$this->moveRecord($currentRecord, new PreviouslyOwnedGpu());
}
public function reacquire(mixed $currentRecord): void
{
$this->moveRecord($currentRecord, new Gpu());
}
}

View File

@ -6,7 +6,7 @@ namespace <?= $namespace ?>;
#[Route('<?= $route_path ?>')]
class <?= $class_name ?> extends AbstractController {
use FormControllerTrait;
use FormControllerBase;
protected const ENTITY = <?= $entity_class_name ?>::class;
protected const TEMPLATE_PATH = '<?= $entity_twig_var_singular ?>/';

View File

@ -41,7 +41,7 @@
</ul>
</td>
<td>{{ chipset.id }}</td>
<td>{{ chipset.name }}</td>
<td>{{ chipset.brand.name }} {{ chipset.name }}</td>
<td>{{ chipset.parts }}</td>
<td>{{ chipset.link }}</td>
</tr>

View File

@ -34,7 +34,7 @@
</tr>
<tr>
<th>Name</th>
<td>{{ chipset.name }}</td>
<td>{{ chipset.brand.name }} {{ chipset.name }}</td>
</tr>
<tr>
<th>Parts</th>

View File

@ -0,0 +1,46 @@
<div class="row expanded">
<ul class="menu">
<li class="not-implemented">
<a href="#">🖥️ Systems</a>
</li>
</ul>
<ul class="menu">
<li class="menu-text">Components</li>
<li class="{{ route starts with 'cpu_' ? 'is-active' }}">
<a href="{{ path('cpu_index') }}">🧠 CPUs</a>
</li>
<li class="{{ route starts with 'fpu_' ? 'is-active' }}">
<a href="{{ path('fpu_index') }}">🧮 FPUs</a>
</li>
<li class="{{ route starts with 'gpu_' ? 'is-active' }}">
<a href="{{ path('gpu_index') }}">🎮 GPUs</a>
</li>
<li class="not-implemented {{ route starts with 'motherboard_' ? 'is-active' }}">
<a href="/motherboard/">🤰 Motherboards</a>
</li>
</ul>
<ul class="menu">
<li class="menu-text">Previously Owned</li>
<li class="{{ route starts with 'previously-owned-gpu_' ? 'is-active' }}">
<a href="{{ path('previously-owned-gpu_index') }}">🎮 GPUs</a>
</li>
</ul>
<ul class="menu">
<li class="menu-text">Meta</li>
<li class="{{ route starts with 'brand_' ? 'is-active' }}">
<a href="{{ path('brand_index') }}">🕺 Brands</a>
</li>
<li class="{{ route starts with 'brand-category_' ? 'is-active' }}">
<a href="{{ path('brand-category_index') }}">💃 Brand Categories</a>
</li>
<li class="{{ route starts with 'chipset_' ? 'is-active' }}">
<a href="{{ path('chipset_index') }}">🧩 Chipsets</a>
</li>
<li class="{{ route starts with 'gpu-core' ? 'is-active' }}">
<a href="{{ path('gpu-core_index') }}">🌀 GPU Cores</a>
</li>
<li class="{{ route starts with 'socket_' ? 'is-active' }}">
<a href="{{ path('socket_index') }}">📍Sockets</a>
</li>
</ul>
</div>

View File

@ -4,3 +4,15 @@
Collection CRUD
{% endblock %}
{% block body %}
<div class="cell">
<h2>Computer Collection</h2>
{% include 'computer-menu.html.twig' %}
</div>
<div class="cell">
<h2>Photography</h2>
{% include 'photo-menu.html.twig' %}
</div>
{% endblock %}

View File

@ -97,9 +97,19 @@
>Update</button>
{{ form_end(form) }}
<form method="post" action="{{ path('gpu_delete', {'id': gpu.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ gpu.id) }}">
<button type="submit" class="alert button expanded">Delete</button>
</form>
<div class="grid-x grid-margin-x">
<div class="cell large-6 small-12">
{{ form_start(deacquire_form) }}
{{ form_widget(deacquire_form) }}
<button type="submit" class="button expanded">De-acquire</button>
{{ form_end(deacquire_form) }}
</div>
<div class="cell large-6 small-12">
<form method="post" action="{{ path('gpu_delete', {'id': gpu.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ gpu.id) }}">
<button type="submit" class="alert button expanded">Delete</button>
</form>
</div>
</div>
</div>
{% endblock %}

View File

@ -6,90 +6,14 @@
<a data-toggle="computer-menu" href="#">Computer Related</a>
<div class="dropdown-pane bottom" id="computer-menu" data-dropdown data-options="closeOnClick:true; hover: true; hoverPane: true; vOffset:11">
<div class="row expanded">
<ul class="menu">
<li class="{{ route starts with 'cpu_' ? 'is-active' }}">
<a href="{{ path('cpu_index') }}">🧠 CPUs</a>
</li>
<li class="{{ route starts with 'fpu_' ? 'is-active' }}">
<a href="{{ path('fpu_index') }}">🧮 FPUs</a>
</li>
<li class="{{ route starts with 'gpu_' ? 'is-active' }}">
<a href="{{ path('gpu_index') }}">🎮 GPUs</a>
</li>
<li class="not-implemented {{ route starts with 'motherboard_' ? 'is-active' }}">
<a href="#">🤰 Motherboards</a>
</li>
<li class="not-implemented">
<a href="#">🖥️ Systems</a>
</li>
</ul>
<ul class="menu">
<li class="menu-text">Meta</li>
<li class="{{ route starts with 'brand_' ? 'is-active' }}">
<a href="{{ path('brand_index') }}">🕺 Brands</a>
</li>
<li class="{{ route starts with 'brand-category_' ? 'is-active' }}">
<a href="{{ path('brand-category_index') }}">💃 Brand Categories</a>
</li>
<li class="{{ route starts with 'chipset_' ? 'is-active' }}">
<a href="{{ path('chipset_index') }}">🧩 Chipsets</a>
</li>
<li class="{{ route starts with 'gpu-core' ? 'is-active' }}">
<a href="{{ path('gpu-core_index') }}">🌀 GPU Cores</a>
</li>
<li class="{{ route starts with 'socket_' ? 'is-active' }}">
<a href="{{ path('socket_index') }}">📍Sockets</a>
</li>
</ul>
</div>
{% include 'computer-menu.html.twig' %}
</div>
</li>
<li class="mega-menu">
<a data-toggle="photo-menu" href="#">Photography</a>
<div class="dropdown-pane bottom" id="photo-menu" data-dropdown data-options="closeOnClick:true; hover: true; hoverPane: true; vOffset:11">
<div class="row expanded">
<div class="column">
<ul class="menu">
<li class="menu-text">Currently Owned</li>
<li class="{{ route starts with 'camera_' ? 'is-active' }}">
<a href="{{ path('camera_index') }}">📷 Cameras</a>
</li>
<li class="{{ route starts with 'flash_' ? 'is-active' }}">
<a href="{{ path('flash_index') }}">📸 Flashes</a>
</li>
<li class="{{ route starts with 'lens_' ? 'is-active' }}">
<a href="{{ path('lens_index') }}">🔎 Lenses</a>
</li>
</ul>
</div>
<div class="column">
<ul class="menu">
<li class="menu-text">Previously Owned</li>
<li class="{{ route starts with 'previously-owned-camera' ? 'is-active' }}">
<a href="{{ path('previously-owned-camera_index') }}">📷 Cameras</a>
</li>
<li class="{{ route starts with 'previously-owned-flash' ? 'is-active' }}">
<a href="{{ path('previously-owned-flash_index') }}">📸 Flashes</a>
</li>
<li class="{{ route starts with 'previously-owned-lens' ? 'is-active' }}">
<a href="{{ path('previously-owned-lens_index') }}">🔎 Lenses</a>
</li>
</ul>
</div>
<div class="column">
<ul class="menu">
<li class="menu-text">Meta</li>
<li class="{{ route starts with 'film_' ? 'is-active' }}">
<a href="{{ path('film_index') }}">🎞️ Film</a>
</li>
<li class="{{ route starts with 'camera-type_' ? 'is-active' }}">
<a href="{{ path('camera-type_index') }}">🎥 Camera Types</a>
</li>
</ul>
</div>
</div>
{% include 'photo-menu.html.twig' %}
</div>
</li>
</ul>

View File

@ -0,0 +1,41 @@
<div class="row expanded">
<div class="column">
<ul class="menu">
<li class="menu-text">Currently Owned</li>
<li class="{{ route starts with 'camera_' ? 'is-active' }}">
<a href="{{ path('camera_index') }}">📷 Cameras</a>
</li>
<li class="{{ route starts with 'flash_' ? 'is-active' }}">
<a href="{{ path('flash_index') }}">📸 Flashes</a>
</li>
<li class="{{ route starts with 'lens_' ? 'is-active' }}">
<a href="{{ path('lens_index') }}">🔎 Lenses</a>
</li>
</ul>
</div>
<div class="column">
<ul class="menu">
<li class="menu-text">Previously Owned</li>
<li class="{{ route starts with 'previously-owned-camera' ? 'is-active' }}">
<a href="{{ path('previously-owned-camera_index') }}">📷 Cameras</a>
</li>
<li class="{{ route starts with 'previously-owned-flash' ? 'is-active' }}">
<a href="{{ path('previously-owned-flash_index') }}">📸 Flashes</a>
</li>
<li class="{{ route starts with 'previously-owned-lens' ? 'is-active' }}">
<a href="{{ path('previously-owned-lens_index') }}">🔎 Lenses</a>
</li>
</ul>
</div>
<div class="column">
<ul class="menu">
<li class="menu-text">Meta</li>
<li class="{{ route starts with 'film_' ? 'is-active' }}">
<a href="{{ path('film_index') }}">🎞️ Film</a>
</li>
<li class="{{ route starts with 'camera-type_' ? 'is-active' }}">
<a href="{{ path('camera-type_index') }}">🎥 Camera Types</a>
</li>
</ul>
</div>
</div>

View File

@ -0,0 +1,107 @@
{% extends 'form.html.twig' %}
{% block title %}Edit Previously Owned Gpu{% endblock %}
{% block form %}
<h2>Edit Graphics Card</h2>
<div class="small callout">
<ul>
<li>
<a href="{{ path('previously-owned-gpu_index') }}">Back to the list</a>
</li>
</ul>
</div>
<div>
{{ form_start(form) }}
<fieldset class="large primary callout">
<legend>Names / Brands</legend>
{{ form_row(form.gpuBrand) }}
{{ form_row(form.modelName) }}
{{ form_row(form.gpuCore) }}
<hr />
{{ form_row(form.boardBrand) }}
{{ form_row(form.alternateModelName) }}
</fieldset>
<fieldset class="large primary callout">
<legend>Bus / Size</legend>
{{ form_row(form.cardKey) }}
{{ form_row(form.busInterface) }}
{{ form_row(form.slotSpan) }}
</fieldset>
<fieldset class="large primary callout">
<legend>Power</legend>
{{ form_row(form.molexPower) }}
{{ form_row(form.pcie6power) }}
{{ form_row(form.pcie8power) }}
{{ form_row(form.tdp) }}
</fieldset>
<fieldset class="large primary callout">
<legend>Clock Speeds</legend>
{{ form_row(form.baseClock) }}
{{ form_row(form.boostClock) }}
{{ form_row(form.memoryClock) }}
</fieldset>
<fieldset class="large primary callout">
<legend>Memory</legend>
{{ form_row(form.memorySize) }}
{{ form_row(form.memoryBus) }}
{{ form_row(form.memoryType) }}
</fieldset>
<fieldset class="large primary callout">
<legend>Rendering Hardware</legend>
{{ form_row(form.shadingUnits) }}
{{ form_row(form.tmus) }}
{{ form_row(form.rops) }}
{{ form_row(form.computeUnits) }}
{{ form_row(form.l1cache) }}
{{ form_row(form.l2cache) }}
</fieldset>
<fieldset class="large primary callout">
<legend>API Support</legend>
{{ form_row(form.directXSupport) }}
{{ form_row(form.openGLSupport) }}
{{ form_row(form.openCLSupport) }}
{{ form_row(form.vulkanSupport) }}
{{ form_row(form.shaderModel) }}
</fieldset>
<fieldset class="large primary callout">
<legend>Misc.</legend>
{{ form_row(form.link) }}
{{ form_row(form.count) }}
{{ form_row(form.acquired) }}
{{ form_row(form.notes) }}
</fieldset>
{{ form_widget(form) }}
<button
type="submit"
class="success button expanded"
>Update</button>
{{ form_end(form) }}
{{ form_start(reacquire_form) }}
{{ form_widget(reacquire_form) }}
<button type="submit" class="button expanded">Reacquire</button>
{{ form_end(reacquire_form) }}
</div>
{% endblock %}

View File

@ -0,0 +1,83 @@
{% extends 'base.html.twig' %}
{% block title %}Previously Owned Gpu index{% endblock %}
{% block body %}
<h2>Previously Owned Graphics Cards</h2>
<table class="hover scroll sortable stack">
<thead>
<tr>
<th>&nbsp;</th>
<th>Id</th>
<th>Model Name</th>
<th>GPU</th>
<th>Card Brand</th>
<th>Alternate Model Name</th>
<th>Card Key / Bus Interface</th>
<th>Slot Width</th>
<th>Power</th>
<th>Tdp</th>
<th>Memory</th>
<th>Link</th>
<th>Count</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
{% for gpu in gpus %}
<tr>
<td>
<ul>
<li>
<a href="{{ path('previously-owned-gpu_show', {'id': gpu.id}) }}">View 👁</a>
</li>
<li>
<a href="{{ path('previously-owned-gpu_edit', {'id': gpu.id}) }}">Edit <span class="edit-icon">&#9998;</span></a>
</li>
</ul>
</td>
<td>{{ gpu.id }}</td>
<td>{{ gpu.gpuBrand.name }} {{ gpu.modelName }}</td>
<td>
{% if gpu.gpuCore %}
{% if gpu.gpuCore.variant %}
{{ gpu.gpuCore.name }} ({{ gpu.gpuCore.variant }})
{% else %}
{{ gpu.gpuCore.name }}
{% endif %}
{% endif %}
</td>
<td>{% if gpu.boardBrand %}{{ gpu.boardBrand.name }}{% else %}Unknown{% endif %}</td>
<td>{{ gpu.alternateModelName }}</td>
<td>{{ gpu.cardKey.value }} / {{ gpu.busInterface.value }}</td>
<td>{{ gpu.slotSpan }}</td>
<td>
{% if gpu.pcie6power > 0 or gpu.pcie8power > 0 %}
{% if gpu.pcie6power > 0 %}
{{ gpu.pcie6power }} PCIe 6-pin
{% endif %}
{% if gpu.pcie8power > 0 %}
{{ gpu.pcie8power }} PCIe 8-pin
{% endif %}
{% elseif gpu.molexPower > 0 %}
{{ gpu.molexPower }} Molex
{% else %}
Slot
{% endif %}
</td>
<td>{{ gpu.tdp }}</td>
<td>{{ gpu.memorySize }}MiB {{ gpu.memoryClock }}MHz {{ gpu.memoryBus }}bit {{ gpu.memoryType }}</td>
<td><a href="{{ gpu.link }}">Specs</a></td>
<td>{{ gpu.count }}</td>
<td>{{ gpu.notes }}</td>
</tr>
{% else %}
<tr>
<td colspan="32">no records found</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -0,0 +1,159 @@
{% extends 'form.html.twig' %}
{% block title %}Gpu{% endblock %}
{% block form %}
<h2>Graphics Card</h2>
<div class="callout">
<ul>
<li>
<a href="{{ path('previously-owned-gpu_index') }}">Back to the list</a>
</li>
<li>
<a href="{{ path('previously-owned-gpu_edit', { 'id': previouslyOwnedGpu.id }) }}">Edit</a>
</li>
</ul>
<hr />
<form method="post" action="{{ path('previously-owned-gpu_delete', {'id': previouslyOwnedGpu.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ previouslyOwnedGpu.id) }}">
<button type="submit" class="alert button expanded">Delete</button>
</form>
</div>
<div class="large primary callout">
<table class="table">
<tbody>
<tr>
<th>Id</th>
<td>{{ previouslyOwnedGpu.id }}</td>
</tr>
<tr>
<th>ModelName</th>
<td>{{ previouslyOwnedGpu.modelName }}</td>
</tr>
<tr>
<th>AlternateModelName</th>
<td>{{ previouslyOwnedGpu.alternateModelName }}</td>
</tr>
<tr>
<th>CardKey</th>
<td>{{ previouslyOwnedGpu.cardKey.value }}</td>
</tr>
<tr>
<th>BusInterface</th>
<td>{{ previouslyOwnedGpu.busInterface.value }}</td>
</tr>
<tr>
<th>slotSpan</th>
<td>{{ previouslyOwnedGpu.slotSpan }}</td>
</tr>
<tr>
<th>MolexPower</th>
<td>{{ previouslyOwnedGpu.molexPower }}</td>
</tr>
<tr>
<th>Pcie6power</th>
<td>{{ previouslyOwnedGpu.pcie6power }}</td>
</tr>
<tr>
<th>Pcie8power</th>
<td>{{ previouslyOwnedGpu.pcie8power }}</td>
</tr>
<tr>
<th>Tdp</th>
<td>{{ previouslyOwnedGpu.tdp }}</td>
</tr>
<tr>
<th>BaseClock</th>
<td>{{ previouslyOwnedGpu.baseClock }}</td>
</tr>
<tr>
<th>BoostClock</th>
<td>{{ previouslyOwnedGpu.boostClock }}</td>
</tr>
<tr>
<th>MemoryClock</th>
<td>{{ previouslyOwnedGpu.memoryClock }}</td>
</tr>
<tr>
<th>MemorySize</th>
<td>{{ previouslyOwnedGpu.memorySize }}</td>
</tr>
<tr>
<th>MemoryBus</th>
<td>{{ previouslyOwnedGpu.memoryBus }}</td>
</tr>
<tr>
<th>MemoryType</th>
<td>{{ previouslyOwnedGpu.memoryType }}</td>
</tr>
<tr>
<th>ShadingUnits</th>
<td>{{ previouslyOwnedGpu.shadingUnits }}</td>
</tr>
<tr>
<th>Tmus</th>
<td>{{ previouslyOwnedGpu.tmus }}</td>
</tr>
<tr>
<th>Rops</th>
<td>{{ previouslyOwnedGpu.rops }}</td>
</tr>
<tr>
<th>ComputeUnits</th>
<td>{{ previouslyOwnedGpu.computeUnits }}</td>
</tr>
<tr>
<th>L1cache</th>
<td>{{ previouslyOwnedGpu.l1cache }}</td>
</tr>
<tr>
<th>L2cache</th>
<td>{{ previouslyOwnedGpu.l2cache }}</td>
</tr>
<tr>
<th>DirectXSupport</th>
<td>{{ previouslyOwnedGpu.directXSupport }}</td>
</tr>
<tr>
<th>OpenGLSupport</th>
<td>{{ previouslyOwnedGpu.openGLSupport }}</td>
</tr>
<tr>
<th>OpenCLSupport</th>
<td>{{ previouslyOwnedGpu.openCLSupport }}</td>
</tr>
<tr>
<th>VulkanSupport</th>
<td>{{ previouslyOwnedGpu.vulkanSupport }}</td>
</tr>
<tr>
<th>ShaderModel</th>
<td>{{ previouslyOwnedGpu.shaderModel }}</td>
</tr>
<tr>
<th>Link</th>
<td>{{ previouslyOwnedGpu.link }}</td>
</tr>
<tr>
<th>Count</th>
<td>{{ previouslyOwnedGpu.count }}</td>
</tr>
<tr>
<th>Acquired</th>
<td>{{ previouslyOwnedGpu.acquired ? 'Yes' : 'No' }}</td>
</tr>
<tr>
<th>Notes</th>
<td>{{ previouslyOwnedGpu.notes }}</td>
</tr>
</tbody>
</table>
</div>
{% endblock %}

View File

@ -44,6 +44,7 @@ return [
'Card key' => 'Card Interface Keying',
'Categories' => 'Categories',
'Cellulose Triacetate' => 'Cellulose Triacetate',
'Chipset' => 'Chipset',
'Chemistry' => 'Film Chemistry',
'Clock speed' => 'Clock Speed (MHz)',
'Coatings' => 'Coatings',