summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Weipert <code@drogueronin.de>2022-01-10 20:29:04 +0100
committerDaniel Weipert <code@drogueronin.de>2022-01-10 20:29:04 +0100
commita319f3a419790925bed539ba141038c72a83e70f (patch)
treedfb24183cc693863df733e190dbbc6da93bb82e5 /src
Initial commit
Diffstat (limited to 'src')
-rw-r--r--src/AppException.php7
-rw-r--r--src/Controller/Card.php31
-rw-r--r--src/Controller/Home.php22
-rw-r--r--src/DB.php55
-rw-r--r--src/Model/Card.php87
-rw-r--r--src/Model/CardMeta.php57
-rw-r--r--src/Router.php70
-rw-r--r--src/Template.php23
8 files changed, 352 insertions, 0 deletions
diff --git a/src/AppException.php b/src/AppException.php
new file mode 100644
index 0000000..d7949a3
--- /dev/null
+++ b/src/AppException.php
@@ -0,0 +1,7 @@
+<?php
+
+namespace Elements;
+
+class AppException extends \Exception
+{}
+
diff --git a/src/Controller/Card.php b/src/Controller/Card.php
new file mode 100644
index 0000000..39560bb
--- /dev/null
+++ b/src/Controller/Card.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Elements\Controller;
+
+use Elements\DB;
+use Elements\Model\Card as CardModel;
+use Elements\Model\CardMeta;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+
+class Card
+{
+ public static function add(Request $request)
+ {
+ $card = new CardModel();
+
+ foreach ($request->get('meta') as $key => $value) {
+ $meta = new CardMeta($key, $value);
+ $card->addMeta($meta);
+ DB::save($meta);
+ }
+
+ DB::save($card);
+
+ $response = new RedirectResponse('/');
+
+ return $response;
+ }
+}
+
diff --git a/src/Controller/Home.php b/src/Controller/Home.php
new file mode 100644
index 0000000..511b89b
--- /dev/null
+++ b/src/Controller/Home.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Elements\Controller;
+
+use Elements\DB;
+use Elements\Model\Card;
+use Elements\Template;
+
+class Home
+{
+ public static function index()
+ {
+ $c = DB::$entityManager->getRepository(Card::class)->findOneBy([], ['id' => 'DESC']);
+ echo "<pre>";
+ $c && var_dump(
+ array_map(fn ($item) => [$item->key, $item->value], $c->meta->toArray()),
+ );
+
+ return Template::render('home.twig');
+ }
+}
+
diff --git a/src/DB.php b/src/DB.php
new file mode 100644
index 0000000..c04d189
--- /dev/null
+++ b/src/DB.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Elements;
+
+use Doctrine\ORM\Cache;
+use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\Mapping\Driver\AttributeDriver;
+use Doctrine\ORM\Tools\Setup;
+
+class DB
+{
+ public static EntityManager $entityManager;
+
+ /**
+ * DB constructor.
+ */
+ public static function init()
+ {
+ $isDevMode = true;
+ $proxyDir = null;
+ $cache = null;
+ $config = Setup::createConfiguration($isDevMode, $proxyDir, $cache);
+ $config->setMetadataDriverImpl($config->newDefaultAnnotationDriver([__DIR__ . '/Model'], true));
+ #$config->setMetadataDriverImpl(new AttributeDriver([__DIR__ . '/Model']));
+
+ $conn = array(
+ 'driver' => 'pdo_sqlite',
+ 'path' => dirname(__DIR__) . '/db.sqlite',
+ );
+
+ self::$entityManager = EntityManager::create($conn, $config);
+ }
+
+ /**
+ * @param object $entity
+ * @param array $criteria
+ */
+ public static function save(object $entity, array $criteria = [])
+ {
+ $repository = self::$entityManager->getRepository(get_class($entity));
+ $exists = $repository->findOneBy($criteria);
+
+ if (! empty($criteria) && ! is_null($exists)) {
+ foreach (get_object_vars($entity) as $key => $value) {
+ $exists->$key = $value;
+ }
+ } else {
+ $exists = $entity;
+ }
+
+ self::$entityManager->persist($exists);
+ self::$entityManager->flush();
+ }
+}
+
diff --git a/src/Model/Card.php b/src/Model/Card.php
new file mode 100644
index 0000000..ab421ab
--- /dev/null
+++ b/src/Model/Card.php
@@ -0,0 +1,87 @@
+<?php
+
+namespace Elements\Model;
+
+use Doctrine\Common\Collections\ArrayCollection;
+use Doctrine\Common\Collections\Collection;
+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\OneToMany;
+use Doctrine\ORM\PersistentCollection;
+use Elements\DB;
+
+#[Entity]
+#[Table(name: 'cards')]
+/**
+ * @Entity
+ * @Table(name="cards")
+ */
+class Card
+{
+ #[Id]
+ #[Column(type: 'integer')]
+ #[GeneratedValue]
+ /**
+ * @Id
+ * @Column(type="integer")
+ * @GeneratedValue
+ */
+ public int $id;
+
+ #[OneToMany(targetEntity: CardMeta::class, mappedBy: 'card')]
+ /**
+ * @OneToMany(targetEntity="CardMeta", mappedBy="card")
+ */
+ public Collection|ArrayCollection|PersistentCollection $meta;
+
+ /**
+ * Card constructor.
+ */
+ public function __construct()
+ {
+ $this->meta = new ArrayCollection();
+ }
+
+ /**
+ * @param CardMeta $meta
+ */
+ public function addMeta(CardMeta $meta)
+ {
+ $meta->card = $this;
+ $this->meta[] = $meta;
+ }
+
+ /**
+ * @param string $key
+ *
+ * @return string
+ */
+ public function getMeta(string $key): ?string
+ {
+ // if meta is already hydrated
+ if ($this->meta->isInitialized()) {
+ $meta = $this->meta->unwrap()
+ #->findFirst(fn (CardMeta $item) => $item->key === $key);
+ ->filter(fn ($item) => $item->key === $key)->first();
+
+ return $meta->value ?? null;
+ }
+
+ // get directly from db otherwise
+ $result = DB::$entityManager
+ ->createQuery(
+ 'SELECT cm.value
+ FROM Elements\Model\CardMeta cm
+ WHERE cm.key = :key AND cm.card = :card'
+ )
+ ->setParameter('key', $key)
+ ->setParameter('card', $this)
+ ->getOneOrNullResult();
+
+ return $result['value'] ?? null;
+ }
+}
+
diff --git a/src/Model/CardMeta.php b/src/Model/CardMeta.php
new file mode 100644
index 0000000..2ec0da9
--- /dev/null
+++ b/src/Model/CardMeta.php
@@ -0,0 +1,57 @@
+<?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: 'card_meta')]
+/**
+ * @Entity
+ * @Table(name="card_meta")
+ */
+class CardMeta
+{
+ #[Id]
+ #[Column(type: 'integer')]
+ #[GeneratedValue]
+ /**
+ * @Id
+ * @Column(type="integer")
+ * @GeneratedValue
+ */
+ public int $id;
+
+ #[Column(type: 'string')]
+ /**
+ * @Column(type="string")
+ */
+ public string $key;
+
+ #[Column(type: 'string')]
+ /**
+ * @Column(type="string")
+ */
+ public string $value;
+
+ #[ManyToOne(targetEntity: Card::class, inversedBy: 'meta')]
+ /**
+ * @ManyToOne(targetEntity="Card", inversedBy="meta", cascade={"persist"})
+ */
+ public Card $card;
+
+ /**
+ * CardMeta constructor.
+ */
+ public function __construct(string $key, string $value)
+ {
+ $this->key = $key;
+ $this->value = $value;
+ }
+}
+
diff --git a/src/Router.php b/src/Router.php
new file mode 100644
index 0000000..377c00b
--- /dev/null
+++ b/src/Router.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace Elements;
+
+use Elements\Controller\Card;
+use Elements\Controller\Home;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+
+class Router
+{
+ private $routes = [
+ 'GET' => [
+ '/' => [Home::class, 'index'],
+ ],
+
+ 'POST' => [
+ '/card/add' => [Card::class, 'add'],
+ ],
+ ];
+
+ /**
+ * Router constructor.
+ */
+ public function __construct()
+ {
+ $request = Request::createFromGlobals();
+ $response = new Response();
+
+ $method = $request->getMethod();
+ $path = $request->getPathInfo();
+
+ // if the route is defined
+ if (isset($this->routes[$method][$path])) {
+ try {
+ // run controller function
+ $content = call_user_func($this->routes[$method][$path], $request);
+
+ // set response to new response
+ if ($content instanceof Response) {
+ $response = $content;
+ }
+
+ // set content directly otherwise
+ else {
+ $response->setContent($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());
+ }
+ }
+
+ // route is not defined
+ else {
+ $response->setStatusCode(Response::HTTP_NOT_FOUND);
+ $response->setContent('Not Found');
+ }
+
+ $response->send();
+ }
+}
+
diff --git a/src/Template.php b/src/Template.php
new file mode 100644
index 0000000..b4360b8
--- /dev/null
+++ b/src/Template.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Elements;
+
+use Twig\Environment;
+use Twig\Loader\FilesystemLoader;
+
+class Template
+{
+ public static ?Environment $twig = null;
+
+ public static function init(): void
+ {
+ $loader = new FilesystemLoader(dirname(__DIR__) . '/templates');
+ self::$twig = new Environment($loader);
+ }
+
+ public static function render(string $name, array $context = []): string
+ {
+ return self::$twig->render($name, $context);
+ }
+}
+