Initial MVC refactor
This commit is contained in:
		
							parent
							
								
									7a85c7f9dd
								
							
						
					
					
						commit
						cacbf85283
					
				| @ -1,5 +1,4 @@ | ||||
| <?php | ||||
| #require_once __DIR__ . '/../bootstrap.php';
 | ||||
| 
 | ||||
| define('APP_ROOT', dirname(dirname(__FILE__))); | ||||
| 
 | ||||
| @ -33,10 +32,7 @@ foreach (recursive_glob('*.php', SRC_DIR) as $file) { | ||||
| } | ||||
| 
 | ||||
| confirm_setup(); | ||||
| 
 | ||||
| $isLoggedIn = isset($_SESSION['user_id']); | ||||
| $config = Config::load(); | ||||
| $user = User::load(); | ||||
| 
 | ||||
| // Get request data
 | ||||
| $method = $_SERVER['REQUEST_METHOD']; | ||||
| @ -80,21 +76,9 @@ function route($pattern, $callback, $methods = ['GET']) { | ||||
| 
 | ||||
| // Set content type
 | ||||
| header('Content-Type: text/html; charset=utf-8'); | ||||
| echo "Path: " . $path; | ||||
| 
 | ||||
| // routes
 | ||||
| route('', function() use ($isLoggedIn, $config, $user) { | ||||
|     $page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1; | ||||
|     $limit = $config->itemsPerPage; | ||||
|     $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); | ||||
| route('', function(){ | ||||
|     $hc = new HomeController(); | ||||
|     echo $hc->render(); | ||||
| }); | ||||
|  | ||||
							
								
								
									
										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 | ||||
| #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 { | ||||
|     // properties and default values
 | ||||
|     public string $siteTitle = 'My tkr'; | ||||
| @ -39,9 +33,4 @@ class Config { | ||||
| 
 | ||||
|         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 | ||||
| #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 { | ||||
|     $config = Config::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 = $user->save(); | ||||
|  | ||||
| @ -1,5 +1,4 @@ | ||||
| <?php | ||||
| #require_once __DIR__ . '/../bootstrap.php';
 | ||||
| 
 | ||||
| function save_tick(string $tick): void { | ||||
|     // 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); | ||||
| } | ||||
| 
 | ||||
| // TODO - move this into a view along with
 | ||||
| //        the code that builds the tick list.
 | ||||
| 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
 | ||||
| @ -46,9 +47,6 @@ function stream_ticks(int $limit, int $offset = 0): Generator { | ||||
|         $year = $pathParts[count($pathParts) - 3]; | ||||
|         $month = $pathParts[count($pathParts) - 2]; | ||||
|         $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) { | ||||
|             // 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'; | ||||
| } | ||||
| 
 | ||||
| function verify_data_dir(string $dir, bool $allow_create = false): void { | ||||
|     if (!is_dir($dir)) { | ||||
|         if ($allow_create) { | ||||
| @ -117,9 +118,9 @@ function get_db(): PDO { | ||||
|     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 { | ||||
|     #$templatePath = TEMPLATES_DIR . '/' . ltrim($templateFile, '/');
 | ||||
|      | ||||
|     if (!file_exists($templateFile)) { | ||||
|         throw new RuntimeException("Template not found: $templatePath"); | ||||
|     } | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <?php /** @var bool $isLoggedIn */ ?>
 | ||||
| <?php /** @var Config $config */ ?>
 | ||||
| <?php /** @var User $user */ ?>
 | ||||
| <?php /** @var array $ticks */ ?>
 | ||||
| <?php /** @var string $tickList */ ?>
 | ||||
| 
 | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
| @ -48,27 +48,7 @@ | ||||
|                 </div> | ||||
| <?php endif; ?>
 | ||||
|             </section> | ||||
|             <section id="ticks" class="home-ticks"> | ||||
|                 <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> | ||||
|             <?php echo $tickList ?>
 | ||||
|         </div> | ||||
|     </body> | ||||
| </html> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user