__DIR__ . '/../../datas/pages/404.md', 'filename' => '404', 'created_at' => '1970-01-01', 'modified_at' => '1970-01-01', ]; /** * Constructs a new instance of the class * * @param array $params An array of parameters */ function __construct($params) { if (!isset($params['config']['cron'])) { $params['config']['cron'] = false; } if (file_exists($this->cacheFile) && $params['config']['cron'] === false) { $mdFileCache = json_decode(file_get_contents($this->cacheFile), true); } else { $mdFileCache = $this->indexMdFiles(); } $this->postPerPage = $params['config']['postPerPage']; $this->totalPost = count($mdFileCache); $this->totalPage = ceil($this->totalPost / $this->postPerPage); $this->numberEntry = $params['config']['numberOfLastItem']; $this->mdFileCache = $mdFileCache; } /** * Indexes all the markdown files in the posts directory * * @return array The indexed markdown files */ private function indexMdFiles(): array { $directory = new \RecursiveDirectoryIterator($this->postsDir); $slugify = new Slugify(); foreach (new \RecursiveIteratorIterator($directory) as $file) { if ($file->getExtension() === 'md') { $filename = $file->getBasename('.md'); $pathParts = explode(DIRECTORY_SEPARATOR, $file->getPath()); $year = $pathParts[count($pathParts) - 2]; $month = $pathParts[count($pathParts) - 1]; $nameParts = explode(' - ', $filename); $day = $nameParts[0]; if (empty($nameParts['1'])) { continue; } $slug = $slugify->slugify(trim($nameParts[1])); $createDate = \DateTimeImmutable::createFromFormat("Y-m-d H:i:s", "$year-$month-$day" . ' ' . date('H:i:s')); $created_at = $createDate->format("Y-m-d"); $modifiedDate = \DateTimeImmutable::createFromFormat("U", $file->getMTime()); $modified_at = $modifiedDate->format(\DateTimeImmutable::ATOM); $this->mdFileCache[$slug] = [ 'file' => $file->getPathname(), 'filename' => $filename, 'title' => ucfirst(trim($nameParts[1])), 'year' => $year, 'month' => $month, 'created_at' => $created_at, 'modified_at' => $modified_at ]; } } uasort($this->mdFileCache, function ($a, $b) { return strtotime($b['created_at']) <=> strtotime($a['created_at']); }); file_put_contents($this->cacheFile, json_encode($this->mdFileCache)); return $this->mdFileCache; } /** * Retrieves the markdown files for a given page * * @param int $page The page number * @return array An array of markdown files */ function getFilesForPage(int $page): array { if ($page > $this->totalPage) { $page = $this->totalPage; } $offset = ($page - 1) * $this->postPerPage; return array_slice($this->mdFileCache, $offset, $this->postPerPage, true); } /** * Finds a markdown file by slug and returns its content * * @param string $slug The slug of posts/page * @return string The content of the markdown */ public function findPostBySlug(string $slug): string { if ($this->mdFileCache[$slug] && file_exists($this->mdFileCache[$slug]['file'])) { return file_get_contents($this->mdFileCache[$slug]['file']); } else { return file_get_contents($this->notFound['file']); } } /** * Finds all the markdown files for a given year * * @param int $year * @return array An array of markdown file */ public function findPostByYear(int $year): array { $result = array(); foreach ($this->mdFileCache as $key => $post) { if ((int)$post['year'] === $year) { $result[$key] = $post; } } $this->mdFileCache = $result; $this->totalPage = ceil(count($this->mdFileCache) / $this->postPerPage); return $result; } /** * Finds all the markdown files for a given month * * @param int $month * @return array An array of markdown file */ public function findPostByMonth(int $month): array { $result = array(); foreach ($this->mdFileCache as $key => $post) { if ((int)$post['year'] === $month) { $result[$key] = $post; } } $this->mdFileCache = $result; $this->totalPage = ceil(count($this->mdFileCache) / $this->postPerPage); return $result; } /** * Returns the information of a markdown file for given slug * * @param string $slug The slug of post/page * @return array The information of the markdown file */ public function returnPostInfo(string $slug): array { return $this->mdFileCache[$slug]; } /** * Returns the most recent post * * @return array An array of the most recent mdFileCache */ public function getLastPost(): array { if ($this->totalPost > 0) { $this->postList = array_slice($this->mdFileCache, 0, $this->numberEntry); } return $this->postList; } /** * Generates the HTML for the pagination links * * @param int $page The current page number * @return string The generated HTML for the pagination links */ public function makePagination(int $page): string { $html = ''; for ($i = 1; $i <= $this->totalPage; $i++) { if ($i === $page) { $class = 'class="current" '; } else { $class = null; } $html .= '
  • ' . $i . '
  • '; } return $html; } /** * Generates the HTML for the list of posts * * @return string|null The generated HTML for the list of posts or null */ public function makeList(): string { if (!empty($this->postList)) { $htmlPost = ''; $this->postsHash = sha1($htmlPost); return $htmlPost; } $this->postsHash = sha1('empty'); return ''; } /** * Converts markdown content to HTML * * @param string $content The markdown content to convert to HTML * @return string The converted HTML content */ function markdownToHtml(string $content): string { $config = [ 'disallowed_raw_html' => [ 'disallowed_tags' => ['title', 'textarea', 'style', 'xmp', 'iframe', 'noembed', 'noframes', 'script', 'plaintext'], ], 'table' => [ 'wrap' => [ 'enabled' => false, 'tag' => 'div', 'attributes' => [], ], 'alignment_attributes' => [ 'left' => ['align' => 'left'], 'center' => ['align' => 'center'], 'right' => ['align' => 'right'], ], ], 'mentions' => [ 'tag_handle' => [ 'prefix' => '#', 'pattern' => '[a-z\d](?:[a-z\d]|-(?=[a-z\d])){0,38}(?!\w)', 'generator' => '/tag/%s', ] ], ]; $environment = new Environment($config); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new MentionExtension()); $environment->addExtension(new TableExtension()); $converter = new MarkdownConverter($environment); return $converter->convert($content); } /** * Extracts the lead paragraph from a post * * @param string $markdownContent The markdown content to extract the lead paragraph from * @return string|null The extracted lead paragraph or null */ static function extractLead(string $markdownContent): ?string { $pattern = '/---\s*(.*?)\s*---/s'; if (preg_match($pattern, $markdownContent, $matches)) { return trim($matches[1]); } return null; } }