From 4cacc94240944ff316104bfd1b5e8e00fad14517 Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Fri, 14 Jan 2022 18:21:36 +0100 Subject: Add Artworks, Votes and better routing --- src/Controller/Card.php | 42 +++++++++++++++++++ src/Controller/Home.php | 11 ++++- src/Model/Artwork.php | 101 ++++++++++++++++++++++++++++++++++++++++++++++ src/Model/Card.php | 49 ++++++++++++++++++++++ src/Model/Vote.php | 30 ++++++++++++++ src/Model/VoteArtwork.php | 26 ++++++++++++ src/Model/VoteCard.php | 26 ++++++++++++ src/Router.php | 81 +++++++++++++++++++++---------------- 8 files changed, 330 insertions(+), 36 deletions(-) create mode 100644 src/Model/Artwork.php create mode 100644 src/Model/Vote.php create mode 100644 src/Model/VoteArtwork.php create mode 100644 src/Model/VoteCard.php (limited to 'src') 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 "
";
     $c && var_dump(
       array_map(fn ($item) => [$item->key, $item->value], $c->meta->toArray()),
+      array_map(fn ($item) => " 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 @@
+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();
   }
 
   /**
@@ -54,6 +68,24 @@ class Card
     $this->meta[] = $meta;
   }
 
+  /**
+   * @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
    *
@@ -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 @@
+ [
-      '/' => [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;
+  }
 }
 
-- 
cgit v1.2.3