diff options
author | Daniel Weipert <code@drogueronin.de> | 2022-01-14 18:21:36 +0100 |
---|---|---|
committer | Daniel Weipert <code@drogueronin.de> | 2022-01-14 18:21:36 +0100 |
commit | 4cacc94240944ff316104bfd1b5e8e00fad14517 (patch) | |
tree | 2559dc3aa121d70bd645ff0a2fe56e1ae0695daa /src | |
parent | 9c0893cb65df986b9edf0f48a6d4d2d65f27b8ef (diff) |
Add Artworks, Votes and better routing
Diffstat (limited to 'src')
-rw-r--r-- | src/Controller/Card.php | 42 | ||||
-rw-r--r-- | src/Controller/Home.php | 11 | ||||
-rw-r--r-- | src/Model/Artwork.php | 101 | ||||
-rw-r--r-- | src/Model/Card.php | 49 | ||||
-rw-r--r-- | src/Model/Vote.php | 30 | ||||
-rw-r--r-- | src/Model/VoteArtwork.php | 26 | ||||
-rw-r--r-- | src/Model/VoteCard.php | 26 | ||||
-rw-r--r-- | src/Router.php | 81 |
8 files changed, 330 insertions, 36 deletions
diff --git a/src/Controller/Card.php b/src/Controller/Card.php index 39560bb..d4ee393 100644 --- a/src/Controller/Card.php +++ b/src/Controller/Card.php @@ -3,8 +3,12 @@ namespace Elements\Controller; use Elements\DB; +use Elements\Model\Artwork; use Elements\Model\Card as CardModel; use Elements\Model\CardMeta; +use Elements\Model\VoteArtwork; +use Elements\Model\VoteCard; +use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -21,11 +25,49 @@ class Card DB::save($meta); } + /**@var UploadedFile[] $files*/ + if ($files = $request->files->get('images')) { + foreach ($files as $file) { + $image = Artwork::fromUploadedFile($file); + + /*TEST*/ + for ($i = 0; $i <= rand(0, 40); $i++) { + $vote = new VoteArtwork(); + $vote->value = rand(-1, 1) >= 0 ? 1 : -1; + $image->addVote($vote); + DB::save($vote); + } + /*TEST*/ + + $card->addArtwork($image); + DB::save($image); + } + } + + /*TEST*/ + for ($i = 0; $i <= rand(0, 60); $i++) { + $vote = new VoteCard(); + $vote->value = rand(-1, 1) > 0 ? 1 : -1; + $card->addVote($vote); + DB::save($vote); + } + /*TEST*/ + DB::save($card); $response = new RedirectResponse('/'); return $response; } + + public static function get(Request $request) + { + $route = $request->attributes->get('route'); + $cardId = $route['id']; + + $card = DB::$entityManager->getRepository(CardModel::class)->find($cardId); + + return $card->getMeta('name'); + } } diff --git a/src/Controller/Home.php b/src/Controller/Home.php index 511b89b..1c1500c 100644 --- a/src/Controller/Home.php +++ b/src/Controller/Home.php @@ -14,9 +14,18 @@ class Home echo "<pre>"; $c && var_dump( array_map(fn ($item) => [$item->key, $item->value], $c->meta->toArray()), + array_map(fn ($item) => "<img style='max-width: 100%;max-height:300px;' src='$item->path'> Votes: " . $item->getVotesTotal(), $c->artworks->toArray()), + array_map(fn ($item) => $item->value, $c->votes->toArray()), + 'Votes: ' . $c->getVotesTotal(), ); - return Template::render('home.twig'); + return Template::render('home.twig', [ + 'fields' => [ + 'name' => 'meta[name]', + 'converted mana cost' => 'meta[cmc]', + 'is uno reverse' => 'meta[is_uno_reverse]', + ], + ]); } } diff --git a/src/Model/Artwork.php b/src/Model/Artwork.php new file mode 100644 index 0000000..25f6ee5 --- /dev/null +++ b/src/Model/Artwork.php @@ -0,0 +1,101 @@ +<?php + +namespace Elements\Model; + +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\Table; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\GeneratedValue; +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\ManyToOne; +use Doctrine\ORM\PersistentCollection; +use Elements\DB; +use Symfony\Component\HttpFoundation\File\UploadedFile; + +#[Entity] +#[Table(name: 'artworks')] +/** + * @Entity + * @Table(name="artworks") + */ +class Artwork +{ + #[Id] + #[Column(type: 'integer')] + #[GeneratedValue] + /** + * @Id + * @Column(type="integer") + * @GeneratedValue + */ + public int $id; + + #[Column(type: 'string')] + /** + * @Column(type="string") + */ + public string $path; + + #[ManyToOne(targetEntity: Card::class, inversedBy: 'artworks')] + /** + * @ManyToOne(targetEntity="Card", inversedBy="artworks", cascade={"persist"}) + */ + public Card $card; + + #[OneToMany(targetEntity: VoteArtwork::class, mappedBy: 'artwork')] + /** + * @OneToMany(targetEntity="VoteArtwork", mappedBy="artwork") + */ + public Collection|ArrayCollection|PersistentCollection $votes; + + /** + * Artwork constructor. + */ + public function __construct(string $path) + { + $this->path = $path; + $this->votes = new ArrayCollection(); + } + + /** + * @param UploadedFile $file + * + * @return self + */ + public static function fromUploadedFile(UploadedFile $file): self + { + $artworksDir = dirname(dirname(__DIR__)) . '/public/artworks/'; + $path = str_replace($_SERVER['DOCUMENT_ROOT'], '', $artworksDir . $file->getClientOriginalName()); + $file->move($artworksDir, $file->getClientOriginalName()); + + return new self($path); + } + + /** + * @param VoteArtwork $vote + */ + public function addVote(VoteArtwork $vote) + { + $vote->artwork = $this; + $this->votes[] = $vote; + } + + /** + * @return int + */ + public function getVotesTotal(): int + { + $result = DB::$entityManager + ->createQuery( + 'SELECT sum(v.value) as total + FROM Elements\Model\VoteArtwork v + WHERE v.artwork = :artwork' + ) + ->setParameter('artwork', $this) + ->getOneOrNullResult(); + + return $result['total'] ?? 0; + } +} + diff --git a/src/Model/Card.php b/src/Model/Card.php index ab421ab..9707e16 100644 --- a/src/Model/Card.php +++ b/src/Model/Card.php @@ -37,12 +37,26 @@ class Card */ public Collection|ArrayCollection|PersistentCollection $meta; + #[OneToMany(targetEntity: Artwork::class, mappedBy: 'card')] + /** + * @OneToMany(targetEntity="Artwork", mappedBy="card") + */ + public Collection|ArrayCollection|PersistentCollection $artworks; + + #[OneToMany(targetEntity: VoteCard::class, mappedBy: 'card')] + /** + * @OneToMany(targetEntity="VoteCard", mappedBy="card") + */ + public Collection|ArrayCollection|PersistentCollection $votes; + /** * Card constructor. */ public function __construct() { $this->meta = new ArrayCollection(); + $this->artworks = new ArrayCollection(); + $this->votes = new ArrayCollection(); } /** @@ -55,6 +69,24 @@ class Card } /** + * @param Artwork $artwork + */ + public function addArtwork(Artwork $artwork) + { + $artwork->card = $this; + $this->artworks[] = $artwork; + } + + /** + * @param VoteCard $vote + */ + public function addVote(VoteCard $vote) + { + $vote->card = $this; + $this->votes[] = $vote; + } + + /** * @param string $key * * @return string @@ -83,5 +115,22 @@ class Card return $result['value'] ?? null; } + + /** + * @return int + */ + public function getVotesTotal(): int + { + $result = DB::$entityManager + ->createQuery( + 'SELECT sum(v.value) as total + FROM Elements\Model\VoteCard v + WHERE v.card = :card' + ) + ->setParameter('card', $this) + ->getOneOrNullResult(); + + return $result['total'] ?? 0; + } } diff --git a/src/Model/Vote.php b/src/Model/Vote.php new file mode 100644 index 0000000..c5415aa --- /dev/null +++ b/src/Model/Vote.php @@ -0,0 +1,30 @@ +<?php + +namespace Elements\Model; + +use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\Table; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\GeneratedValue; +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\ManyToOne; + +class Vote +{ + #[Id] + #[Column(type: 'integer')] + #[GeneratedValue] + /** + * @Id + * @Column(type="integer") + * @GeneratedValue + */ + public int $id; + + #[Column(type: 'integer')] + /** + * @Column(type="integer") + */ + public int $value; +} + diff --git a/src/Model/VoteArtwork.php b/src/Model/VoteArtwork.php new file mode 100644 index 0000000..ee6ac8b --- /dev/null +++ b/src/Model/VoteArtwork.php @@ -0,0 +1,26 @@ +<?php + +namespace Elements\Model; + +use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\Table; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\GeneratedValue; +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\ManyToOne; + +#[Entity] +#[Table(name: 'votes_artwork')] +/** + * @Entity + * @Table(name="votes_artwork") + */ +class VoteArtwork extends Vote +{ + #[ManyToOne(targetEntity: Artwork::class, inversedBy: 'votes')] + /** + * @ManyToOne(targetEntity="Artwork", inversedBy="votes", cascade={"persist"}) + */ + public Artwork $artwork; +} + diff --git a/src/Model/VoteCard.php b/src/Model/VoteCard.php new file mode 100644 index 0000000..e9b3e60 --- /dev/null +++ b/src/Model/VoteCard.php @@ -0,0 +1,26 @@ +<?php + +namespace Elements\Model; + +use Doctrine\DBAL\Schema\Column; +use Doctrine\DBAL\Schema\Table; +use Doctrine\ORM\Mapping\Entity; +use Doctrine\ORM\Mapping\GeneratedValue; +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\ManyToOne; + +#[Entity] +#[Table(name: 'votes_card')] +/** + * @Entity + * @Table(name="votes_card") + */ +class VoteCard extends Vote +{ + #[ManyToOne(targetEntity: Card::class, inversedBy: 'votes')] + /** + * @ManyToOne(targetEntity="Card", inversedBy="votes", cascade={"persist"}) + */ + public Card $card; +} + diff --git a/src/Router.php b/src/Router.php index 377c00b..5635d5c 100644 --- a/src/Router.php +++ b/src/Router.php @@ -7,64 +7,75 @@ use Elements\Controller\Home; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Matcher\UrlMatcher; +use Symfony\Component\Routing\RequestContext; +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; class Router { - private $routes = [ - 'GET' => [ - '/' => [Home::class, 'index'], - ], - - 'POST' => [ - '/card/add' => [Card::class, 'add'], - ], - ]; + private ?RouteCollection $routes; + private array $routeFunctions = []; /** * Router constructor. */ public function __construct() { + /**@var Request $request*/ $request = Request::createFromGlobals(); $response = new Response(); - $method = $request->getMethod(); - $path = $request->getPathInfo(); + $this->routes = new RouteCollection(); + $this->addRoute('GET', '/', [Home::class, 'index']); + $this->addRoute('GET', '/card/{id}', [Card::class, 'get']); + $this->addRoute('POST', '/card/add', [Card::class, 'add']); + + $context = new RequestContext(); + $context->fromRequest($request); + $matcher = new UrlMatcher($this->routes, $context); - // if the route is defined - if (isset($this->routes[$method][$path])) { - try { - // run controller function - $content = call_user_func($this->routes[$method][$path], $request); + try { + $match = $matcher->match($request->getPathInfo()); + $request->attributes->set('route', $match); - // set response to new response - if ($content instanceof Response) { - $response = $content; - } + // run controller function + $content = call_user_func($this->routeFunctions[$match['_route']], $request); - // set content directly otherwise - else { - $response->setContent($content); - } + // set response to new response + if ($content instanceof Response) { + $response = $content; } - // catch any errors - catch (AppException $exception) { - $response->setStatusCode($exception->getCode()); - $response->setContent($exception->getMessage()); - } catch (\Exception $exception) { - $response->setStatusCode(Response::HTTP_BAD_REQUEST); - $response->setContent($exception->getMessage()); + // set content directly otherwise + else { + $response->setContent($content); } } - // route is not defined - else { - $response->setStatusCode(Response::HTTP_NOT_FOUND); - $response->setContent('Not Found'); + // catch any errors + catch (AppException $exception) { + $response->setStatusCode($exception->getCode()); + $response->setContent($exception->getMessage()); + } catch (\Exception $exception) { + $response->setStatusCode(Response::HTTP_BAD_REQUEST); + $response->setContent($exception->getMessage()); } $response->send(); } + + /** + * @param string|array $methods + * @param string $path + * @param callable $function + */ + public function addRoute(string|array $methods, string $path, array $function) + { + $name = "$function[0]::$function[1]"; + + $this->routes->add($name, new Route($path, methods: (array)$methods)); + $this->routeFunctions[$name] = $function; + } } |