245 lines
6.1 KiB
PHP
245 lines
6.1 KiB
PHP
<?php
|
|
|
|
class Post implements ArrayAccess {
|
|
public $handler;
|
|
|
|
private $content_html;
|
|
private $content_markdown;
|
|
|
|
public $data;
|
|
|
|
public $html_data;
|
|
public $raw_data;
|
|
|
|
private $_child_posts;
|
|
private $_parent_post;
|
|
|
|
public static function _generate_404($post_data) {
|
|
$post_data ??= [
|
|
'id' => -1,
|
|
'path' => '/404.md',
|
|
'title' => '404 Page',
|
|
'metadata' => [
|
|
'type' => '404'
|
|
]
|
|
];
|
|
|
|
return $post_data;
|
|
}
|
|
|
|
public static function deduce_type($path) {
|
|
$ext = pathinfo($path, PATHINFO_EXTENSION);
|
|
|
|
if(preg_match("/\.(\w+)\.md$/", $path, $ext_match)) {
|
|
$ext = $ext_match[1];
|
|
}
|
|
|
|
$ext_mapping = [
|
|
'' => 'directory',
|
|
'md' => 'text/markdown',
|
|
'png' => 'image',
|
|
'jpg' => 'image',
|
|
'jpeg' => 'image'
|
|
];
|
|
|
|
return $ext_mapping[$ext] ?? '?';
|
|
}
|
|
|
|
public static function deduce_media_url($path) {
|
|
if(preg_match("/^(.*\.\w+)\.md$/", $path, $ext_match)) {
|
|
return $ext_match[1];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static function deduce_icon($type) {
|
|
$icon_mapping = [
|
|
'' => 'question',
|
|
'text/markdown' => 'markdown',
|
|
'markdown' => 'markdown',
|
|
'blog' => 'markdown',
|
|
'blog_list' => 'rectangle-list',
|
|
'directory' => 'folder',
|
|
'gallery' => 'images',
|
|
'image' => 'image'
|
|
];
|
|
|
|
return $icon_mapping[$type] ?? 'unknown';
|
|
}
|
|
|
|
public static function deduce_template($type) {
|
|
$template_mapping = [
|
|
'directory' => 'directory',
|
|
'gallery' => 'gallery',
|
|
'image' => 'image'
|
|
];
|
|
|
|
return $template_mapping[$type] ?? 'vanilla';
|
|
}
|
|
|
|
function __construct($post_handler, $post_data, $site_defaults) {
|
|
$this->handler = $post_handler;
|
|
|
|
$this->content_html = null;
|
|
$this->content_markdown = null;
|
|
|
|
if(!isset($post_data) or !isset($post_data['id'])) {
|
|
$post_data = $this->_generate_404($post_data);
|
|
}
|
|
|
|
$data = array_merge($site_defaults, $post_data);
|
|
|
|
if($data['path'] == '') {
|
|
$data['path'] = '/';
|
|
$data['title'] ??= 'root';
|
|
$data['basename'] ??= 'root';
|
|
}
|
|
|
|
|
|
$data['basename'] ??= basename($data['path']);
|
|
$data['title'] ??= basename($data['path']);
|
|
|
|
$data['tags'] ??= [];
|
|
|
|
$data['type'] ??= self::deduce_type($post_data['path']);
|
|
|
|
if(!isset($data['url'])) {
|
|
$url = $site_defaults['uri_prefix'] . $post_data['path'];
|
|
// Adding a trailing slash for "non-filename" paths that
|
|
// need a trail to render properly
|
|
|
|
if(!preg_match('/\.\w+$/', $url)) {
|
|
$url .= '/';
|
|
}
|
|
$data['url'] = $url;
|
|
}
|
|
|
|
$data['icon'] ??= self::deduce_icon($data['type']);
|
|
$data['template'] ??= self::deduce_template($data['type']);
|
|
|
|
$data['media_url'] ??= self::deduce_media_url($data['path']);
|
|
$data['media_preview_url'] ??= $data['media_url'];
|
|
|
|
// TODO: Try to check for thumb image automatically here
|
|
$data['preview_image'] ??= $data['media_preview_url'] ??
|
|
$data['banners'][0]['src'] ?? null;
|
|
|
|
$data['brief'] ??= $data['title'];
|
|
|
|
if($data['type'] == 'gallery') {
|
|
$data['search'] ??= [
|
|
'path' => $data['path'],
|
|
'tags' => [
|
|
'+type:image'
|
|
]
|
|
];
|
|
}
|
|
|
|
$this->data = $data;
|
|
}
|
|
|
|
public function __get($name) {
|
|
if($name == 'html') {
|
|
return $this->get_html();
|
|
}
|
|
if($name == 'markdown') {
|
|
return $this->get_markdown();
|
|
}
|
|
if($name == 'json') {
|
|
return $this->to_json();
|
|
}
|
|
if($name == 'child_posts') {
|
|
return $this->get_child_posts();
|
|
}
|
|
if($name == 'parent') {
|
|
return $this->get_parent_post();
|
|
}
|
|
|
|
if(isset($this->data[$name])) {
|
|
return $this->data[$name];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function offsetGet($offset) : mixed {
|
|
return $this->__get($offset) ?? null;
|
|
}
|
|
public function offsetExists($offset) : bool {
|
|
if(isset($this->data[$offset])) {
|
|
return true;
|
|
}
|
|
|
|
return !is_null($this->offsetGet($offset));
|
|
}
|
|
public function offsetSet($offset, $value) : void {
|
|
$this->data[$offset] = $value;
|
|
}
|
|
public function offsetUnset($offset) : void {
|
|
unset($this->data[$offset]);
|
|
}
|
|
|
|
public function get_html() {
|
|
$this->content_html ??= $this->handler->render_post($this);
|
|
|
|
return $this->content_html;
|
|
}
|
|
public function get_markdown() {
|
|
$this->content_markdown ??=
|
|
$this->handler->get_markdown_for($this);
|
|
|
|
return $this->content_markdown;
|
|
}
|
|
|
|
public function get_child_posts(...$search_args) {
|
|
if(count($search_args) == 0) {
|
|
$this->_child_posts ??=
|
|
$this->handler->get_children_for($this);
|
|
|
|
return $this->_child_posts;
|
|
}
|
|
else {
|
|
return $this->handler->get_children_for($this, ...$search_args);
|
|
}
|
|
}
|
|
|
|
public function to_array($options = []) {
|
|
$out_data = $this->data;
|
|
|
|
if(isset($options['markdown'])) {
|
|
$out_data['markdown'] = $this->get_markdown();
|
|
}
|
|
if(isset($options['html'])) {
|
|
$out_data['html'] = $this->get_html();
|
|
}
|
|
if(isset($options['children'])) {
|
|
$children = $this->get_child_posts();
|
|
$child_arrays = [];
|
|
|
|
foreach($children AS $child) {
|
|
array_push($child_arrays, $child->to_array());
|
|
}
|
|
|
|
$out_data['children'] = $child_arrays;
|
|
}
|
|
|
|
return $out_data;
|
|
}
|
|
public function to_json($options = []) {
|
|
return json_encode($this->to_array($options));
|
|
}
|
|
|
|
|
|
public function get_parent_post() {
|
|
$parent_path = dirname($this->data['path']);
|
|
if($parent_path == '')
|
|
return null;
|
|
|
|
$this->_parent_post ??= $this->handler->get_post($parent_path);
|
|
|
|
return $this->_parent_post;
|
|
}
|
|
}
|
|
|
|
?>
|