From 22127b8702b679a1b516afae0c2c5f04975576c7 Mon Sep 17 00:00:00 2001 From: clfreville2 Date: Tue, 15 Nov 2022 09:23:20 +0100 Subject: [PATCH] Initial commit --- convert_mysql.sh | 3 + index.php | 1 + public/index.php | 11 ++ src/Silex/Config/Config.php | 8 ++ src/Silex/Config/SplClassLoader.php | 155 ++++++++++++++++++++++++ src/Silex/Controller/UserController.php | 17 +++ src/Silex/DI/DI.php | 30 +++++ src/Silex/Gateway/NewsGateway.php | 37 ++++++ src/Silex/Http/HttpResponse.php | 30 +++++ src/Silex/Model/News.php | 36 ++++++ tables.sql | 28 +++++ views/home.php | 3 + views/layout.php | 10 ++ 13 files changed, 369 insertions(+) create mode 100755 convert_mysql.sh create mode 120000 index.php create mode 100644 public/index.php create mode 100644 src/Silex/Config/Config.php create mode 100644 src/Silex/Config/SplClassLoader.php create mode 100644 src/Silex/Controller/UserController.php create mode 100644 src/Silex/DI/DI.php create mode 100644 src/Silex/Gateway/NewsGateway.php create mode 100644 src/Silex/Http/HttpResponse.php create mode 100644 src/Silex/Model/News.php create mode 100644 tables.sql create mode 100644 views/home.php create mode 100644 views/layout.php diff --git a/convert_mysql.sh b/convert_mysql.sh new file mode 100755 index 0000000..90c89c5 --- /dev/null +++ b/convert_mysql.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +sed 's/SERIAL PRIMARY KEY/INT PRIMARY KEY AUTO_INCREMENT/g' tables.sql diff --git a/index.php b/index.php new file mode 120000 index 0000000..00c7f4c --- /dev/null +++ b/index.php @@ -0,0 +1 @@ +public/index.php \ No newline at end of file diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..7d9625e --- /dev/null +++ b/public/index.php @@ -0,0 +1,11 @@ +register(); + +// TODO router +$controller = new \Silex\Controller\UserController(); +$controller->index(new \Silex\DI\DI())->render(__DIR__ . '/../' . VIEW_PATH); diff --git a/src/Silex/Config/Config.php b/src/Silex/Config/Config.php new file mode 100644 index 0000000..e4c4972 --- /dev/null +++ b/src/Silex/Config/Config.php @@ -0,0 +1,8 @@ +. + */ + +/** + * SplClassLoader implementation that implements the technical interoperability + * standards for PHP 5.3 namespaces and class names. + * + * http://groups.google.com/group/php-standards/web/psr-0-final-proposal?pli=1 + * + * // Example which loads classes for the Doctrine Common package in the + * // Doctrine\Common namespace. + * $classLoader = new SplClassLoader('Doctrine\Common', '/path/to/doctrine'); + * $classLoader->register(); + * + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @author Jonathan H. Wage + * @author Roman S. Borschel + * @author Matthew Weier O'Phinney + * @author Kris Wallsmith + * @author Fabien Potencier + */ +class SplClassLoader +{ + private $_fileExtension = '.php'; + private $_namespace; + private $_includePath; + private $_namespaceSeparator = '\\'; + + /** + * Creates a new SplClassLoader that loads classes of the + * specified namespace. + * + * @param string $ns The namespace to use. + */ + public function __construct(string $ns = null, string $includePath = null) + { + $this->_namespace = $ns; + $this->_includePath = $includePath; + } + + /** + * Sets the namespace separator used by classes in the namespace of this class loader. + * + * @param string $sep The separator to use. + */ + public function setNamespaceSeparator(string $sep) + { + $this->_namespaceSeparator = $sep; + } + + /** + * Gets the namespace seperator used by classes in the namespace of this class loader. + * + * @return void + */ + public function getNamespaceSeparator() + { + return $this->_namespaceSeparator; + } + + /** + * Sets the base include path for all class files in the namespace of this class loader. + * + * @param string $includePath + */ + public function setIncludePath(string $includePath) + { + $this->_includePath = $includePath; + } + + /** + * Gets the base include path for all class files in the namespace of this class loader. + * + * @return string $includePath + */ + public function getIncludePath() + { + return $this->_includePath; + } + + /** + * Sets the file extension of class files in the namespace of this class loader. + * + * @param string $fileExtension + */ + public function setFileExtension($fileExtension) + { + $this->_fileExtension = $fileExtension; + } + + /** + * Gets the file extension of class files in the namespace of this class loader. + * + * @return string $fileExtension + */ + public function getFileExtension() + { + return $this->_fileExtension; + } + + /** + * Installs this class loader on the SPL autoload stack. + */ + public function register() + { + spl_autoload_register(array($this, 'loadClass')); + } + + /** + * Uninstalls this class loader from the SPL autoloader stack. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $className The name of the class to load. + * @return void + */ + public function loadClass(string $className) + { + if (null === $this->_namespace || $this->_namespace . $this->_namespaceSeparator === substr($className, 0, strlen($this->_namespace . $this->_namespaceSeparator))) { + $fileName = ''; + $namespace = ''; + if (false !== ($lastNsPos = strripos($className, $this->_namespaceSeparator))) { + $namespace = substr($className, 0, $lastNsPos); + $className = substr($className, $lastNsPos + 1); + $fileName = str_replace($this->_namespaceSeparator, DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; + } + $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . $this->_fileExtension; + + require ($this->_includePath !== null ? $this->_includePath . DIRECTORY_SEPARATOR : '') . $fileName; + } + } +} diff --git a/src/Silex/Controller/UserController.php b/src/Silex/Controller/UserController.php new file mode 100644 index 0000000..767a666 --- /dev/null +++ b/src/Silex/Controller/UserController.php @@ -0,0 +1,17 @@ +getNewsGateway()->getPaginatedRecentNews(); + return new HttpResponse(200, 'home', ['news' => $news]); + } +} diff --git a/src/Silex/DI/DI.php b/src/Silex/DI/DI.php new file mode 100644 index 0000000..fde5367 --- /dev/null +++ b/src/Silex/DI/DI.php @@ -0,0 +1,30 @@ +newsGateway === null) { + $this->newsGateway = new NewsGateway($this->getPDO()); + } + return $this->newsGateway; + } + + private function getPDO(): PDO + { + if ($this->pdo === null) { + return new PDO(sprintf('mysql:host=%s;dbname=%s', DB_HOST, DB_DATABASE), DB_USER, DB_PASSWORD); + } + return $this->pdo; + } +} diff --git a/src/Silex/Gateway/NewsGateway.php b/src/Silex/Gateway/NewsGateway.php new file mode 100644 index 0000000..d2ee725 --- /dev/null +++ b/src/Silex/Gateway/NewsGateway.php @@ -0,0 +1,37 @@ +pdo = $pdo; + } + + /** + * @return News[] + */ + public function getPaginatedRecentNews(int $page = 1, int $limit = 10): array + { + $req = $this->pdo->prepare('SELECT * FROM news ORDER BY publication_date DESC LIMIT :limit OFFSET :offset;'); + $req->bindValue('limit', $limit, PDO::PARAM_INT); + $req->bindValue('offset', ($page - 1) * $limit, PDO::PARAM_INT); + if (!$req->execute()) { + return []; + } + $news = []; + while ($data = $req->fetch()) { + $news[] = new News($data['title'], $data['content'], DateTime::createFromFormat('Y-m-d H:i:s', $data['publication_date'])); + } + return $news; + } +} diff --git a/src/Silex/Http/HttpResponse.php b/src/Silex/Http/HttpResponse.php new file mode 100644 index 0000000..7511c01 --- /dev/null +++ b/src/Silex/Http/HttpResponse.php @@ -0,0 +1,30 @@ +status = $status; + $this->viewPath = $viewPath; + $this->viewParams = $viewParams; + } + + public function render(string $viewBasePath) + { + $params = $this->viewParams; + ob_start(); + require $viewBasePath . '/' . $this->viewPath . '.php'; + $content = ob_get_clean(); + require $viewBasePath . '/layout.php'; + } +} diff --git a/src/Silex/Model/News.php b/src/Silex/Model/News.php new file mode 100644 index 0000000..72c8329 --- /dev/null +++ b/src/Silex/Model/News.php @@ -0,0 +1,36 @@ +title = $title; + $this->content = $content; + $this->publicationDate = $publicationDate; + } + + public function getTitle(): string + { + return $this->title; + } + + public function getContent(): string + { + return $this->content; + } + + public function getPublicationDate(): DateTime + { + return $this->publicationDate; + } +} diff --git a/tables.sql b/tables.sql new file mode 100644 index 0000000..6f03838 --- /dev/null +++ b/tables.sql @@ -0,0 +1,28 @@ +CREATE TABLE registered_user ( + id_user SERIAL PRIMARY KEY, + login VARCHAR(32) NOT NULL, + password CHAR(72) NOT NULL, -- BCrypt + role INT NOT NULL DEFAULT 0 +); + +CREATE TABLE news ( + id_news SERIAL PRIMARY KEY, + publication_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + title VARCHAR(60) NOT NULL, + slug VARCHAR(60) NOT NULL, + content TEXT NOT NULL, + author_id INT NOT NULL, + FOREIGN KEY (author_id) REFERENCES registered_user(id_user) + ON DELETE CASCADE +); +CREATE TABLE comment ( + id_comment SERIAL PRIMARY KEY, + news_id INT NOT NULL, + publication_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, + content TEXT NOT NULL, + author_id INT NOT NULL, + FOREIGN KEY (news_id) REFERENCES news(id_news) + ON DELETE CASCADE, + FOREIGN KEY (author_id) REFERENCES registered_user(id_user) + ON DELETE CASCADE +); \ No newline at end of file diff --git a/views/home.php b/views/home.php new file mode 100644 index 0000000..7d19228 --- /dev/null +++ b/views/home.php @@ -0,0 +1,3 @@ + +

Hello world!

+ \ No newline at end of file diff --git a/views/layout.php b/views/layout.php new file mode 100644 index 0000000..02b8bdb --- /dev/null +++ b/views/layout.php @@ -0,0 +1,10 @@ + + + + + <?= $viewsArgs['title'] ?? 'Is it a blog?' ?> + + + + + \ No newline at end of file