diff --git a/public/config.php b/public/config.php new file mode 100644 index 0000000..efde3e6 --- /dev/null +++ b/public/config.php @@ -0,0 +1,16 @@ + 'CodePress', + 'site_description' => 'A simple PHP CMS', + 'base_url' => '/', + 'content_dir' => __DIR__ . '/public/content', + 'templates_dir' => __DIR__ . '/templates', + 'cache_dir' => __DIR__ . '/cache', + 'default_page' => 'home', + 'error_404' => '404', + 'markdown_enabled' => true, + 'php_enabled' => true, + 'bootstrap_version' => '5.3.0', + 'jquery_version' => '3.7.1' +]; \ No newline at end of file diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..4965702 --- /dev/null +++ b/public/index.php @@ -0,0 +1,365 @@ +config = $config; + $this->buildMenu(); + + if (isset($_GET['search'])) { + $this->performSearch($_GET['search']); + } + } + + private function buildMenu() { + $this->menu = $this->scanDirectory($this->config['content_dir'], ''); + } + + private function scanDirectory($dir, $prefix) { + if (!is_dir($dir)) return []; + + $items = scandir($dir); + sort($items); + $result = []; + + foreach ($items as $item) { + if ($item[0] === '.') continue; + + $path = $dir . '/' . $item; + $relativePath = $prefix ? $prefix . '/' . $item : $item; + + if (is_dir($path)) { + $result[] = [ + 'type' => 'folder', + 'title' => ucfirst($item), + 'path' => $relativePath, + 'children' => $this->scanDirectory($path, $relativePath) + ]; + } elseif (preg_match('/\.(md|php|html)$/', $item)) { + $title = ucfirst(pathinfo($item, PATHINFO_FILENAME)); + $result[] = [ + 'type' => 'file', + 'title' => $title, + 'path' => $relativePath, + 'url' => '?page=' . $relativePath + ]; + } + } + + return $result; + } + + private function performSearch($query) { + $this->searchResults = []; + $this->searchInDirectory($this->config['content_dir'], '', $query); + } + + private function searchInDirectory($dir, $prefix, $query) { + if (!is_dir($dir)) return; + + $items = scandir($dir); + + foreach ($items as $item) { + if ($item[0] === '.') continue; + + $path = $dir . '/' . $item; + $relativePath = $prefix ? $prefix . '/' . $item : $item; + + if (is_dir($path)) { + $this->searchInDirectory($path, $relativePath, $query); +} elseif (preg_match('/\.(md|php|html)$/', $item)) { + $content = file_get_contents($path); + if (stripos($content, $query) !== false || stripos($item, $query) !== false) { + $title = ucfirst(pathinfo($item, PATHINFO_FILENAME)); + $this->searchResults[] = [ + 'title' => $title, + 'path' => $relativePath, + 'url' => '?page=' . $relativePath, + 'snippet' => $this->createSnippet($content, $query) + ]; + } + } + } + } + + private function createSnippet($content, $query) { + $content = strip_tags($content); + $pos = stripos($content, $query); + if ($pos === false) return substr($content, 0, 100) . '...'; + + $start = max(0, $pos - 50); + $snippet = substr($content, $start, 150); + return '...' . $snippet . '...'; + } + + public function getPage() { + if (isset($_GET['search'])) { + return $this->getSearchResults(); + } + + $page = $_GET['page'] ?? $this->config['default_page']; + $page = preg_replace('/\.[^.]+$/', '', $page); + + $filePath = $this->config['content_dir'] . '/' . $page; + $actualFilePath = null; + + if (file_exists($filePath . '.md')) { + $actualFilePath = $filePath . '.md'; + $result = $this->parseMarkdown(file_get_contents($actualFilePath)); + } elseif (file_exists($filePath . '.php')) { + $actualFilePath = $filePath . '.php'; + $result = $this->parsePHP($actualFilePath); + } elseif (file_exists($filePath . '.html')) { + $actualFilePath = $filePath . '.html'; + $result = $this->parseHTML(file_get_contents($actualFilePath)); + } elseif (file_exists($filePath)) { + $actualFilePath = $filePath; + $extension = pathinfo($filePath, PATHINFO_EXTENSION); + if ($extension === 'md') { + $result = $this->parseMarkdown(file_get_contents($actualFilePath)); + } elseif ($extension === 'php') { + $result = $this->parsePHP($actualFilePath); + } elseif ($extension === 'html') { + $result = $this->parseHTML(file_get_contents($actualFilePath)); + } + } + + if (isset($result) && $actualFilePath) { + $result['file_info'] = $this->getFileInfo($actualFilePath); + return $result; + } + + return $this->getError404(); + } + + private function getFileInfo($filePath) { + if (!file_exists($filePath)) { + return null; + } + + $stats = stat($filePath); + $created = date('d-m-Y H:i', $stats['ctime']); + $modified = date('d-m-Y H:i', $stats['mtime']); + + return [ + 'created' => $created, + 'modified' => $modified, + 'size' => $this->formatFileSize($stats['size']) + ]; + } + + private function formatFileSize($bytes) { + $units = ['B', 'KB', 'MB', 'GB']; + $bytes = max($bytes, 0); + $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); + $pow = min($pow, count($units) - 1); + + $bytes /= pow(1024, $pow); + + return round($bytes, 2) . ' ' . $units[$pow]; + } + + private function getSearchResults() { + $query = $_GET['search']; + $content = '
No results found.
'; + } else { + $content .= 'Found ' . count($this->searchResults) . ' results:
'; + foreach ($this->searchResults as $result) { + $content .= '' . htmlspecialchars($result['path']) . '
'; + $content .= '' . htmlspecialchars($result['snippet']) . '
'; + $content .= '', $body); + $body = '
' . $body . '
'; + $body = preg_replace('/<\/p>/', '', $body); + $body = preg_replace('/
( The page you are looking for does not exist.]*>(.*?)<\/h1>/i', $content, $matches)) {
+ $title = strip_tags($matches[1]);
+ }
+
+ return [
+ 'title' => $title,
+ 'content' => $content
+ ];
+ }
+
+ private function getError404() {
+ return [
+ 'title' => 'Page Not Found',
+ 'content' => '
404 - Page Not Found
+
{{site_title}}
+ {{page_title}}
+