Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.com.git
<?php
declare( strict_types=1 );

final class BlogIndex
{
  private string $baseDir;
  private array  $posts;

  public function __construct()
  {
    $this->baseDir = __DIR__;
    $this->posts   = [];
    $this->scan();
  }

  private function scan() : void
  {
    $flags   = FilesystemIterator::SKIP_DOTS;
    $dirIter = new RecursiveDirectoryIterator( $this->baseDir, $flags );
    $iter    = new RecursiveIteratorIterator(
      $dirIter,
      RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ( $iter as $file ) {
      if ( $file->isDir() === false ) {
        continue;
      }

      $path = $file->getPathname();

      if ( $path === $this->baseDir ) {
        continue;
      }

      $relative = str_replace( $this->baseDir, '', $path );
      $relative = ltrim( $relative, '/' );

      $parts = explode( '/', $relative );

      if ( count( $parts ) !== 4 ) {
        continue;
      }

      list( $year, $month, $day, $slug ) = $parts;

      if ( ctype_digit( $year ) && ctype_digit( $month ) &&
           ctype_digit( $day ) ) {
        $title = $this->readTitle( $path . '/index.html' );

        $this->posts[] = [
          'year'  => $year,
          'month' => $month,
          'day'   => $day,
          'slug'  => $slug,
          'url'   => $relative . '/',
          'title' => $title
        ];
      }
    }

    usort( $this->posts, function ( $a, $b ) : int {
      $ka = $b['year'] . $b['month'] . $b['day'];
      $kb = $a['year'] . $a['month'] . $a['day'];
      return strcmp( $ka, $kb );
    } );
  }

  private function readTitle( string $filePath ) : string
  {
    $title = '';
    $html  = '';

    if ( file_exists( $filePath ) ) {
      $content = file_get_contents( $filePath );
      $html    = $content === false ? '' : $content;
    }

    if ( $html !== '' ) {
      if ( preg_match( '/<title[^>]*>(.*?)<\/title>/is', $html, $m ) ) {
        $t = trim( $m[1] );
        $title = $t === '' ? '' : $t;
      }
    }

    return $title;
  }

  public function render() : void
  {
?>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Blog Index</title>
  <link rel="stylesheet" href="../styles/base.css">
</head>
<body>
<header>
  <img src="../images/logo/title.svg" alt="KeenWrite" class="title">
  <p>
    A free, cross-platform desktop text editor for producing
    <a href="../docs/user-manual.pdf">beautifully typeset</a> PDF files.
  </p>
</header>

<main>
  <h1>Blog</h1>

  <ul>
<?php foreach ( $this->posts as $post ) { ?>
    <li>
      <a href="<?= htmlspecialchars( $post['url'],
        ENT_QUOTES | ENT_SUBSTITUTE ) ?>"><?=
          htmlspecialchars( $post['title'] !== ''
          ? $post['title']
          : $post['slug'], ENT_QUOTES | ENT_SUBSTITUTE ) ?></a>
      <?= ' (' . htmlspecialchars( $post['year'] . '-' . $post['month'] .
        '-' . $post['day'], ENT_QUOTES | ENT_SUBSTITUTE ) . ')' ?>
    </li>
<?php } ?>
  </ul>
</main>
</body>
</html>
<?php
    return;
  }
}

$index = new BlogIndex();
$index->render();