feat: add post search function

This commit is contained in:
David Bailey 2024-01-22 16:32:38 +01:00
parent add698651e
commit 12d3838eae
2 changed files with 100 additions and 9 deletions

View file

@ -69,6 +69,14 @@ class MySQLAdapter {
return $post_data;
}
function _normalize_post_array($post_data) {
$post_data ??= [];
return array_map(function($post) {
return $this->_normalize_post_data($post);
}, $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, "/");
@ -212,6 +220,86 @@ class MySQLAdapter {
", "ss", $this->SITE_CONFIG['HTTP_HOST'], $post_path . "%");
}
function escape_tag($tag) {
return preg_replace_callback('/[\WZ]/', function($match) {
return "Z" . ord($match[0]);
}, strtolower($tag));
}
function escape_search_tag($tag) {
preg_match("/^([\+\-]?)(.*?)(\*?)$/", $tag, $matches);
if(!isset($matches[1])) {
echo "Problem with tag!";
var_dump($tag);
}
return $matches[1] . $this->escape_tag($matches[2]) . $matches[3];
}
function update_post_search_data($post_path, $post_tags) {
$post_tags []= "path:" . $post_path;
$post_tags []= "host:" . $this->SITE_CONFIG['HTTP_HOST'];
$post_tags = array_unique($post_tags);
$post_tags = array_map(function($val) {
return $this->escape_tag($val);
}, $post_tags);
asort($post_tags);
$post_tags = join(' ', $post_tags);
$qry = "
INSERT INTO posts
( host, post_path, post_tags )
VALUES
( ?, ?, ? ) AS new
ON DUPLICATE KEY
UPDATE post_tags=new.post_tags;
";
$this->_exec($qry, "sss",
$this->SITE_CONFIG['HTTP_HOST'], $post_path, $post_tags);
}
function perform_post_search($taglist, $order = null, $limit = 20, $page = 0) {
$allowed_ordering = [
"post_create_time"
];
$qry = "
SELECT post_path, post_metadata
FROM posts
WHERE MATCH(post_tags) AGAINST (? IN BOOLEAN MODE)
";
if(!is_array($taglist)) {
$taglist = explode(' ', $taglist);
}
$taglist []= '+host:' . $this->SITE_CONFIG['HTTP_HOST'];
$taglist = array_unique($taglist);
$taglist = array_map(function($key) {
return $this->escape_search_tag($key);
}, $taglist);
$taglist = implode(' ', $taglist);
if(isset($order) and in_array($order, $allowed_ordering)) {
$qry = $qry . " ORDER BY " . $order;
}
$qry = $qry . " LIMIT ? OFFSET ?";
$search_results = $this->_exec($qry, "sii", $taglist, $limit, $limit * $page)->fetch_all(MYSQLI_ASSOC);
$search_results = [
"query_string" => $taglist,
"results" => $this->_normalize_post_array($search_results)
];
return $search_results;
}
function update_or_create_post($post_path, $post_metadata, $post_content) {
$post_path = $this->_sanitize_path($post_path);
$path_depth = substr_count($post_path, "/");
@ -236,6 +324,8 @@ class MySQLAdapter {
$path_depth,
json_encode($post_metadata),
$post_content);
$this->update_post_search_data($post_path, $post_metadata['tags'] ?? []);
}
function get_settings_for_path($post_path) {
@ -294,9 +384,7 @@ class MySQLAdapter {
$post_data = $this->_exec($qry, "ss", $post_path, $this->SITE_CONFIG['HTTP_HOST'])->fetch_assoc();
if(!isset($post_data)) {
$post_data = ['found' => false];
}
$post_data ??= ['found' => false];
$post_data['post_path'] = $post_path;
$post_data = $this->_normalize_post_data($post_data);
@ -334,11 +422,7 @@ class MySQLAdapter {
$post_data = $this->_exec($qry, "ssi", $this->SITE_CONFIG['HTTP_HOST'],
$path, $path_depth+1)->fetch_all(MYSQLI_ASSOC);
$fn = function($data) {
return $this->_normalize_post_data($data);
};
$post_data = array_map($fn, $post_data);
$post_data = $this->_normalize_post_array($post_data);
return $post_data;
}

View file

@ -25,7 +25,10 @@ $adapter = new PostHandler($SITE_CONFIG);
$loader = new \Twig\Loader\FilesystemLoader(['./templates', './user_content']);
$twig = new \Twig\Environment($loader,['cache' => 'twig_cache']);
$twig = new \Twig\Environment($loader,[
'debug' => true,
'cache' => 'twig_cache'
]);
$twig->addExtension(new Twig\Extra\Markdown\MarkdownExtension());
use Twig\Extra\Markdown\DefaultMarkdown;
@ -239,6 +242,10 @@ function generate_website($SURI) {
} elseif($SURI == '/api/upload') {
echo $twig->render('upload.html');
} elseif($SURI == '/api/search') {
header('Content-Type: application/json');
echo json_encode($adapter->perform_post_search($_GET['search_query']));
}
} elseif(preg_match('/^\/feed(?:\/(rss|atom)(.*))?$/', $SURI, $match)) {
$feed = $adapter->get_laminas_feed($match[2] ?? '/', $match[1] ?? 'rss');