update readme
This commit is contained in:
parent
b12cf019e7
commit
ab3227b75f
88 changed files with 7546 additions and 176 deletions
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Lubian\NoFramework\Action;
|
||||
|
||||
use Lubian\NoFramework\Model\MarkdownPage;
|
||||
use Lubian\NoFramework\Repository\MarkdownPageFilesystem;
|
||||
use Lubian\NoFramework\Repository\MarkdownPageRepo;
|
||||
use Lubian\NoFramework\Template\Renderer;
|
||||
use Parsedown;
|
||||
|
@ -12,19 +14,33 @@ use function str_replace;
|
|||
|
||||
class Page
|
||||
{
|
||||
public function __invoke(
|
||||
public function __construct(
|
||||
private ResponseInterface $response,
|
||||
private MarkdownPageRepo $repo,
|
||||
private Parsedown $parsedown,
|
||||
private Renderer $renderer,
|
||||
){}
|
||||
public function show(
|
||||
string $page,
|
||||
ResponseInterface $response,
|
||||
MarkdownPageRepo $repo,
|
||||
Parsedown $parsedown,
|
||||
Renderer $renderer,
|
||||
): ResponseInterface {
|
||||
$page = $repo->byTitle($page);
|
||||
$page = $this->repo->byTitle($page);
|
||||
$content = $this->linkFilter($page->content);
|
||||
$content = $parsedown->parse($content);
|
||||
$html = $renderer->render('page', ['content' => $content]);
|
||||
$response->getBody()->write($html);
|
||||
return $response;
|
||||
$content = $this->parsedown->parse($content);
|
||||
$html = $this->renderer->render('page', ['content' => $content, 'title' => $page->title]);
|
||||
$this->response->getBody()->write($html);
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
public function list(): ResponseInterface
|
||||
{
|
||||
$pages = array_map(
|
||||
fn (MarkdownPage $p) => ['title' => $p->title, 'id' => $p->id],
|
||||
$this->repo->all()
|
||||
);
|
||||
$html = $this->renderer->render('pagelist', ['pages' => $pages]);
|
||||
$this->response->getBody()->write($html);
|
||||
return $this->response;
|
||||
|
||||
}
|
||||
|
||||
private function linkFilter(string $content): string
|
||||
|
|
32
app/src/Factory/DoctrineEm.php
Normal file
32
app/src/Factory/DoctrineEm.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Lubian\NoFramework\Factory;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
|
||||
use Doctrine\ORM\Tools\Setup;
|
||||
use Lubian\NoFramework\Settings;
|
||||
|
||||
final class DoctrineEm
|
||||
{
|
||||
public function __construct(private Settings $settings){}
|
||||
public function create(): EntityManagerInterface
|
||||
{
|
||||
$config = Setup::createConfiguration($this->settings->doctrine['devMode']);
|
||||
|
||||
$config->setMetadataDriverImpl(
|
||||
new AttributeDriver(
|
||||
$this->settings->doctrine['metadataDirs']
|
||||
)
|
||||
);
|
||||
|
||||
return EntityManager::create(
|
||||
$this->settings->connection,
|
||||
$config,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -18,8 +18,9 @@ final class SettingsContainerProvider implements ContainerProvider
|
|||
$builder = new ContainerBuilder;
|
||||
$settings = $this->settingsProvider->getSettings();
|
||||
$dependencies = require $settings->dependenciesFile;
|
||||
$dependencies[Settings::class] = fn (): Settings => $settings;
|
||||
$dependencies[Settings::class] = $settings;
|
||||
$builder->addDefinitions($dependencies);
|
||||
// $builder->enableCompilation('/tmp');
|
||||
return $builder->build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Lubian\NoFramework\Middleware;
|
||||
|
||||
use Laminas\Diactoros\Response;
|
||||
use Lubian\NoFramework\Settings;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
|
@ -10,23 +11,30 @@ use Psr\Http\Server\RequestHandlerInterface;
|
|||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
use function base64_encode;
|
||||
|
||||
final class CacheMiddleware implements MiddlewareInterface
|
||||
{
|
||||
public function __construct(private CacheInterface $cache){}
|
||||
public function __construct(
|
||||
private CacheInterface $cache,
|
||||
private Response\Serializer $serializer,
|
||||
private Settings $settings,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
if ($request->getMethod() === 'GET') {
|
||||
if ($request->getMethod() === 'GET' && !$this->settings->isDev()) {
|
||||
$key = (string) $request->getUri();
|
||||
$key = base64_encode($key);
|
||||
$callback = fn () => $handler->handle($request);
|
||||
$response = new Response();
|
||||
$body = $this->cache->get($key, function (ItemInterface $item) use ($callback) {
|
||||
$cached = $this->cache->get($key, function (ItemInterface $item) use ($callback) {
|
||||
$item->expiresAfter(120);
|
||||
return (string) $callback()->getBody();
|
||||
$response = $callback();
|
||||
return $this->serializer::toString($response);
|
||||
});
|
||||
$response->getBody()->write($body);
|
||||
return $response;
|
||||
return $this->serializer::fromString($cached);
|
||||
}
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
|
|
@ -2,12 +2,22 @@
|
|||
|
||||
namespace Lubian\NoFramework\Model;
|
||||
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping\Column;
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
use Doctrine\ORM\Mapping\GeneratedValue;
|
||||
use Doctrine\ORM\Mapping\Id;
|
||||
|
||||
#[Entity]
|
||||
class MarkdownPage
|
||||
{
|
||||
public function __construct(
|
||||
public readonly int $id,
|
||||
public readonly string $title,
|
||||
public readonly string $content,
|
||||
#[Id, Column, GeneratedValue]
|
||||
public int|null $id = null,
|
||||
#[Column]
|
||||
public string $title,
|
||||
#[Column(type: Types::TEXT)]
|
||||
public string $content,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,16 @@
|
|||
namespace Lubian\NoFramework\Repository;
|
||||
|
||||
use Lubian\NoFramework\Model\MarkdownPage;
|
||||
use Lubian\NoFramework\Settings;
|
||||
use Symfony\Contracts\Cache\CacheInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
|
||||
class CachedMarkdownPageRepo implements MarkdownPageRepo
|
||||
{
|
||||
public function __construct(
|
||||
private CacheInterface $cache,
|
||||
private MarkdownPageRepo $repo,
|
||||
private readonly CacheInterface $cache,
|
||||
private readonly MarkdownPageRepo $repo,
|
||||
private readonly Settings $settings,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -20,6 +22,9 @@ class CachedMarkdownPageRepo implements MarkdownPageRepo
|
|||
public function all(): array
|
||||
{
|
||||
$callback = fn () => $this->repo->all();
|
||||
if ($this->settings->isDev()) {
|
||||
return $callback();
|
||||
}
|
||||
return $this->cache->get('ALLPAGES', function (ItemInterface $item) use ($callback) {
|
||||
$item->expiresAfter(30);
|
||||
return $callback();
|
||||
|
@ -29,6 +34,9 @@ class CachedMarkdownPageRepo implements MarkdownPageRepo
|
|||
public function byId(int $id): MarkdownPage
|
||||
{
|
||||
$callback = fn () => $this->repo->byId($id);
|
||||
if ($this->settings->isDev()) {
|
||||
return $callback();
|
||||
}
|
||||
return $this->cache->get('PAGE' . $id, function (ItemInterface $item) use ($callback) {
|
||||
$item->expiresAfter(30);
|
||||
return $callback();
|
||||
|
@ -38,9 +46,17 @@ class CachedMarkdownPageRepo implements MarkdownPageRepo
|
|||
public function byTitle(string $title): MarkdownPage
|
||||
{
|
||||
$callback = fn () => $this->repo->byTitle($title);
|
||||
if ($this->settings->isDev()) {
|
||||
return $callback();
|
||||
}
|
||||
return $this->cache->get('PAGE' . $title, function (ItemInterface $item) use ($callback) {
|
||||
$item->expiresAfter(30);
|
||||
return $callback();
|
||||
});
|
||||
}
|
||||
|
||||
public function save(MarkdownPage $page): MarkdownPage
|
||||
{
|
||||
return $this->repo->save($page);
|
||||
}
|
||||
}
|
||||
|
|
60
app/src/Repository/DoctrineMarkdownPageRepo.php
Normal file
60
app/src/Repository/DoctrineMarkdownPageRepo.php
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace Lubian\NoFramework\Repository;
|
||||
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Lubian\NoFramework\Exception\NotFound;
|
||||
use Lubian\NoFramework\Model\MarkdownPage;
|
||||
|
||||
final class DoctrineMarkdownPageRepo implements MarkdownPageRepo
|
||||
{
|
||||
/**
|
||||
* @var EntityRepository<MarkdownPage>
|
||||
*/
|
||||
private EntityRepository $repo;
|
||||
public function __construct(
|
||||
private EntityManagerInterface $entityManager
|
||||
){
|
||||
$this->repo = $this->entityManager->getRepository(MarkdownPage::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function all(): array
|
||||
{
|
||||
usleep(rand(500, 1500) * 1000);
|
||||
return $this->repo->findAll();
|
||||
}
|
||||
|
||||
public function byId(int $id): MarkdownPage
|
||||
{
|
||||
usleep(rand(500, 1500) * 1000);
|
||||
$page = $this->repo->findOneBy(['id' => $id]);
|
||||
if (!$page instanceof MarkdownPage){
|
||||
throw new NotFound;
|
||||
}
|
||||
return $page;
|
||||
}
|
||||
|
||||
public function byTitle(string $title): MarkdownPage
|
||||
{
|
||||
usleep(rand(500, 1500) * 1000);
|
||||
$page = $this->repo->findOneBy(['title' => $title]);
|
||||
if (!$page instanceof MarkdownPage){
|
||||
throw new NotFound;
|
||||
}
|
||||
return $page;
|
||||
}
|
||||
|
||||
public function save(MarkdownPage $page): MarkdownPage
|
||||
{
|
||||
$this->entityManager->persist($page);
|
||||
$this->entityManager->flush();
|
||||
return $page;
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ final class MarkdownPageFilesystem implements MarkdownPageRepo
|
|||
$fileNames = glob($this->dataPath . '*.md');
|
||||
assert(is_array($fileNames));
|
||||
return array_map(function (string $name): MarkdownPage {
|
||||
usleep(100000);
|
||||
usleep(rand(200, 500) * 1000);
|
||||
$content = file_get_contents($name);
|
||||
$name = str_replace($this->dataPath, '', $name);
|
||||
$name = str_replace('.md', '', $name);
|
||||
|
@ -60,4 +60,9 @@ final class MarkdownPageFilesystem implements MarkdownPageRepo
|
|||
}
|
||||
return $filtered[0];
|
||||
}
|
||||
|
||||
public function save(MarkdownPage $page): MarkdownPage
|
||||
{
|
||||
return $page;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,4 +14,6 @@ interface MarkdownPageRepo
|
|||
public function byId(int $id): MarkdownPage;
|
||||
|
||||
public function byTitle(string $title): MarkdownPage;
|
||||
|
||||
public function save(MarkdownPage $page): MarkdownPage;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@ namespace Lubian\NoFramework;
|
|||
|
||||
final class Settings
|
||||
{
|
||||
/**
|
||||
* @param array{driver: string, user: string, password: string, path: string} $connection
|
||||
* @param array{devMode: bool, metadataDirs: string[], cacheDir: string} $doctrine
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly string $environment,
|
||||
public readonly string $dependenciesFile,
|
||||
|
@ -11,6 +15,19 @@ final class Settings
|
|||
public readonly string $templateDir,
|
||||
public readonly string $templateExtension,
|
||||
public readonly string $pagesPath,
|
||||
/**
|
||||
* @var array{driver: string, user: string, password: string, path: string}
|
||||
*/
|
||||
public readonly array $connection,
|
||||
/**
|
||||
* @var array{devMode: bool, metadataDirs: string[], cacheDir: string}
|
||||
*/
|
||||
public readonly array $doctrine,
|
||||
) {
|
||||
}
|
||||
|
||||
public function isDev(): bool
|
||||
{
|
||||
return $this->environment === 'dev';
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue