Функция поиска по постам

Мне это всё расписывать что-ли? Смотрите в содержание коммита, мне феерически индифферентно
This commit is contained in:
2024-03-07 19:58:39 +03:00
parent 8700a544b9
commit 62b7b68976
24 changed files with 804 additions and 36 deletions

View File

@ -15,6 +15,9 @@ function NTFY_AddNotice (string $text, string $type = "fail") {
case "fail":
$NTFY_NoticesQueue[] = "<div class=\"notification_fail\"><p>$text</p></div>";
break;
case "warning":
$NTFY_NoticesQueue[] = "<div class=\"notification_warning\"><p>$text</p></div>";
break;
case "success":
$NTFY_NoticesQueue[] = "<div class=\"notification_success\"><p>$text</p></div>";
break;

View File

@ -17,16 +17,17 @@ require_once("api/post/index.php");
$totalPostsAmount = Post_GetPostsAmount();
$totalPostsAmount = strval($totalPostsAmount);
$totalPostsAmountLen = strlen($totalPostsAmount);
?>
<div class="visualbox">
<?php
// India stronk 🇮🇳💪
$allNumbers = array();
for ($i = 0; $i < strlen($totalPostsAmount); ++$i)
$allNumbers[] = "<img src=\"front/images/counter/" . $totalPostsAmount[$i] . ".png\">";
while (count($allNumbers) < 7)
while (count($allNumbers) < (7 - $totalPostsAmountLen))
$allNumbers[] = "<img src=\"front/images/counter/0.png\">";
for ($i = 0; $i < $totalPostsAmountLen; ++$i)
$allNumbers[] = "<img src=\"front/images/counter/" . $totalPostsAmount[$i] . ".png\">";
foreach ($allNumbers as $numberImg)
echo $numberImg;
?>

View File

@ -2,5 +2,5 @@
// TODO: picking random meme
?>
<div class="visualbox">
<img style="max-width: 90%; max-height: 240px;" src="test.png">
<img src="test.png">
</div>

View File

@ -47,7 +47,7 @@ require_once("api/user/index.php");
<div>
<form action="." accept-charset="UTF-8" method="get">
<input type="hidden" name="do" value="search_posts">
<input type="text" name="tags" id="tags" value="" size="36" autofocus="autofocus" autocomplete="on"><br>
<input type="text" name="query" value="" size="36" autofocus="autofocus" autocomplete="on"><br>
<input type="submit" value="Search">
<!-- TODO: JS
<input type="button" value="Show random meme" id="random-meme">

View File

@ -44,7 +44,7 @@
</li>
<span>|</span>
<li>
<p><a title="A paginated list of every tag" href="./?do=view_tags">Tags</p></a>
<p><a title="A (not yet) paginated list of every tag" href="./?do=view_tags">Tags</p></a>
</li>
<span>|</span>
<li>

View File

@ -5,6 +5,7 @@
// Includes
require_once("api/post/create.php");
// Markup includes
require_once("front/pages/main_nav.php");
require_once("front/notifications.php");
@ -52,7 +53,7 @@ NTFY_EchoAllNotices();
</div>
<div>
<label for="title">Post title:</label><br>
<textarea placeholder="Lorem ipsum dolor sit amet..." name="title" id="title" style="width: 98%;" rows="2"><?php if (isset($_POST["title"]) && !$_POST["title"]) { echo $_POST["title"]; } ?></textarea>
<textarea placeholder="Lorem ipsum dolor sit amet..." name="title" id="title" style="width: 98%;" rows="2"><?php if (isset($_POST["title"]) && $_POST["title"]) { echo $_POST["title"]; } ?></textarea>
</div>
<div>
<input type="submit" value="Submit">

View File

@ -0,0 +1,58 @@
<?php
// Create entry in posts search list
// Includes
require_once("api/user/index.php");
// Create entry from post info
function GenPostEntry (array $data): string {
$userReqResp = User_GetInfoByID($data["author_id"]);
if ($userReqResp->IsError())
$userLogin = strval($data["author_id"]);
else
$userLogin = $userReqResp->GetData()["login"];
if (!is_string($data["created_at"]))
$timestamp = strval($data["created_at"]);
else
$timestamp = $data["created_at"];
$placeholderString = "ID: " . strval($data["id"]);
$placeholderString .= " | AUTHOR: $userLogin";
$placeholderString .= " | TIMESTAMP: $timestamp";
$placeholderString .= " | TAGS: " . $data["tags"];
$result = "<a class=\"entry\">\n"; // TODO: href
$result .= "<img src=\"";
if ($data["preview_path"])
$result .= $data["preview_path"];
else
$result .= $data["pic_path"];
$result .= "\" alt=\"$placeholderString\" title=\"$placeholderString\">\n";
$result .= "<div class=\"stats\">\n";
$result .= "<p><b>+</b>" . strval($data["votes_up"]);
$result .= " <b>-</b>" . strval($data["votes_down"]);
$result .= " <b>V</b> " . strval($data["views"]);
/*
if ($data["comments_enabled"]) {
$result .= " <b>C</b> " . null; // TODO: resolve comment section by id and count comments amount
}
*/
$result .= "</p>\n";
$result .= "</div>\n";
$result .= "</a>\n";
return $result;
}
?>

View File

@ -0,0 +1,180 @@
<?php
// Search posts by filter
// Includes
// API
require_once("api/_input_checks.php");
require_once("api/post/find.php");
// Front pieces
require_once("front/pages/search_posts/gen_post_entry.php");
// Markup includes
require_once("front/pages/main_nav.php");
require_once("front/notifications.php");
// Needed config values
$cfgMaxPostsPerRequest = $Config["max_posts_per_request"];
// Checking request fields
// Checking amount of posts per page
$postsPerPage = null;
if (isset($_REQUEST["amount"])) {
$postsPerPage = $_REQUEST["amount"];
if (
(!InpChk_IsValidInt32($postsPerPage))
|| ($postsPerPage > $cfgMaxPostsPerRequest)
|| ($postsPerPage < 1)
) {
$postsPerPage = $_REQUEST["amount"] = $cfgMaxPostsPerRequest; // TODO: user defaults
NTFY_AddNotice("Wrong posts \"amount\" value in query, was normalized to $postsPerPage.", "warning");
} else {
$_REQUEST["amount"] = intval($_REQUEST["amount"]);
}
} else {
$postsPerPage = $cfgMaxPostsPerRequest; // TODO: user defaults
}
// Checking posts offset
$currentOffset = null;
if (!empty($_REQUEST["offset"])) {
$currentOffset = $_REQUEST["offset"];
if (
(!InpChk_IsValidInt32($currentOffset))
|| $currentOffset < 0
) {
$currentOffset = $_REQUEST["offset"] = 0;
NTFY_AddNotice("Wrong \"offset\" value in query, was defaulted to $currentOffset.", "warning");
} else {
$_REQUEST["offset"] = intval($_REQUEST["offset"]);
}
} else {
$currentOffset = 0;
}
$currentOffsetIsCorrect = ($currentOffset === 0) || (!($currentOffset % $postsPerPage));
// Processing request
$result = Post_GetMatchingPosts_Method($_REQUEST);
$requestedPostsResult = null;
if ($result->IsError()) // Something happened
NTFY_AddNotice("Failed to fetch posts! Reason:<br>" . $result->GetError(), "fail");
else
$requestedPostsResult = $result->GetData();
// Checking offset again NOTICE: doshirak-code
if ($requestedPostsResult && $currentOffset > $requestedPostsResult["total_amount"]) {
$currentOffset = $_REQUEST["offset"] = 0;
NTFY_AddNotice("Wrong \"offset\" value in query!", "fail");
$requestedPostsResult = null;
}
NTFY_EchoAllNotices();
?>
<div class="visualbox">
<menu class="paginator">
<?php
// TODO: move to function, remove trashy dependencies and dublicate at bottom of posts list
if ($requestedPostsResult) {
// Calculating current page based on offset NOTICE: counting starts from zero, so user will see $currentPage + 1
$currentPage = intdiv($currentOffset, $postsPerPage);
if (!$currentOffsetIsCorrect)
++$currentPage;
// Calculating maximum page based on total posts amount
$totalPagesAmount = intdiv($requestedPostsResult["total_amount"], $postsPerPage);
if ($requestedPostsResult["total_amount"] % $postsPerPage)
++$totalPagesAmount;
} else {
$currentPage = 0;
$totalPagesAmount = 0;
}
$tempGETArr = $_GET;
$tempGETArr["offset"] = $currentOffset; // Starting offset
$startingPage = $currentPage; // And page, yeah
// Calculating starting offset
for ($i = 0; $i < 2 && $tempGETArr["offset"] > 0; ++$i) {
$tempGETArr["offset"] -= $postsPerPage;
--$startingPage;
}
// If list of posts does not begin from first
if ($currentOffset > 0) { // Then adding link to first and previous page
$secondTempGETArr = $_GET;
$secondTempGETArr["offset"] = 0;
// First page
echo "<li><a title=\"First page\" href=\"./?" . http_build_query($secondTempGETArr) . "\">First</a></li>\n";
// Previous page
if ($currentOffsetIsCorrect) {
$secondTempGETArr["offset"] = $currentOffset - $postsPerPage;
echo "<li><a title=\"Previous page\" href=\"./?" . http_build_query($secondTempGETArr) . "\">&lt;</a></li>\n";
}
unset($secondTempGETArr);
echo "<li><p>...</p></li>";
}
// Showing pages
$i = $startingPage;
$endingPage = $startingPage + 5; // Unaccurate naming, tbh, but who cares
for (; $i < $endingPage && $i < $totalPagesAmount; ++$i) {
echo "<li>";
if ($tempGETArr["offset"] === $currentOffset)
echo "<b>";
echo "<a href=\"./?" . http_build_query($tempGETArr) . "\">" . strval($i + 1) ."</a>";
if ($tempGETArr["offset"] === $currentOffset)
echo "</b>";
echo "</li>\n";
$tempGETArr["offset"] += $postsPerPage;
}
// If we have even MORE posts!
if ($currentPage < ($totalPagesAmount - 1)) { // Then adding link to last and next page
echo "<li><p>...</p></li>";
$secondTempGETArr = $_GET;
// Next page
if ($currentOffsetIsCorrect) {
$secondTempGETArr["offset"] = $currentOffset + $postsPerPage;
echo "<li><a title=\"Next page\" href=\"./?" . http_build_query($secondTempGETArr) . "\">&gt;</a></li>\n";
}
// Last page
$secondTempGETArr["offset"] = ($totalPagesAmount - 1) * $postsPerPage;
echo "<li><a title=\"Last page\" href=\"./?" . http_build_query($secondTempGETArr) . "\">Last</a></li>\n";
}
?>
</menu>
<div class="postsearchcolumn">
<h3 style="margin-top: 4px; margin-bottom: 4px;">Search</h3>
<form class="basicform" action="." accept-charset="UTF-8" method="get">
<input type="hidden" name="do" value="search_posts">
<input type="text" name="query" autocomplete="on" <?php if (isset($_REQUEST["query"])) { echo "value=\"" . $_REQUEST["query"] . "\""; } ?>>
<input type="submit" value="Search">
</form>
</div>
<div class="postlist">
<?php
if ($requestedPostsResult && $requestedPostsResult["total_amount"]) {
foreach ($requestedPostsResult["data"] as $postData)
echo GenPostEntry($postData);
} else {
echo "<h2 style=\"color: gray; font-style: italic;\">Nothing found!</h2>";
}
// TODO: pages
?>
</div>
</div>

View File

@ -0,0 +1,39 @@
<?php
// Approved tags list
// Includes
// API
require_once("api/_config.php");
require_once("api/user/index.php");
// Front pieces
require_once("front/pages/main_nav.php");
require_once("front/notifications.php");
// Process request
if (isset($_REQUEST["id"])) {
$result = User_GetInfoByID_Method($_REQUEST);
if ($result->IsError())
NTFY_AddNotice("Failed to fetch posts! Reason:<br>" . $result->GetError());
} else {
header("Location: .");
exit();
}
NTFY_EchoAllNotices();
?>
<div class="visualbox">
<?php
if (!$result->IsError()) {
echo "<h2>" . $result["login"] . "'s personal page</h2>";
// TODO
}
?>
</div>

View File

@ -77,6 +77,19 @@ div.notification_fail p {
color: red;
}
div.notification_warning {
margin: 10px;
padding: 10px;
border-radius: 5px;
box-shadow: 0 0 5px orange;
text-shadow: 0 0 2px black, 0 0 6px black;
backdrop-filter: blur(6px);
background-color: #fa03;
}
div.notification_warning p {
color: orange;
}
div.notification_success {
margin: 10px;
padding: 10px;

View File

@ -54,3 +54,12 @@ div.nav a.useraccount {
color: orange;
text-decoration: underline;
}
/* Index random meme box */
div.visualbox img {
max-width: 90%;
max-height: 240px;
}

View File

@ -92,7 +92,7 @@ td {
/* Other */
/* Basic form form login and registration */
/* Basic form for login and registration */
form.basicform div {
margin-bottom: 14px;
@ -117,3 +117,103 @@ div.loginmisc p {
font-style: italic;
font-size: 80%;
}
/* Paginator */
menu.paginator {
text-align: center;
margin: 2px auto;
}
menu.paginator li {
display: inline-block;
margin: 0 8px;
}
menu.paginator li a {
text-decoration: none;
}
menu.paginator li p {
color: gray;
}
/* Post search column styling */
div.postsearchcolumn {
display: block;
float: left;
width: 15em;
}
div.postsearchcolumn form input[type="text"] {
width: 10em;
border-top-right-radius: 0px;
border-bottom-right-radius: 0px;
border-right: 1px solid gray;
display: inline-block;
}
div.postsearchcolumn form input[type="submit"] {
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
border-left: 1px solid gray;
display: inline-block;
margin-left: -4px;
}
/* Posts list styling */
div.postlist {
display: block;
margin-left: 15em;
overflow: visible;
padding-left: 1em;
text-align: center;
}
div.postlist a.entry {
display: inline-block;
text-align: center;
vertical-align: text-top;
width: 150px;
max-width: 150px; /* TODO: must be relative or at least tunable through profile settings */
background-color: #00904910;
border-radius: 2px;
box-shadow: 0 0 5px #0006;
transition: all 0.2s;
margin: 5px;
text-decoration: none;
font-size: 10px;
text-shadow: none;
}
div.postlist a.entry:hover {
background-color: #00904920;
box-shadow: 0 0 8px #000a;
scale: 1.015;
}
div.postlist a.entry img {
object-fit: contain;
max-width: 150px;
max-height: 150px; /* TODO: same as stated higher */
}
div.postlist a.entry div.stats {
width: 100%;
border-top: 1px solid #00c07c20;
}
div.postlist a.entry div.stats p {
color: #00c07c;
font-size: 12px;
text-shadow: none;
margin: 3px 0;
transition: all 0.2s;
}
div.postlist a.entry:hover div.stats p {
color: #49f49f;
}