raw = mysqli_connect(getenv('MYSQL_HOST'),
getenv('MYSQL_USER'), getenv('MYSQL_PASSWORD'), getenv('MYSQL_DATABASE'));
}
else {
$this->raw = mysqli_connect($db_params['MYSQL_HOST'],
$db_params['MYSQL_USER'], $db_params['MYSQL_PASSWORD'], $db_params['MYSQL_DATABASE']);
}
$this->data_directory = 'raw';
if (!$this->raw)
{
echo 'Connection failed
';
echo 'Error number: ' . mysqli_connect_errno() . '
';
echo 'Error message: ' . mysqli_connect_error() . '
';
die();
}
}
function _exec($qery, $argtypes, ...$args) {
$stmt = $this->raw->prepare($qery);
$stmt->bind_param($argtypes, ...$args);
$stmt->execute();
return $stmt->get_result();
}
function _prepare_post_data($post_data) {
if($post_data == null) {
return [
"found" => false
];
}
$post_data["found"] = true;
$post_data["post_basename"] = basename($post_data["post_path"]);
$post_meta = json_decode($post_data["post_metadata"], true) ?? [];
$post_meta["title"] ??= basename($post_data["post_path"]);
if(!isset($post_meta['type'])) {
$type = null;
$ext = pathinfo($post_data['post_basename'], PATHINFO_EXTENSION);
if($ext == '') {
$type = 'directory';
} elseif($ext == 'md') {
$type = 'text/markdown';
}
$post_meta['type'] = $type;
}
$post_data["post_content"] ??= '';
$post_data["post_file_dir"] = '/' . $this->data_directory . $post_data["post_path"];
$post_data['post_metadata'] = $post_meta;
return $post_data;
}
function _fill_post_descriptors($post_data) {
switch(($post_data['post_metadata']['type'] ?? '')) {
case 'directory':
$readme = $this->get_post_by_path($post_data['post_path'] . '/README.md', false);
$post_data['readme'] = $readme;
if($readme['found']) {
$post_data['post_metadata']['title'] = $readme['post_metadata']['title'];
}
break;
case 'file':
$post_data['descriptor'] = $this->get_post_by_path($post_data['post_path'] . '.md', false);
break;
}
return $post_data;
}
function ensure_directory($directory) {
$data_directory = $this->data_directory . $directory;
is_dir($data_directory) || mkdir($data_directory, 0777, true);
$insert_statement = "
INSERT INTO posts
(post_path, post_path_depth, post_metadata, post_content)
VALUES
(?, ?, ?, '') AS new
ON DUPLICATE KEY UPDATE post_path=new.post_path
";
$json_metadata = json_encode(["type" => 'directory']);
while(strlen($directory) > 1) {
try {
echo "Inserting dir " . $directory . "\n";
$this->_exec($insert_statement, "sis",
$directory, substr_count($directory, '/'),
$json_metadata);
}
catch(Exception $e) {
}
$directory = dirname($directory);
}
}
function ensure_post_placeholder($post_path, $post_metadata) {
$post_path = chop($post_path, '/');
$path_depth = substr_count($post_path, "/");
$this->ensure_directory(dirname($post_path));
echo "Bumping post placeholder " . $post_path . "\n";
$qry = "
INSERT INTO posts
(post_path, post_path_depth, post_metadata, post_content)
VALUES
( ?, ?, ?, ?) AS new
ON DUPLICATE KEY UPDATE post_path=new.post_path;";
$this->_exec($qry, "siss",
$post_path,
$path_depth,
json_encode($post_metadata),
'');
}
function create_post_entry($post_path, $post_metadata, $post_content) {
$post_path = chop($post_path, '/');
$path_depth = substr_count($post_path, "/");
$this->ensure_directory(dirname($post_path));
echo "Creating post entry " . $post_path . "\n";
$qry = "
INSERT INTO posts
(post_path, post_path_depth, post_metadata, post_content)
VALUES
( ?, ?, ?, ?) AS new
ON DUPLICATE KEY UPDATE post_metadata=new.post_metadata, post_content=new.post_content;";
$this->_exec($qry, "siss",
$post_path,
$path_depth,
json_encode($post_metadata),
$post_content);
}
function save_markdown_post($post_path, $post_data) {
$frontmatter_post = YamlFrontMatter::parse($post_data);
$post_path = chop($post_path, '/');
$post_content = $frontmatter_post->body();
$post_metadata = $frontmatter_post->matter();
if(basename($post_path) == "README.md") {
$readme_metadata = $frontmatter_post->matter();
$readme_metadata['type'] = $post_metadata['readme_type'] ?? 'directory';
$this->create_post_entry(dirname($post_path), $readme_metadata, '');
$post_metadata['type'] = 'text/markdown';
}
$post_metadata['type'] ??= 'text/markdown';
$this->create_post_entry($post_path, $post_metadata, $post_content);
file_put_contents($this->data_directory . $post_path,
$post_data);
}
function save_file($post_path, $file_path) {
$post_metadata = ["type" => 'file'];
$post_path = chop($post_path, '/');
$this->ensure_post_placeholder($post_path, $post_metadata, '');
copy($file_path, $this->data_directory . $post_path);
}
function handle_upload($post_path, $file_path) {
$ext = pathinfo($post_path, PATHINFO_EXTENSION);
switch($ext) {
case "md":
$this->save_markdown_post($post_path, file_get_contents($file_path));
break;
default:
$this->save_file($post_path, $file_path);
}
}
function get_post_by_path($post_path, $with_subposts = true) {
$qry = "SELECT * FROM posts WHERE post_path = ?";
$post_path = chop($post_path, '/');
$post_data = $this->_exec($qry, "s", $post_path)->fetch_assoc();
$post_data = $this->_prepare_post_data($post_data);
$post_data = $this->_fill_post_descriptors($post_data);
if($with_subposts) {
$post_data['subposts'] = $this->get_subposts_by_path($post_path);
}
return $post_data;
}
function get_subposts_by_path($path) {
global $sql;
$path = chop($path, '/');
$path_depth = substr_count($path, "/");
$qry = "SELECT post_path, post_metadata, post_update_time
FROM posts
WHERE (post_path LIKE CONCAT(?,'/%'))
AND post_path_depth = ?
ORDER BY post_create_time DESC
LIMIT 10";
$post_data = $this->_exec($qry, "si", $path, $path_depth+1)->fetch_all(MYSQLI_ASSOC);
$fn = function($data) {
return $this->_prepare_post_data($data);
};
$post_data = array_map($fn, $post_data);
return $post_data;
}
}
?>