raw = mysqli_connect(getenv('MYSQL_HOST'), getenv('MYSQL_USER'), getenv('MYSQL_PASSWORD'), getenv('MYSQL_DATABASE'), getenv('MYSQL_PORT')); } else { $this->raw = mysqli_connect($db_params['MYSQL_HOST'], $db_params['MYSQL_USER'], $db_params['MYSQL_PASSWORD'], $db_params['MYSQL_DATABASE'], $db_params['MYSQL_PORT']); } } catch (\Throwable $th) { echo 'Connection failed
'; echo 'Error number: ' . mysqli_connect_errno() . '
'; echo 'Error message: ' . mysqli_connect_error() . '
'; die(); //throw $th; } } function _sanitize_path($post_path) { $post_path = chop($post_path, '/'); if($post_path == "") { return ""; } if(!preg_match('/^(?:\/[\w-]+)+(?:\.[\w-]+)*$/', $post_path)) { echo "Post path match against " . $post_path . " failed!"; die(); } return $post_path; } function _exec($qery, $argtypes, ...$args) { $stmt = $this->raw->prepare($qery); $stmt->bind_param($argtypes, ...$args); $stmt->execute(); return $stmt->get_result(); } function _normalize_post_data($post_data) { if($post_data == null) { return [ "found" => false ]; } $post_data["found"] = true; $post_data['post_metadata'] = json_decode($post_data["post_metadata"], true) ?? []; $post_data["post_content"] ??= ''; return $post_data; } function bump_post($post_path, $post_metadata = [], $create_dirs = true) { $post_path = $this->_sanitize_path($post_path); $path_depth = substr_count($post_path, "/"); if($create_dirs) { $this->make_post_directory(dirname($post_path)); } $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 make_post_directory($directory) { $json_metadata = ["type" => 'directory']; while(strlen($directory) > 1) { try { $this->bump_post($directory, $json_metadata, false); } catch(Exception $e) { } $directory = dirname($directory); } } function update_or_create_post($post_path, $post_metadata, $post_content) { $post_path = $this->_sanitize_path($post_path); $path_depth = substr_count($post_path, "/"); $this->make_post_directory(dirname($post_path)); $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 get_settings_for_path($post_path) { $post_path = $this->_sanitize_path($post_path); $qry = " WITH RECURSIVE settings_data (post_path, post_depth, json_settings) AS ( SELECT post_path, post_path_depth, post_metadata FROM posts WHERE post_path = ? UNION ALL SELECT posts.post_path, posts.post_path_depth, posts.post_metadata FROM posts, settings_data WHERE posts.post_path = SUBSTRING_INDEX(settings_data.post_path, '/', settings_data.post_depth) AND posts.post_path_depth = settings_data.post_depth - 1 ) SELECT post_depth, json_settings FROM settings_data ORDER BY post_depth ASC; "; $out_settings = []; $settings_list = $this->_exec($qry, "s", $post_path)->fetch_all(MYSQLI_ASSOC); foreach($settings_list AS $setting) { $setting = json_decode($setting['json_settings'], true); if(!isset($setting) || !isset($setting['settings'])) { continue; } $out_settings = array_merge($out_settings, $setting['settings']); } return $out_settings; } function get_post_by_path($post_path, $with_subposts = false, $with_settings = true) { $qry = "SELECT * FROM posts WHERE post_path = ?"; $post_path = $this->_sanitize_path($post_path); $post_data = $this->_exec($qry, "s", $post_path)->fetch_assoc(); $post_data = $this->_normalize_post_data($post_data); $post_data['post_path'] = $post_path; if(!$post_data['found']) { return $post_data; } if($with_subposts) { $post_data['subposts'] = $this->get_subposts_by_path($post_path); } if($with_settings) { $post_data['settings'] = $this->get_settings_for_path($post_path); } return $post_data; } function get_subposts_by_path($path) { global $sql; $path = $this->_sanitize_path($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->_normalize_post_data($data); }; $post_data = array_map($fn, $post_data); return $post_data; } } ?>