Varous improvements
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
* [PHP](https://www.php.net) comme langage
|
* [PHP](https://www.php.net) comme langage
|
||||||
* [Slim](https://www.slimframework.com) comme framework
|
* [Slim](https://www.slimframework.com) comme framework
|
||||||
* [RedBeanPHP](https://www.redbeanphp.com/index.php) comme ORM
|
* [Medoo](https://medoo.in) comme ORM
|
||||||
* [Twig](https://twig.symfony.com) comme template engine
|
* [Twig](https://twig.symfony.com) comme template engine
|
||||||
|
|
||||||
## HOWTO
|
## HOWTO
|
||||||
@@ -12,12 +12,6 @@ Installer les dépendances :
|
|||||||
$ composer install
|
$ composer install
|
||||||
```
|
```
|
||||||
|
|
||||||
Initialiser la base de données :
|
|
||||||
```
|
|
||||||
$ mkdir database
|
|
||||||
$ php scripts/migrations.php
|
|
||||||
```
|
|
||||||
|
|
||||||
Lancer le serveur de développement :
|
Lancer le serveur de développement :
|
||||||
```
|
```
|
||||||
$ php -S localhost:8080 -t public
|
$ php -S localhost:8080 -t public
|
||||||
|
|||||||
@@ -5,16 +5,22 @@ declare(strict_types=1);
|
|||||||
require __DIR__ . '/../vendor/autoload.php';
|
require __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
use Dotenv\Dotenv;
|
use Dotenv\Dotenv;
|
||||||
|
|
||||||
// Charger les variables d'environnement
|
|
||||||
$dotenv = Dotenv::createImmutable(__DIR__ . '/..');
|
|
||||||
$dotenv->load();
|
|
||||||
|
|
||||||
use Slim\Factory\AppFactory;
|
use Slim\Factory\AppFactory;
|
||||||
use Slim\Views\TwigMiddleware;
|
use Slim\Views\TwigMiddleware;
|
||||||
use Slim\Views\Twig;
|
use Slim\Views\Twig;
|
||||||
use Medoo\Medoo;
|
use Medoo\Medoo;
|
||||||
use App\Controllers\PostController;
|
use App\Controllers\PostController;
|
||||||
|
use App\Repositories\PostRepository;
|
||||||
|
use App\Services\HtmlSanitizer;
|
||||||
|
use App\Routes;
|
||||||
|
use App\Config;
|
||||||
|
|
||||||
|
// ============================================
|
||||||
|
// Charger les variables d'environnement
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
$dotenv = Dotenv::createImmutable(__DIR__ . '/..');
|
||||||
|
$dotenv->load();
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// Configuration
|
// Configuration
|
||||||
@@ -23,26 +29,6 @@ use App\Controllers\PostController;
|
|||||||
$env = $_ENV['APP_ENV'] ?? 'production';
|
$env = $_ENV['APP_ENV'] ?? 'production';
|
||||||
$isDev = strtolower($env) === 'development';
|
$isDev = strtolower($env) === 'development';
|
||||||
|
|
||||||
// Dossier de cache Twig (false en dev, chemin en prod)
|
|
||||||
$twigCache = false;
|
|
||||||
if (!$isDev) {
|
|
||||||
$twigCache = __DIR__ . '/../var/cache/twig';
|
|
||||||
if (!is_dir($twigCache)) {
|
|
||||||
@mkdir($twigCache, 0755, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Chemin base de données
|
|
||||||
$dbFile = __DIR__ . '/../database/app.sqlite';
|
|
||||||
$dbDir = dirname($dbFile);
|
|
||||||
if (!is_dir($dbDir)) {
|
|
||||||
@mkdir($dbDir, 0755, true);
|
|
||||||
}
|
|
||||||
if (!file_exists($dbFile)) {
|
|
||||||
@touch($dbFile);
|
|
||||||
@chmod($dbFile, 0664);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// Initialisation des services
|
// Initialisation des services
|
||||||
// ============================================
|
// ============================================
|
||||||
@@ -50,10 +36,11 @@ if (!file_exists($dbFile)) {
|
|||||||
// Twig
|
// Twig
|
||||||
$twig = Twig::create(
|
$twig = Twig::create(
|
||||||
__DIR__ . '/../views',
|
__DIR__ . '/../views',
|
||||||
['cache' => $twigCache]
|
['cache' => Config::getTwigCache($isDev)]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Medoo (SQLite)
|
// Medoo (SQLite)
|
||||||
|
$dbFile = Config::getDatabasePath();
|
||||||
$db = new Medoo([
|
$db = new Medoo([
|
||||||
'type' => 'sqlite',
|
'type' => 'sqlite',
|
||||||
'database' => $dbFile,
|
'database' => $dbFile,
|
||||||
@@ -71,8 +58,11 @@ $db->pdo->exec("
|
|||||||
)
|
)
|
||||||
");
|
");
|
||||||
|
|
||||||
// Sanitizer HTML
|
// HtmlSanitizer
|
||||||
$htmlSanitizer = new \App\Services\HtmlSanitizer();
|
$htmlSanitizer = new HtmlSanitizer();
|
||||||
|
|
||||||
|
// PostRepository
|
||||||
|
$postRepository = new PostRepository($db);
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// Slim App
|
// Slim App
|
||||||
@@ -86,19 +76,17 @@ $app->add(TwigMiddleware::create($app, $twig));
|
|||||||
// Routes
|
// Routes
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
$controller = new PostController($twig, $db, $htmlSanitizer);
|
$controller = new PostController($twig, $postRepository, $htmlSanitizer);
|
||||||
|
Routes::register($app, $controller);
|
||||||
|
|
||||||
$app->get('/', [$controller, 'index']);
|
// ============================================
|
||||||
$app->get('/article/{slug}', [$controller, 'show']);
|
// Error Handling
|
||||||
$app->get('/admin', [$controller, 'admin']);
|
// ============================================
|
||||||
$app->get('/admin/edit/{id}', [$controller, 'form']);
|
|
||||||
$app->post('/admin/create', [$controller, 'create']);
|
$errorMiddleware = $app->addErrorMiddleware($isDev, $isDev, $isDev);
|
||||||
$app->post('/admin/edit/{id}', [$controller, 'update']);
|
|
||||||
$app->post('/admin/delete/{id}', [$controller, 'delete']);
|
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
// Run
|
// Run
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|
||||||
$errorMiddleware = $app->addErrorMiddleware($isDev, $isDev, $isDev);
|
|
||||||
$app->run();
|
$app->run();
|
||||||
|
|||||||
34
src/Config.php
Normal file
34
src/Config.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
final class Config
|
||||||
|
{
|
||||||
|
public static function getTwigCache(bool $isDev): string|bool
|
||||||
|
{
|
||||||
|
if ($isDev) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$path = __DIR__ . '/../var/cache/twig';
|
||||||
|
if (!is_dir($path)) {
|
||||||
|
@mkdir($path, 0755, true);
|
||||||
|
}
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getDatabasePath(): string
|
||||||
|
{
|
||||||
|
$path = __DIR__ . '/../database/app.sqlite';
|
||||||
|
$dir = dirname($path);
|
||||||
|
if (!is_dir($dir)) {
|
||||||
|
@mkdir($dir, 0755, true);
|
||||||
|
}
|
||||||
|
if (!file_exists($path)) {
|
||||||
|
@touch($path);
|
||||||
|
@chmod($path, 0664);
|
||||||
|
}
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,8 +7,9 @@ namespace App\Controllers;
|
|||||||
use Psr\Http\Message\ResponseInterface as Response;
|
use Psr\Http\Message\ResponseInterface as Response;
|
||||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||||
use Slim\Views\Twig;
|
use Slim\Views\Twig;
|
||||||
use Medoo\Medoo;
|
use App\Repositories\PostRepository;
|
||||||
use App\Models\Post;
|
use App\Models\Post;
|
||||||
|
use App\Services\HtmlSanitizer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contrôleur pour les posts.
|
* Contrôleur pour les posts.
|
||||||
@@ -17,8 +18,8 @@ class PostController
|
|||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private Twig $view,
|
private Twig $view,
|
||||||
private Medoo $db,
|
private PostRepository $postRepository,
|
||||||
private \App\Services\HtmlSanitizer $sanitizer
|
private HtmlSanitizer $sanitizer
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,9 +28,7 @@ class PostController
|
|||||||
*/
|
*/
|
||||||
public function index(Request $req, Response $res): Response
|
public function index(Request $req, Response $res): Response
|
||||||
{
|
{
|
||||||
$rows = $this->db->select('post', '*', ['ORDER' => ['id' => 'DESC']]);
|
$posts = $this->postRepository->findAll();
|
||||||
$posts = array_map(fn ($row) => Post::fromArray($row), $rows ?: []);
|
|
||||||
|
|
||||||
return $this->view->render($res, 'pages/home.twig', ['posts' => $posts]);
|
return $this->view->render($res, 'pages/home.twig', ['posts' => $posts]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,16 +38,15 @@ class PostController
|
|||||||
public function show(Request $req, Response $res, array $args): Response
|
public function show(Request $req, Response $res, array $args): Response
|
||||||
{
|
{
|
||||||
$slug = (string)($args['slug'] ?? '');
|
$slug = (string)($args['slug'] ?? '');
|
||||||
$row = $this->db->get('post', '*', ['slug' => $slug]);
|
$post = $this->postRepository->findBySlug($slug);
|
||||||
|
|
||||||
if (!$row) {
|
if (!$post) {
|
||||||
$res->getBody()->write('Article non trouvé');
|
$res->getBody()->write('Article non trouvé');
|
||||||
return $res->withStatus(404);
|
return $res->withStatus(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
$post = Post::fromArray($row);
|
$sanitizedContent = $this->sanitizer->sanitize($post->getContent());
|
||||||
// Nettoyer le contenu avant de l'envoyer au template
|
$post = $post->withSanitizedContent($sanitizedContent);
|
||||||
$post = $post->withSanitizedContent($this->sanitizer->sanitize($post->getContent()));
|
|
||||||
|
|
||||||
return $this->view->render($res, 'pages/post_detail.twig', ['post' => $post]);
|
return $this->view->render($res, 'pages/post_detail.twig', ['post' => $post]);
|
||||||
}
|
}
|
||||||
@@ -58,9 +56,7 @@ class PostController
|
|||||||
*/
|
*/
|
||||||
public function admin(Request $req, Response $res): Response
|
public function admin(Request $req, Response $res): Response
|
||||||
{
|
{
|
||||||
$rows = $this->db->select('post', '*', ['ORDER' => ['id' => 'DESC']]);
|
$posts = $this->postRepository->findAll();
|
||||||
$posts = array_map(fn ($row) => Post::fromArray($row), $rows ?: []);
|
|
||||||
|
|
||||||
return $this->view->render($res, 'pages/admin.twig', ['posts' => $posts]);
|
return $this->view->render($res, 'pages/admin.twig', ['posts' => $posts]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,12 +69,11 @@ class PostController
|
|||||||
$post = null;
|
$post = null;
|
||||||
|
|
||||||
if ($id > 0) {
|
if ($id > 0) {
|
||||||
$row = $this->db->get('post', '*', ['id' => $id]);
|
$post = $this->postRepository->findById($id);
|
||||||
if (!$row) {
|
if (!$post) {
|
||||||
$res->getBody()->write('Article non trouvé');
|
$res->getBody()->write('Article non trouvé');
|
||||||
return $res->withStatus(404);
|
return $res->withStatus(404);
|
||||||
}
|
}
|
||||||
$post = Post::fromArray($row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$action = $id ? "/admin/edit/{$id}" : "/admin/create";
|
$action = $id ? "/admin/edit/{$id}" : "/admin/create";
|
||||||
@@ -97,41 +92,19 @@ class PostController
|
|||||||
$title = trim((string)($data['title'] ?? ''));
|
$title = trim((string)($data['title'] ?? ''));
|
||||||
$content = trim((string)($data['content'] ?? ''));
|
$content = trim((string)($data['content'] ?? ''));
|
||||||
|
|
||||||
$post = new Post(0, $title, $content);
|
try {
|
||||||
$slug = $post->getSlug();
|
$post = new Post(0, $title, $content);
|
||||||
|
} catch (\InvalidArgumentException) {
|
||||||
// Gérer les collisions
|
// Validation échouée, retour à l'admin
|
||||||
$slug = $this->ensureUniqueSlug($slug);
|
return $res->withHeader('Location', '/admin')->withStatus(302);
|
||||||
|
|
||||||
$this->db->insert('post', [
|
|
||||||
'title' => $post->getTitle(),
|
|
||||||
'content' => $post->getContent(),
|
|
||||||
'slug' => $slug,
|
|
||||||
'created_at' => date('Y-m-d H:i:s'),
|
|
||||||
'updated_at' => date('Y-m-d H:i:s'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $res->withHeader('Location', '/admin')->withStatus(302);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function ensureUniqueSlug(string $slug, ?int $excludeId = null): string
|
|
||||||
{
|
|
||||||
$original = $slug;
|
|
||||||
$counter = 1;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
$existing = $this->db->get('post', 'id', ['slug' => $slug]);
|
|
||||||
|
|
||||||
// Si pas de collision, ou si c'est le même post, le slug est unique
|
|
||||||
if (!$existing || ($excludeId && $existing === $excludeId)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
$slug = $original . '-' . $counter;
|
|
||||||
$counter++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $slug;
|
$slug = $post->getSlug();
|
||||||
|
$slug = $this->ensureUniqueSlug($slug);
|
||||||
|
|
||||||
|
$this->postRepository->create($post, $slug);
|
||||||
|
|
||||||
|
return $res->withHeader('Location', '/admin')->withStatus(302);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,7 +113,7 @@ class PostController
|
|||||||
public function update(Request $req, Response $res, array $args): Response
|
public function update(Request $req, Response $res, array $args): Response
|
||||||
{
|
{
|
||||||
$id = (int)$args['id'];
|
$id = (int)$args['id'];
|
||||||
$existing = $this->db->get('post', 'id', ['id' => $id]);
|
$existing = $this->postRepository->findById($id);
|
||||||
|
|
||||||
if (!$existing) {
|
if (!$existing) {
|
||||||
$res->getBody()->write('Article non trouvé');
|
$res->getBody()->write('Article non trouvé');
|
||||||
@@ -151,7 +124,6 @@ class PostController
|
|||||||
$title = trim((string)($data['title'] ?? ''));
|
$title = trim((string)($data['title'] ?? ''));
|
||||||
$content = trim((string)($data['content'] ?? ''));
|
$content = trim((string)($data['content'] ?? ''));
|
||||||
|
|
||||||
// Créer un objet Post pour valider
|
|
||||||
try {
|
try {
|
||||||
$post = new Post($id, $title, $content);
|
$post = new Post($id, $title, $content);
|
||||||
} catch (\InvalidArgumentException) {
|
} catch (\InvalidArgumentException) {
|
||||||
@@ -159,17 +131,10 @@ class PostController
|
|||||||
return $res->withHeader('Location', '/admin')->withStatus(302);
|
return $res->withHeader('Location', '/admin')->withStatus(302);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculer le nouveau slug
|
|
||||||
$newSlug = $post->getSlug();
|
$newSlug = $post->getSlug();
|
||||||
$newSlug = $this->ensureUniqueSlug($newSlug, $id); // Passer l'ID pour exclure le post actuel
|
$newSlug = $this->ensureUniqueSlug($newSlug, $id);
|
||||||
|
|
||||||
// Persister en DB
|
$this->postRepository->update($id, $post, $newSlug);
|
||||||
$this->db->update('post', [
|
|
||||||
'title' => $post->getTitle(),
|
|
||||||
'content' => $post->getContent(),
|
|
||||||
'slug' => $newSlug,
|
|
||||||
'updated_at' => date('Y-m-d H:i:s'),
|
|
||||||
], ['id' => $id]);
|
|
||||||
|
|
||||||
return $res->withHeader('Location', '/admin')->withStatus(302);
|
return $res->withHeader('Location', '/admin')->withStatus(302);
|
||||||
}
|
}
|
||||||
@@ -180,14 +145,34 @@ class PostController
|
|||||||
public function delete(Request $req, Response $res, array $args): Response
|
public function delete(Request $req, Response $res, array $args): Response
|
||||||
{
|
{
|
||||||
$id = (int)$args['id'];
|
$id = (int)$args['id'];
|
||||||
$existing = $this->db->get('post', 'id', ['id' => $id]);
|
$existing = $this->postRepository->findById($id);
|
||||||
|
|
||||||
if (!$existing) {
|
if (!$existing) {
|
||||||
$res->getBody()->write('Article non trouvé');
|
$res->getBody()->write('Article non trouvé');
|
||||||
return $res->withStatus(404);
|
return $res->withStatus(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->db->delete('post', ['id' => $id]);
|
$this->postRepository->delete($id);
|
||||||
return $res->withHeader('Location', '/admin')->withStatus(302);
|
return $res->withHeader('Location', '/admin')->withStatus(302);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assure l'unicité d'un slug en ajoutant un suffixe numérique si nécessaire.
|
||||||
|
*
|
||||||
|
* @param string $slug Le slug de base
|
||||||
|
* @param int|null $excludeId L'ID du post à exclure de la vérification (pour les mises à jour)
|
||||||
|
* @return string Le slug unique
|
||||||
|
*/
|
||||||
|
private function ensureUniqueSlug(string $slug, ?int $excludeId = null): string
|
||||||
|
{
|
||||||
|
$original = $slug;
|
||||||
|
$counter = 1;
|
||||||
|
|
||||||
|
while ($this->postRepository->slugExists($slug, $excludeId)) {
|
||||||
|
$slug = $original . '-' . $counter;
|
||||||
|
$counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $slug;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
66
src/Repositories/PostRepository.php
Normal file
66
src/Repositories/PostRepository.php
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Repositories;
|
||||||
|
|
||||||
|
use Medoo\Medoo;
|
||||||
|
use App\Models\Post;
|
||||||
|
|
||||||
|
final class PostRepository
|
||||||
|
{
|
||||||
|
public function __construct(private Medoo $db)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findAll(): array
|
||||||
|
{
|
||||||
|
$rows = $this->db->select('post', '*', ['ORDER' => ['id' => 'DESC']]);
|
||||||
|
return array_map(fn ($row) => Post::fromArray($row), $rows ?: []);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findBySlug(string $slug): ?Post
|
||||||
|
{
|
||||||
|
$row = $this->db->get('post', '*', ['slug' => $slug]);
|
||||||
|
return $row ? Post::fromArray($row) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function findById(int $id): ?Post
|
||||||
|
{
|
||||||
|
$row = $this->db->get('post', '*', ['id' => $id]);
|
||||||
|
return $row ? Post::fromArray($row) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create(Post $post, string $slug): int
|
||||||
|
{
|
||||||
|
$this->db->insert('post', [
|
||||||
|
'title' => $post->getTitle(),
|
||||||
|
'content' => $post->getContent(),
|
||||||
|
'slug' => $slug,
|
||||||
|
'created_at' => date('Y-m-d H:i:s'),
|
||||||
|
'updated_at' => date('Y-m-d H:i:s'),
|
||||||
|
]);
|
||||||
|
return (int) $this->db->id();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(int $id, Post $post, string $slug): void
|
||||||
|
{
|
||||||
|
$this->db->update('post', [
|
||||||
|
'title' => $post->getTitle(),
|
||||||
|
'content' => $post->getContent(),
|
||||||
|
'slug' => $slug,
|
||||||
|
'updated_at' => date('Y-m-d H:i:s'),
|
||||||
|
], ['id' => $id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(int $id): void
|
||||||
|
{
|
||||||
|
$this->db->delete('post', ['id' => $id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function slugExists(string $slug, ?int $excludeId = null): bool
|
||||||
|
{
|
||||||
|
$existing = $this->db->get('post', 'id', ['slug' => $slug]);
|
||||||
|
return $existing && (!$excludeId || $existing !== $excludeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/Routes.php
Normal file
22
src/Routes.php
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use Slim\App;
|
||||||
|
use App\Controllers\PostController;
|
||||||
|
|
||||||
|
final class Routes
|
||||||
|
{
|
||||||
|
public static function register(App $app, PostController $controller): void
|
||||||
|
{
|
||||||
|
$app->get('/', [$controller, 'index']);
|
||||||
|
$app->get('/article/{slug}', [$controller, 'show']);
|
||||||
|
$app->get('/admin', [$controller, 'admin']);
|
||||||
|
$app->get('/admin/edit/{id}', [$controller, 'form']);
|
||||||
|
$app->post('/admin/create', [$controller, 'create']);
|
||||||
|
$app->post('/admin/edit/{id}', [$controller, 'update']);
|
||||||
|
$app->post('/admin/delete/{id}', [$controller, 'delete']);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,12 @@ final class HtmlSanitizer
|
|||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
// Créer le répertoire de cache s'il n'existe pas
|
||||||
|
$cacheDir = __DIR__ . '/../../var/cache/htmlpurifier';
|
||||||
|
if (!is_dir($cacheDir)) {
|
||||||
|
@mkdir($cacheDir, 0755, true);
|
||||||
|
}
|
||||||
|
|
||||||
$config = HTMLPurifier_Config::createDefault();
|
$config = HTMLPurifier_Config::createDefault();
|
||||||
// Autoriser les balises courantes de formatage
|
// Autoriser les balises courantes de formatage
|
||||||
$config->set('HTML.Allowed', 'p,br,strong,em,u,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,a[href],img[src|alt|width|height]');
|
$config->set('HTML.Allowed', 'p,br,strong,em,u,h1,h2,h3,h4,h5,h6,ul,ol,li,blockquote,a[href],img[src|alt|width|height]');
|
||||||
@@ -20,7 +26,7 @@ final class HtmlSanitizer
|
|||||||
$config->set('HTML.AllowedAttributes', 'href,src,alt,width,height,title');
|
$config->set('HTML.AllowedAttributes', 'href,src,alt,width,height,title');
|
||||||
// Activer le cache
|
// Activer le cache
|
||||||
$config->set('Cache.DefinitionImpl', 'Serializer');
|
$config->set('Cache.DefinitionImpl', 'Serializer');
|
||||||
$config->set('Cache.SerializerPath', __DIR__ . '/../../var/cache/htmlpurifier');
|
$config->set('Cache.SerializerPath', $cacheDir);
|
||||||
|
|
||||||
$this->purifier = new HTMLPurifier($config);
|
$this->purifier = new HTMLPurifier($config);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user