Initial MVC refactor
This commit is contained in:
parent
7a85c7f9dd
commit
cacbf85283
@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
#require_once __DIR__ . '/../bootstrap.php';
|
|
||||||
|
|
||||||
define('APP_ROOT', dirname(dirname(__FILE__)));
|
define('APP_ROOT', dirname(dirname(__FILE__)));
|
||||||
|
|
||||||
@ -33,10 +32,7 @@ foreach (recursive_glob('*.php', SRC_DIR) as $file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
confirm_setup();
|
confirm_setup();
|
||||||
|
|
||||||
$isLoggedIn = isset($_SESSION['user_id']);
|
|
||||||
$config = Config::load();
|
$config = Config::load();
|
||||||
$user = User::load();
|
|
||||||
|
|
||||||
// Get request data
|
// Get request data
|
||||||
$method = $_SERVER['REQUEST_METHOD'];
|
$method = $_SERVER['REQUEST_METHOD'];
|
||||||
@ -80,21 +76,9 @@ function route($pattern, $callback, $methods = ['GET']) {
|
|||||||
|
|
||||||
// Set content type
|
// Set content type
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
echo "Path: " . $path;
|
|
||||||
|
|
||||||
// routes
|
// routes
|
||||||
route('', function() use ($isLoggedIn, $config, $user) {
|
route('', function(){
|
||||||
$page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
|
$hc = new HomeController();
|
||||||
$limit = $config->itemsPerPage;
|
echo $hc->render();
|
||||||
$offset = ($page - 1) * $limit;
|
|
||||||
$ticks = iterator_to_array(stream_ticks($limit, $offset));
|
|
||||||
|
|
||||||
$vars = [
|
|
||||||
'isLoggedIn' => $isLoggedIn,
|
|
||||||
'config' => $config,
|
|
||||||
'user' => $user,
|
|
||||||
'ticks' => $ticks,
|
|
||||||
];
|
|
||||||
|
|
||||||
echo render_template(TEMPLATES_DIR . "/home.php", $vars);
|
|
||||||
});
|
});
|
||||||
|
77
src/Controller/Home/Home.php
Normal file
77
src/Controller/Home/Home.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
class HomeController{
|
||||||
|
private function stream_ticks(int $limit, int $offset = 0): Generator {
|
||||||
|
$tick_files = glob(TICKS_DIR . '/*/*/*.txt');
|
||||||
|
usort($tick_files, fn($a, $b) => strcmp($b, $a)); // sort filenames in reverse chronological order
|
||||||
|
|
||||||
|
$count = 0;
|
||||||
|
foreach ($tick_files as $file) {
|
||||||
|
// read all the ticks from the current file and reverse the order
|
||||||
|
// so the most recent ones are first
|
||||||
|
//
|
||||||
|
// each file is a single day, so we never hold more than
|
||||||
|
// one day's ticks in memory
|
||||||
|
$lines = array_reverse(
|
||||||
|
file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES)
|
||||||
|
);
|
||||||
|
|
||||||
|
// split the path to the current file into the date components
|
||||||
|
$pathParts = explode('/', str_replace('\\', '/', $file));
|
||||||
|
|
||||||
|
// assign the different components to the appropriate part of the date
|
||||||
|
$year = $pathParts[count($pathParts) - 3];
|
||||||
|
$month = $pathParts[count($pathParts) - 2];
|
||||||
|
$day = pathinfo($pathParts[count($pathParts) - 1], PATHINFO_FILENAME);
|
||||||
|
|
||||||
|
foreach ($lines as $line) {
|
||||||
|
// just keep skipping ticks until we get to the starting point
|
||||||
|
if ($offset > 0) {
|
||||||
|
$offset--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ticks are pipe-delimited: timestamp|text
|
||||||
|
// But just in case a tick contains a pipe, only split on the first one that occurs
|
||||||
|
$tickParts = explode('|', $line, 2);
|
||||||
|
$time = $tickParts[0];
|
||||||
|
$tick = $tickParts[1];
|
||||||
|
|
||||||
|
// Build the timestamp from the date and time
|
||||||
|
// Ticks are always stored in UTC
|
||||||
|
$timestampUTC = "$year-$month-$day $time";
|
||||||
|
yield [
|
||||||
|
'timestamp' => $timestampUTC,
|
||||||
|
'tick' => $tick,
|
||||||
|
];
|
||||||
|
|
||||||
|
if (++$count >= $limit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render(){
|
||||||
|
$page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
|
||||||
|
$isLoggedIn = isset($_SESSION['user_id']);
|
||||||
|
$config = Config::load();
|
||||||
|
$user = User::load();
|
||||||
|
|
||||||
|
$limit = $config->itemsPerPage;
|
||||||
|
$offset = ($page - 1) * $limit;
|
||||||
|
$ticks = iterator_to_array(stream_ticks($limit, $offset));
|
||||||
|
|
||||||
|
$view = new HomeView();
|
||||||
|
$tickList = $view->renderTicksSection($config->siteDescription, $ticks, $page, $limit);
|
||||||
|
|
||||||
|
$vars = [
|
||||||
|
'isLoggedIn' => $isLoggedIn,
|
||||||
|
'config' => $config,
|
||||||
|
'user' => $user,
|
||||||
|
'tickList' => $tickList,
|
||||||
|
];
|
||||||
|
|
||||||
|
echo render_template(TEMPLATES_DIR . "/home.php", $vars);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
#require_once __DIR__ . '/../bootstrap.php';
|
|
||||||
|
|
||||||
#confirm_setup();
|
|
||||||
|
|
||||||
// Made this a class so it could be more obvious where config settings are coming from.
|
|
||||||
// Felt too much like magic constants in other files before.
|
|
||||||
class Config {
|
class Config {
|
||||||
// properties and default values
|
// properties and default values
|
||||||
public string $siteTitle = 'My tkr';
|
public string $siteTitle = 'My tkr';
|
||||||
@ -39,9 +33,4 @@ class Config {
|
|||||||
|
|
||||||
return self::load();
|
return self::load();
|
||||||
}
|
}
|
||||||
|
|
||||||
// I'm making this
|
|
||||||
public function setPassword(){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
31
src/View/Home/Home.php
Normal file
31
src/View/Home/Home.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
class HomeView {
|
||||||
|
public function renderTicksSection(string $siteDescription, array $ticks, int $page, int $limit){
|
||||||
|
ob_start();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<section id="ticks" class="home-ticks">
|
||||||
|
<div class="home-ticks-header">
|
||||||
|
<h2><?= $siteDescription ?></h2>
|
||||||
|
</div>
|
||||||
|
<div class="home-ticks-list">
|
||||||
|
<?php foreach ($ticks as $tick): ?>
|
||||||
|
<article class="tick">
|
||||||
|
<div class="tick-time"><?= htmlspecialchars(relative_time($tick['timestamp'])) ?></div>
|
||||||
|
<span class="tick-text"><?= escape_and_linkify($tick['tick']) ?></span>
|
||||||
|
</article>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<div class="home-ticks-pagination">
|
||||||
|
<?php if ($page > 1): ?>
|
||||||
|
<a href="?page=<?= $page - 1 ?>">« Newer</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php if (count($ticks) === $limit): ?>
|
||||||
|
<a href="?page=<?= $page + 1 ?>">Older »</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<?php return ob_get_clean();
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
#require_once __DIR__ . '/../bootstrap.php';
|
|
||||||
#require_once CLASSES_DIR . '/Config.php';
|
|
||||||
#require_once CLASSES_DIR . '/User.php';
|
|
||||||
|
|
||||||
#require LIB_DIR . '/emoji.php';
|
|
||||||
|
|
||||||
function save_mood(string $mood): void {
|
function save_mood(string $mood): void {
|
||||||
$config = Config::load();
|
$config = Config::load();
|
||||||
$user = User::load();
|
$user = User::load();
|
||||||
//$db = get_db();
|
|
||||||
|
|
||||||
//$stmt = $db->prepare("UPDATE user SET mood=? WHERE username=?");
|
|
||||||
//$stmt->execute([$mood, $_SESSION['username']]);
|
|
||||||
|
|
||||||
$user->mood = $mood;
|
$user->mood = $mood;
|
||||||
$user = $user->save();
|
$user = $user->save();
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
#require_once __DIR__ . '/../bootstrap.php';
|
|
||||||
|
|
||||||
function save_tick(string $tick): void {
|
function save_tick(string $tick): void {
|
||||||
// build the tick path and filename from the current time
|
// build the tick path and filename from the current time
|
||||||
@ -24,6 +23,8 @@ function save_tick(string $tick): void {
|
|||||||
file_put_contents($filename, $content, FILE_APPEND);
|
file_put_contents($filename, $content, FILE_APPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO - move this into a view along with
|
||||||
|
// the code that builds the tick list.
|
||||||
function stream_ticks(int $limit, int $offset = 0): Generator {
|
function stream_ticks(int $limit, int $offset = 0): Generator {
|
||||||
$tick_files = glob(TICKS_DIR . '/*/*/*.txt');
|
$tick_files = glob(TICKS_DIR . '/*/*/*.txt');
|
||||||
usort($tick_files, fn($a, $b) => strcmp($b, $a)); // sort filenames in reverse chronological order
|
usort($tick_files, fn($a, $b) => strcmp($b, $a)); // sort filenames in reverse chronological order
|
||||||
@ -46,9 +47,6 @@ function stream_ticks(int $limit, int $offset = 0): Generator {
|
|||||||
$year = $pathParts[count($pathParts) - 3];
|
$year = $pathParts[count($pathParts) - 3];
|
||||||
$month = $pathParts[count($pathParts) - 2];
|
$month = $pathParts[count($pathParts) - 2];
|
||||||
$day = pathinfo($pathParts[count($pathParts) - 1], PATHINFO_FILENAME);
|
$day = pathinfo($pathParts[count($pathParts) - 1], PATHINFO_FILENAME);
|
||||||
// $date = $pathParts[count($pathParts) - 3] . '-' .
|
|
||||||
// $pathParts[count($pathParts) - 2] . '-' .
|
|
||||||
// pathinfo($pathParts[count($pathParts) - 1], PATHINFO_FILENAME);
|
|
||||||
|
|
||||||
foreach ($lines as $line) {
|
foreach ($lines as $line) {
|
||||||
// just keep skipping ticks until we get to the starting point
|
// just keep skipping ticks until we get to the starting point
|
||||||
|
@ -38,6 +38,7 @@ function relative_time(string $tickTime): string {
|
|||||||
}
|
}
|
||||||
return $diff->s . ' second' . ($diff->s != 1 ? 's' : '') . ' ago';
|
return $diff->s . ' second' . ($diff->s != 1 ? 's' : '') . ' ago';
|
||||||
}
|
}
|
||||||
|
|
||||||
function verify_data_dir(string $dir, bool $allow_create = false): void {
|
function verify_data_dir(string $dir, bool $allow_create = false): void {
|
||||||
if (!is_dir($dir)) {
|
if (!is_dir($dir)) {
|
||||||
if ($allow_create) {
|
if ($allow_create) {
|
||||||
@ -117,9 +118,9 @@ function get_db(): PDO {
|
|||||||
return $db;
|
return $db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO - Maybe this is the sort of thing that would be good
|
||||||
|
// in a Controller base class.
|
||||||
function render_template(string $templateFile, array $vars = []): string {
|
function render_template(string $templateFile, array $vars = []): string {
|
||||||
#$templatePath = TEMPLATES_DIR . '/' . ltrim($templateFile, '/');
|
|
||||||
|
|
||||||
if (!file_exists($templateFile)) {
|
if (!file_exists($templateFile)) {
|
||||||
throw new RuntimeException("Template not found: $templatePath");
|
throw new RuntimeException("Template not found: $templatePath");
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php /** @var bool $isLoggedIn */ ?>
|
<?php /** @var bool $isLoggedIn */ ?>
|
||||||
<?php /** @var Config $config */ ?>
|
<?php /** @var Config $config */ ?>
|
||||||
<?php /** @var User $user */ ?>
|
<?php /** @var User $user */ ?>
|
||||||
<?php /** @var array $ticks */ ?>
|
<?php /** @var string $tickList */ ?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
@ -48,27 +48,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</section>
|
</section>
|
||||||
<section id="ticks" class="home-ticks">
|
<?php echo $tickList ?>
|
||||||
<div class="home-ticks-header">
|
|
||||||
<h2><?= $config->siteDescription ?></h2>
|
|
||||||
</div>
|
|
||||||
<div class="home-ticks-list">
|
|
||||||
<?php foreach ($ticks as $tick): ?>
|
|
||||||
<article class="tick">
|
|
||||||
<div class="tick-time"><?= htmlspecialchars(relative_time($tick['timestamp'])) ?></div>
|
|
||||||
<span class="tick-text"><?= escape_and_linkify($tick['tick']) ?></span>
|
|
||||||
</article>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</div>
|
|
||||||
<div class="home-ticks-pagination">
|
|
||||||
<?php if ($page > 1): ?>
|
|
||||||
<a href="?page=<?= $page - 1 ?>">« Newer</a>
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php if (count($ticks) === $limit): ?>
|
|
||||||
<a href="?page=<?= $page + 1 ?>">Older »</a>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user