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
|
<?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 all the important paths
|
||||||
define('APP_ROOT', dirname(dirname(__FILE__)));
|
define('APP_ROOT', dirname(dirname(__FILE__)));
|
||||||
define('SRC_DIR', APP_ROOT . '/src');
|
define('SRC_DIR', APP_ROOT . '/src');
|
||||||
@ -34,18 +46,6 @@ Session::start();
|
|||||||
Session::generateCsrfToken();
|
Session::generateCsrfToken();
|
||||||
$config = Config::load();
|
$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
|
// Remove the base path from the URL
|
||||||
// and strip the trailing slash from the resulting route
|
// and strip the trailing slash from the resulting route
|
||||||
if (strpos($path, $config->basePath) === 0) {
|
if (strpos($path, $config->basePath) === 0) {
|
||||||
@ -100,6 +100,7 @@ $routeHandlers = [
|
|||||||
['mood', 'MoodController@handleMood', ['POST']],
|
['mood', 'MoodController@handleMood', ['POST']],
|
||||||
['feed/rss', 'FeedController@rss'],
|
['feed/rss', 'FeedController@rss'],
|
||||||
['feed/atom', 'FeedController@atom'],
|
['feed/atom', 'FeedController@atom'],
|
||||||
|
['tick/{y}/{m}/{d}/{h}/{i}/{s}', 'TickController'],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Set content type
|
// Set content type
|
||||||
|
@ -18,8 +18,8 @@ class AdminController extends Controller {
|
|||||||
// POST handler
|
// POST handler
|
||||||
// save updated settings
|
// save updated settings
|
||||||
public function handleSave(){
|
public function handleSave(){
|
||||||
$isLoggedIn = isset($_SESSION['user_id']);
|
//$isLoggedIn = isset($_SESSION['user_id']);
|
||||||
if (!$isLoggedIn){
|
if (!Session::isLoggedIn()){
|
||||||
header('Location: ' . $config->basePath . 'login.php');
|
header('Location: ' . $config->basePath . 'login.php');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
@ -6,7 +6,6 @@ class HomeController extends Controller {
|
|||||||
// renders the homepage view.
|
// renders the homepage view.
|
||||||
public function index(){
|
public function index(){
|
||||||
$page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
|
$page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
|
||||||
$isLoggedIn = isset($_SESSION['user_id']);
|
|
||||||
$config = Config::load();
|
$config = Config::load();
|
||||||
$user = User::load();
|
$user = User::load();
|
||||||
|
|
||||||
@ -18,10 +17,9 @@ class HomeController extends Controller {
|
|||||||
$tickList = $view->renderTicksSection($config->siteDescription, $ticks, $page, $limit);
|
$tickList = $view->renderTicksSection($config->siteDescription, $ticks, $page, $limit);
|
||||||
|
|
||||||
$vars = [
|
$vars = [
|
||||||
'isLoggedIn' => $isLoggedIn,
|
|
||||||
'config' => $config,
|
'config' => $config,
|
||||||
'user' => $user,
|
'user' => $user,
|
||||||
'tickList' => $tickList,
|
'tickList' => $tickList,
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->render("home.php", $vars);
|
$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'];
|
return $_SESSION['csrf_token'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function isLoggedIn(): bool {
|
||||||
|
return isset($_SESSION['user_id']);
|
||||||
|
}
|
||||||
|
|
||||||
public static function end(): void {
|
public static function end(): void {
|
||||||
$_SESSION = [];
|
$_SESSION = [];
|
||||||
session_destroy();
|
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?
|
// TODO: Move to model base class?
|
||||||
public static function get_db(): PDO {
|
public static function get_db(): PDO {
|
||||||
Util::verify_data_dir(DATA_DIR, true);
|
Util::verify_data_dir(DATA_DIR, true);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
class Tick {
|
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 {
|
public static function streamTicks(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
|
||||||
@ -73,5 +74,30 @@ class Tick {
|
|||||||
// write the tick to the file (the file will be created if it doesn't exist)
|
// write the tick to the file (the file will be created if it doesn't exist)
|
||||||
$content = $time . "|" . $tick . "\n";
|
$content = $time . "|" . $tick . "\n";
|
||||||
file_put_contents($filename, $content, FILE_APPEND);
|
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 Config $config */ ?>
|
||||||
<?php /** @var User $user */ ?>
|
<?php /** @var User $user */ ?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title><?= $config->siteTitle ?></title>
|
<?php include TEMPLATES_DIR . '/partials/head.php'?>
|
||||||
<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">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<?php include TEMPLATES_DIR . '/partials/navbar.php'?>
|
||||||
|
<html lang="en">
|
||||||
<h1>Admin</h1>
|
<h1>Admin</h1>
|
||||||
<div><a href="<?= $config->basePath ?>">Back to home</a></div>
|
|
||||||
<div>
|
<div>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<input type="hidden" name="csrf_token" value="<?= htmlspecialchars($_SESSION['csrf_token']) ?>">
|
<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;
|
[$hour, $minute, $second] = $timeParts;
|
||||||
|
|
||||||
$tickPath = "$year/$month/$day/$hour/$minute/$second";
|
$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']));
|
$tickTime = date(DATE_ATOM, strtotime($tick['timestamp']));
|
||||||
$tickText = htmlspecialchars($tick['tick']);
|
$tickText = htmlspecialchars($tick['tick']);
|
||||||
?>
|
?>
|
||||||
<entry>
|
<entry>
|
||||||
<title><?= $tickText ?></title>
|
<title><?= $tickText ?></title>
|
||||||
|
@ -15,7 +15,6 @@ echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
|||||||
<language>en-us</language>
|
<language>en-us</language>
|
||||||
<lastBuildDate><?php echo date(DATE_RSS); ?></lastBuildDate>
|
<lastBuildDate><?php echo date(DATE_RSS); ?></lastBuildDate>
|
||||||
<?php foreach ($ticks as $tick):
|
<?php foreach ($ticks as $tick):
|
||||||
// TODO: Make this a util function.
|
|
||||||
[$date, $time] = explode(' ', $tick['timestamp']);
|
[$date, $time] = explode(' ', $tick['timestamp']);
|
||||||
$dateParts = explode('-', $date);
|
$dateParts = explode('-', $date);
|
||||||
$timeParts = explode(':', $time);
|
$timeParts = explode(':', $time);
|
||||||
@ -27,7 +26,7 @@ echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
|
|||||||
?>
|
?>
|
||||||
<item>
|
<item>
|
||||||
<title><?php echo htmlspecialchars($tick['tick']); ?></title>
|
<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>
|
<description><?php echo htmlspecialchars($tick['tick']); ?></description>
|
||||||
<pubDate><?php echo date(DATE_RSS, strtotime($tick['timestamp'])); ?></pubDate>
|
<pubDate><?php echo date(DATE_RSS, strtotime($tick['timestamp'])); ?></pubDate>
|
||||||
<guid><?php echo htmlspecialchars($tickPath); ?></guid>
|
<guid><?php echo htmlspecialchars($tickPath); ?></guid>
|
||||||
|
@ -2,26 +2,13 @@
|
|||||||
<?php /** @var Config $config */ ?>
|
<?php /** @var Config $config */ ?>
|
||||||
<?php /** @var User $user */ ?>
|
<?php /** @var User $user */ ?>
|
||||||
<?php /** @var string $tickList */ ?>
|
<?php /** @var string $tickList */ ?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title><?= $config->siteTitle ?></title>
|
<?php include TEMPLATES_DIR . '/partials/head.php'?>
|
||||||
<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() ?>">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="home-navbar">
|
<?php include TEMPLATES_DIR . '/partials/navbar.php'?>
|
||||||
<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>
|
|
||||||
<div class="home-container">
|
<div class="home-container">
|
||||||
<section id="sidebar" class="home-sidebar">
|
<section id="sidebar" class="home-sidebar">
|
||||||
<div class="home-header">
|
<div class="home-header">
|
||||||
@ -32,12 +19,12 @@
|
|||||||
<div class="profile-row">
|
<div class="profile-row">
|
||||||
<div class="mood-bar">
|
<div class="mood-bar">
|
||||||
<span>Current mood: <?= $user->mood ?></span>
|
<span>Current mood: <?= $user->mood ?></span>
|
||||||
<?php if ($isLoggedIn): ?>
|
<?php if (Session::isLoggedIn()): ?>
|
||||||
<a href="<?= $config->basePath ?>mood">Change</a>
|
<a href="<?= $config->basePath ?>mood">Change</a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<?php if ($isLoggedIn): ?>
|
<?php if (Session::isLoggedIn()): ?>
|
||||||
<hr/>
|
<hr/>
|
||||||
<div class="profile-row">
|
<div class="profile-row">
|
||||||
<form class="tick-form" method="post">
|
<form class="tick-form" method="post">
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
<?php /** @var Config $config */ ?>
|
<?php /** @var Config $config */ ?>
|
||||||
<?php /** @var string $csrfToken */ ?>
|
<?php /** @var string $csrfToken */ ?>
|
||||||
<?php /** @var string $error */ ?>
|
<?php /** @var string $error */ ?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title><?= $config->siteTitle ?></title>
|
<?php include TEMPLATES_DIR . '/partials/head.php'?>
|
||||||
<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() ?>">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<?php include TEMPLATES_DIR . '/partials/navbar.php'?>
|
||||||
<h2>Login</h2>
|
<h2>Login</h2>
|
||||||
<?php if ($error): ?>
|
<?php if ($error): ?>
|
||||||
<p style="color:red"><?= htmlspecialchars($error) ?></p>
|
<p style="color:red"><?= htmlspecialchars($error) ?></p>
|
||||||
|
@ -1,19 +1,13 @@
|
|||||||
<?php /** @var Config $config */ ?>
|
<?php /** @var Config $config */ ?>
|
||||||
<?php /** @var string $moodPicker */ ?>
|
<?php /** @var string $moodPicker */ ?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title><?= $config->siteTitle ?></title>
|
<?php include TEMPLATES_DIR . '/partials/head.php'?>
|
||||||
<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">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<?php include TEMPLATES_DIR . '/partials/navbar.php'?>
|
||||||
<h2>How are you feeling?</h2>
|
<h2>How are you feeling?</h2>
|
||||||
|
|
||||||
<?php echo $moodPicker; ?>
|
<?php echo $moodPicker; ?>
|
||||||
|
|
||||||
<a class="back-link" href="<?= htmlspecialchars($config->basePath) ?>">Back to home</a>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</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
|
<?php
|
||||||
#require_once __DIR__ . '/../bootstrap.php';
|
$db = Utli::get_db();
|
||||||
|
|
||||||
#confirm_setup();
|
|
||||||
|
|
||||||
// If we got past confirm_setup(), then setup isn't complete.
|
|
||||||
$db = get_db();
|
|
||||||
|
|
||||||
// Handle submitted form
|
// Handle submitted form
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
@ -1,32 +1,15 @@
|
|||||||
<?php
|
<?php /** @var Config $config */ ?>
|
||||||
|
<?php /** @var Date $tickTime */ ?>
|
||||||
$path = $_GET['path'] ?? '';
|
<?php /** @var string $tick */ ?>
|
||||||
$parts = explode('/', $path);
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
if (count($parts) !== 6) {
|
<head>
|
||||||
http_response_code(400);
|
<?php include TEMPLATES_DIR . '/partials/head.php'?>
|
||||||
echo "Invalid tick path.";
|
</head>
|
||||||
exit;
|
<body>
|
||||||
}
|
<?php include TEMPLATES_DIR . '/partials/navbar.php'?>
|
||||||
|
<!DOCTYPE html>
|
||||||
[$y, $m, $d, $H, $i, $s] = $parts;
|
<h1>Tick from <?= $tickTime->format('Y-m-d H:i:s'); ?></h1>
|
||||||
$timestamp = "$H:$i:$s";
|
<p><?= $tick ?></p>
|
||||||
$file = TICKS_DIR . "/$y/$m/$d.txt";
|
</body>
|
||||||
|
</html>
|
||||||
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.";
|
|
Loading…
x
Reference in New Issue
Block a user