diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/AppException.php | 7 | ||||
-rw-r--r-- | src/Controller/Card.php | 31 | ||||
-rw-r--r-- | src/Controller/Home.php | 22 | ||||
-rw-r--r-- | src/DB.php | 55 | ||||
-rw-r--r-- | src/Model/Card.php | 87 | ||||
-rw-r--r-- | src/Model/CardMeta.php | 57 | ||||
-rw-r--r-- | src/Router.php | 70 | ||||
-rw-r--r-- | src/Template.php | 23 |
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); + } +} + |