Naming fixes. Add partials. Get single ticks working with clean urls.
This commit is contained in:
parent
97e2c205a3
commit
78ebb67fc0
@ -1,4 +1,16 @@
|
||||
<?php
|
||||
// Store and validate request data
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
$request = $_SERVER['REQUEST_URI'];
|
||||
$path = parse_url($request, PHP_URL_PATH);
|
||||
|
||||
// return a 404 if a request for a .php file gets this far.
|
||||
if (preg_match('/\.php$/', $path)) {
|
||||
http_response_code(404);
|
||||
echo '<h1>404 Not Found</h1>';
|
||||
exit;
|
||||
}
|
||||
|
||||
// Define all the important paths
|
||||
define('APP_ROOT', dirname(dirname(__FILE__)));
|
||||
define('SRC_DIR', APP_ROOT . '/src');
|
||||
@ -34,18 +46,6 @@ Session::start();
|
||||
Session::generateCsrfToken();
|
||||
$config = Config::load();
|
||||
|
||||
// Get request data
|
||||
$method = $_SERVER['REQUEST_METHOD'];
|
||||
$request = $_SERVER['REQUEST_URI'];
|
||||
$path = parse_url($request, PHP_URL_PATH);
|
||||
|
||||
// return a 404 if a request for a .php file gets this far.
|
||||
if (preg_match('/\.php$/', $path)) {
|
||||
http_response_code(404);
|
||||
echo '<h1>404 Not Found</h1>';
|
||||
exit;
|
||||
}
|
||||
|
||||
// Remove the base path from the URL
|
||||
// and strip the trailing slash from the resulting route
|
||||
if (strpos($path, $config->basePath) === 0) {
|
||||
@ -100,6 +100,7 @@ $routeHandlers = [
|
||||
['mood', 'MoodController@handleMood', ['POST']],
|
||||
['feed/rss', 'FeedController@rss'],
|
||||
['feed/atom', 'FeedController@atom'],
|
||||
['tick/{y}/{m}/{d}/{h}/{i}/{s}', 'TickController'],
|
||||
];
|
||||
|
||||
// Set content type
|
||||
|
@ -18,8 +18,8 @@ class AdminController extends Controller {
|
||||
// POST handler
|
||||
// save updated settings
|
||||
public function handleSave(){
|
||||
$isLoggedIn = isset($_SESSION['user_id']);
|
||||
if (!$isLoggedIn){
|
||||
//$isLoggedIn = isset($_SESSION['user_id']);
|
||||
if (!Session::isLoggedIn()){
|
||||
header('Location: ' . $config->basePath . 'login.php');
|
||||
exit;
|
||||
}
|
@ -6,7 +6,6 @@ class HomeController extends Controller {
|
||||
// renders the homepage view.
|
||||
public function index(){
|
||||
$page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
|
||||
$isLoggedIn = isset($_SESSION['user_id']);
|
||||
$config = Config::load();
|
||||
$user = User::load();
|
||||
|
||||
@ -18,10 +17,9 @@ class HomeController extends Controller {
|
||||
$tickList = $view->renderTicksSection($config->siteDescription, $ticks, $page, $limit);
|
||||
|
||||
$vars = [
|
||||
'isLoggedIn' => $isLoggedIn,
|
||||
'config' => $config,
|
||||
'user' => $user,
|
||||
'tickList' => $tickList,
|
||||
'tickList' => $tickList,
|
||||
];
|
||||
|
||||
$this->render("home.php", $vars);
|
11
src/Controller/TickController/TickController.php
Normal file
11
src/Controller/TickController/TickController.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
class TickController extends Controller{
|
||||
// every tick is identified by its timestamp
|
||||
public function index(string $year, string $month, string $day, string $hour, string $minute, string $second){
|
||||
|
||||
$model = new Tick();
|
||||
$tick = $model->get($year, $month, $day, $hour, $minute, $second);
|
||||
$this->render('tick.php', $tick);
|
||||
}
|
||||
}
|
@ -24,6 +24,10 @@ class Session {
|
||||
return $_SESSION['csrf_token'];
|
||||
}
|
||||
|
||||
public static function isLoggedIn(): bool {
|
||||
return isset($_SESSION['user_id']);
|
||||
}
|
||||
|
||||
public static function end(): void {
|
||||
$_SESSION = [];
|
||||
session_destroy();
|
||||
|
@ -104,6 +104,17 @@ class Util {
|
||||
};
|
||||
}
|
||||
|
||||
public static function tick_time_to_tick_path($tickTime){
|
||||
[$date, $time] = explode(' ', $tickTime);
|
||||
$dateParts = explode('-', $date);
|
||||
$timeParts = explode(':', $time);
|
||||
|
||||
[$year, $month, $day] = $dateParts;
|
||||
[$hour, $minute, $second] = $timeParts;
|
||||
|
||||
return "$year/$month/$day/$hour/$minute/$second";
|
||||
}
|
||||
|
||||
// TODO: Move to model base class?
|
||||
public static function get_db(): PDO {
|
||||
Util::verify_data_dir(DATA_DIR, true);
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
class Tick {
|
||||
|
||||
// Everything in this class just reads from and writes to the filesystem
|
||||
// It doesn't maintain state, so everything's just a static function
|
||||
public static function streamTicks(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
|
||||
@ -73,5 +74,30 @@ class Tick {
|
||||
// write the tick to the file (the file will be created if it doesn't exist)
|
||||
$content = $time . "|" . $tick . "\n";
|
||||
file_put_contents($filename, $content, FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
public static function get(string $y, string $m, string $d, string $H, string $i, string $s): array{
|
||||
$tickTime = new DateTime("$y-$m-$d $H:$i:$s");
|
||||
$timestamp = "$H:$i:$s";
|
||||
$file = TICKS_DIR . "/$y/$m/$d.txt";
|
||||
|
||||
if (!file_exists($file)) {
|
||||
http_response_code(404);
|
||||
echo "Tick not found: $file.";
|
||||
exit;
|
||||
}
|
||||
|
||||
$lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
foreach ($lines as $line) {
|
||||
if (str_starts_with($line, $timestamp)) {
|
||||
$tick = Util::escape_and_linkify(explode('|', $line)[1]);
|
||||
|
||||
return [
|
||||
'tickTime' => $tickTime,
|
||||
'tick' => $tick,
|
||||
'config' => Config::load(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,14 @@
|
||||
<?php /** @var Config $config */ ?>
|
||||
<?php /** @var User $user */ ?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<title><?= $config->siteTitle ?></title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="<?= htmlspecialchars($config->basePath) ?>css/tkr.css">
|
||||
<?php include TEMPLATES_DIR . '/partials/head.php'?>
|
||||
</head>
|
||||
<body>
|
||||
<?php include TEMPLATES_DIR . '/partials/navbar.php'?>
|
||||
<html lang="en">
|
||||
<h1>Admin</h1>
|
||||
<div><a href="<?= $config->basePath ?>">Back to home</a></div>
|
||||
<div>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
||||
|
@ -27,9 +27,9 @@ echo '<?xml version="1.0" encoding="utf-8"?>' . "\n";
|
||||
[$hour, $minute, $second] = $timeParts;
|
||||
|
||||
$tickPath = "$year/$month/$day/$hour/$minute/$second";
|
||||
$tickUrl = htmlspecialchars($basePath . "tick.php?path=" . $tickPath);
|
||||
$tickUrl = htmlspecialchars($basePath . "tick/$tickPath");
|
||||
$tickTime = date(DATE_ATOM, strtotime($tick['timestamp']));
|
||||
$tickText = htmlspecialchars($tick['tick']);
|
||||
$tickText = htmlspecialchars($tick['tick']);
|
||||
?>
|
||||
<entry>
|
||||
<title><?= $tickText ?></title>
|
||||
|
@ -15,7 +15,6 @@ echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
||||
<language>en-us</language>
|
||||
<lastBuildDate><?php echo date(DATE_RSS); ?></lastBuildDate>
|
||||
<?php foreach ($ticks as $tick):
|
||||
// TODO: Make this a util function.
|
||||
[$date, $time] = explode(' ', $tick['timestamp']);
|
||||
$dateParts = explode('-', $date);
|
||||
$timeParts = explode(':', $time);
|
||||
@ -27,7 +26,7 @@ echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
||||
?>
|
||||
<item>
|
||||
<title><?php echo htmlspecialchars($tick['tick']); ?></title>
|
||||
<link><?php echo htmlspecialchars($config->basePath . "tick.php?path=$tickPath"); ?></link>
|
||||
<link><?php echo htmlspecialchars($config->basePath . "tick/$tickPath"); ?></link>
|
||||
<description><?php echo htmlspecialchars($tick['tick']); ?></description>
|
||||
<pubDate><?php echo date(DATE_RSS, strtotime($tick['timestamp'])); ?></pubDate>
|
||||
<guid><?php echo htmlspecialchars($tickPath); ?></guid>
|
||||
|
@ -2,26 +2,13 @@
|
||||
<?php /** @var Config $config */ ?>
|
||||
<?php /** @var User $user */ ?>
|
||||
<?php /** @var string $tickList */ ?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><?= $config->siteTitle ?></title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="<?= htmlspecialchars($config->basePath) ?>css/tkr.css?v=<?= time() ?>">
|
||||
<?php include TEMPLATES_DIR . '/partials/head.php'?>
|
||||
</head>
|
||||
<body>
|
||||
<div class="home-navbar">
|
||||
<a href="<?= $config->basePath ?>feed/rss">rss</a>
|
||||
<a href="<?= $config->basePath ?>feed/atom">atom</a>
|
||||
<?php if (!$isLoggedIn): ?>
|
||||
<a href="<?= $config->basePath ?>login">login</a>
|
||||
<?php else: ?>
|
||||
<a href="<?= $config->basePath ?>admin">admin</a>
|
||||
<a href="<?= $config->basePath ?>logout">logout</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php include TEMPLATES_DIR . '/partials/navbar.php'?>
|
||||
<div class="home-container">
|
||||
<section id="sidebar" class="home-sidebar">
|
||||
<div class="home-header">
|
||||
@ -32,12 +19,12 @@
|
||||
<div class="profile-row">
|
||||
<div class="mood-bar">
|
||||
<span>Current mood: <?= $user->mood ?></span>
|
||||
<?php if ($isLoggedIn): ?>
|
||||
<?php if (Session::isLoggedIn()): ?>
|
||||
<a href="<?= $config->basePath ?>mood">Change</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($isLoggedIn): ?>
|
||||
<?php if (Session::isLoggedIn()): ?>
|
||||
<hr/>
|
||||
<div class="profile-row">
|
||||
<form class="tick-form" method="post">
|
||||
|
@ -1,16 +1,13 @@
|
||||
<?php /** @var Config $config */ ?>
|
||||
<?php /** @var string $csrfToken */ ?>
|
||||
<?php /** @var string $error */ ?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><?= $config->siteTitle ?></title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="<?= htmlspecialchars($config->basePath) ?>css/tkr.css?v=<?= time() ?>">
|
||||
<?php include TEMPLATES_DIR . '/partials/head.php'?>
|
||||
</head>
|
||||
<body>
|
||||
<?php include TEMPLATES_DIR . '/partials/navbar.php'?>
|
||||
<h2>Login</h2>
|
||||
<?php if ($error): ?>
|
||||
<p style="color:red"><?= htmlspecialchars($error) ?></p>
|
||||
|
@ -1,19 +1,13 @@
|
||||
<?php /** @var Config $config */ ?>
|
||||
<?php /** @var string $moodPicker */ ?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<title><?= $config->siteTitle ?></title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="<?= htmlspecialchars($config->basePath) ?>css/tkr.css">
|
||||
<?php include TEMPLATES_DIR . '/partials/head.php'?>
|
||||
</head>
|
||||
<body>
|
||||
<?php include TEMPLATES_DIR . '/partials/navbar.php'?>
|
||||
<h2>How are you feeling?</h2>
|
||||
|
||||
<?php echo $moodPicker; ?>
|
||||
|
||||
<a class="back-link" href="<?= htmlspecialchars($config->basePath) ?>">Back to home</a>
|
||||
</body>
|
||||
</html>
|
5
templates/partials/head.php
Normal file
5
templates/partials/head.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php /** @var Config $config */ ?>
|
||||
<title><?= $config->siteTitle ?></title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="<?= htmlspecialchars($config->basePath) ?>css/tkr.css?v=<?= time() ?>">
|
12
templates/partials/navbar.php
Normal file
12
templates/partials/navbar.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php /** @var Config $config */ ?>
|
||||
<div class="navbar">
|
||||
<a href="<?= $config->basePath ?>">home</a>
|
||||
<a href="<?= $config->basePath ?>feed/rss">rss</a>
|
||||
<a href="<?= $config->basePath ?>feed/atom">atom</a>
|
||||
<?php if (!Session::isLoggedIn()): ?>
|
||||
<a href="<?= $config->basePath ?>login">login</a>
|
||||
<?php else: ?>
|
||||
<a href="<?= $config->basePath ?>admin">admin</a>
|
||||
<a href="<?= $config->basePath ?>logout">logout</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
@ -1,10 +1,5 @@
|
||||
<?php
|
||||
#require_once __DIR__ . '/../bootstrap.php';
|
||||
|
||||
#confirm_setup();
|
||||
|
||||
// If we got past confirm_setup(), then setup isn't complete.
|
||||
$db = get_db();
|
||||
$db = Utli::get_db();
|
||||
|
||||
// Handle submitted form
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
|
@ -1,32 +1,15 @@
|
||||
<?php
|
||||
|
||||
$path = $_GET['path'] ?? '';
|
||||
$parts = explode('/', $path);
|
||||
|
||||
if (count($parts) !== 6) {
|
||||
http_response_code(400);
|
||||
echo "Invalid tick path.";
|
||||
exit;
|
||||
}
|
||||
|
||||
[$y, $m, $d, $H, $i, $s] = $parts;
|
||||
$timestamp = "$H:$i:$s";
|
||||
$file = TICKS_DIR . "/$y/$m/$d.txt";
|
||||
|
||||
if (!file_exists($file)) {
|
||||
http_response_code(404);
|
||||
echo "Tick not found.";
|
||||
exit;
|
||||
}
|
||||
|
||||
$lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
foreach ($lines as $line) {
|
||||
if (str_starts_with($line, $timestamp)) {
|
||||
echo "<h1>Tick from $timestamp on $y-$m-$d</h1>";
|
||||
echo "<p>" . escape_and_linkify(explode('|', $line)[1]) . "</p>";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
http_response_code(404);
|
||||
echo "Tick not found.";
|
||||
<?php /** @var Config $config */ ?>
|
||||
<?php /** @var Date $tickTime */ ?>
|
||||
<?php /** @var string $tick */ ?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<?php include TEMPLATES_DIR . '/partials/head.php'?>
|
||||
</head>
|
||||
<body>
|
||||
<?php include TEMPLATES_DIR . '/partials/navbar.php'?>
|
||||
<!DOCTYPE html>
|
||||
<h1>Tick from <?= $tickTime->format('Y-m-d H:i:s'); ?></h1>
|
||||
<p><?= $tick ?></p>
|
||||
</body>
|
||||
</html>
|
Loading…
x
Reference in New Issue
Block a user