Test meme filtering

This commit is contained in:
Bruno Rybársky 2024-05-01 17:23:57 +02:00
parent 6fc026f70b
commit 4556b3c349
3 changed files with 94 additions and 50 deletions

@ -7,7 +7,7 @@ function endpoint($endpoint_data): array
return match ($endpoint_data["action"]) { return match ($endpoint_data["action"]) {
"addMeme" => addMeme($endpoint_data['meme_title'], $endpoint_data['meme_text'], $endpoint_data['meme_image_id']), "addMeme" => addMeme($endpoint_data['meme_title'], $endpoint_data['meme_text'], $endpoint_data['meme_image_id']),
"renderGallery" => renderMemeGallery(), "renderGallery" => renderMemeGallery($endpoint_data['offset'], $endpoint_data['meme_author'], $endpoint_data['meme_id'], $endpoint_data['meme_keyword']),
"deleteMeme" => deleteMeme($endpoint_data['meme_id']), "deleteMeme" => deleteMeme($endpoint_data['meme_id']),
"getMemeVotes" => getMemeVotes($endpoint_data['meme_id']), "getMemeVotes" => getMemeVotes($endpoint_data['meme_id']),
"deleteVoteMeme" => deleteVoteMeme($endpoint_data['meme_id']), "deleteVoteMeme" => deleteVoteMeme($endpoint_data['meme_id']),

@ -54,6 +54,9 @@ function loadRouterConfig(): array
'newsarticle' => [ 'newsarticle' => [
'default_permissions' => 255, 'default_permissions' => 255,
], ],
'meme' => [
'per_page' => 10
],
'seo' => [ 'seo' => [
'author' => 'Tím AdlerkaTop', 'author' => 'Tím AdlerkaTop',
'description' => 'Toto je neoficiánla študentská stránka pre Adlerku, kde môžete nájsť plno zaujímavostí.', 'description' => 'Toto je neoficiánla študentská stránka pre Adlerku, kde môžete nájsť plno zaujímavostí.',

@ -8,8 +8,8 @@ require_once "lib/account.php";
* @param string $title The title of the meme. * @param string $title The title of the meme.
* @param string $memeText The text content of the meme. * @param string $memeText The text content of the meme.
* @param int $imageID The ID of the image associated with the meme. * @param int $imageID The ID of the image associated with the meme.
* @global mysqli $mysqli The database connection object.
* @return array Returns an associative array with the operation status and a message. * @return array Returns an associative array with the operation status and a message.
* @global mysqli $mysqli The database connection object.
*/ */
function addMeme(string $title, string $memeText, int $imageID): array function addMeme(string $title, string $memeText, int $imageID): array
{ {
@ -25,6 +25,28 @@ function addMeme(string $title, string $memeText, int $imageID): array
} }
return $output; return $output;
} }
function executeAndRenderMemes(mysqli_stmt $stmt): string {
global $routerConfig;
$stmt->execute();
$stmt->bind_result($memeID, $title, $textContent, $createdAt, $authorID, $filePath, $imageWidth, $imageHeight, $userNickname);
$memes_out = '';
$meme_template = file_get_contents($routerConfig['template_dir'] . "meme.html");
$meme_gallery_template = file_get_contents($routerConfig['template_dir'] . 'meme_gallery.html');
while ($stmt->fetch()) {
$memes_out .= renderMeme($memeID, $authorID, $title, $textContent, $createdAt, $filePath, $imageWidth, $imageHeight, $userNickname, $meme_template);
}
$meme_add = isLoggedIn() ? file_get_contents($routerConfig['template_dir'] . 'meme_add.html') : '';
$meme_gallery_out = str_replace('__TEMPLATE_MEMES_HERE__', $memes_out, $meme_gallery_template);
$meme_gallery_out = str_replace('__TEMPLATE_MEME_ADD__', $meme_add, $meme_gallery_out);
$stmt->close();
return $meme_gallery_out;
}
/** /**
* Renders a meme into HTML based on provided data and a template. * Renders a meme into HTML based on provided data and a template.
* *
@ -54,21 +76,19 @@ function renderMeme(int $id, int $authorId, string $title, string $textContent,
$meme_votes = calculateNetVotes($id); $meme_votes = calculateNetVotes($id);
$meme_net_votes = $meme_votes['NetVotes']; $meme_net_votes = $meme_votes['NetVotes'];
if ($meme_votes['UserVote'] > 0){ if ($meme_votes['UserVote'] > 0) {
$meme_upvote_active = 'fill'; $meme_upvote_active = 'fill';
$meme_downvote_active = 'line'; $meme_downvote_active = 'line';
$meme_vote_counter_class = 'positive'; $meme_vote_counter_class = 'positive';
$meme_upvote_button_class = ' visual_hover'; $meme_upvote_button_class = ' visual_hover';
$meme_downvote_button_class = ''; $meme_downvote_button_class = '';
} } elseif (($meme_votes['UserVote'] < 0)) {
elseif (($meme_votes['UserVote'] < 0)) {
$meme_upvote_active = 'line'; $meme_upvote_active = 'line';
$meme_downvote_active = 'fill'; $meme_downvote_active = 'fill';
$meme_vote_counter_class = 'negative'; $meme_vote_counter_class = 'negative';
$meme_upvote_button_class = ''; $meme_upvote_button_class = '';
$meme_downvote_button_class = ' visual_hover'; $meme_downvote_button_class = ' visual_hover';
} } else {
else {
$meme_downvote_active = 'line'; $meme_downvote_active = 'line';
$meme_upvote_active = 'line'; $meme_upvote_active = 'line';
$meme_vote_counter_class = 'neutral'; $meme_vote_counter_class = 'neutral';
@ -86,60 +106,78 @@ function renderMeme(int $id, int $authorId, string $title, string $textContent,
return str_replace('__TEMPLATE_MEME_TEXT__', htmlspecialchars($textContent), $meme_out); return str_replace('__TEMPLATE_MEME_TEXT__', htmlspecialchars($textContent), $meme_out);
} }
/** /**
* Generates an HTML representation of a gallery of memes from the database. * Renders a gallery of memes, optionally filtered by author ID, meme ID, or a keyword.
* Renders the memes using renderMeme.
* *
* @global mysqli $mysqli The database connection object. * This function retrieves memes from the database and returns an HTML string representation.
* @global array $routerConfig Configuration settings including paths to templates. * It supports filtering by author ID, meme ID, or a keyword that is searched in titles and text content.
* @return string Returns the complete HTML content of the meme gallery. * It also supports pagination through an offset parameter.
*
* @param int|null $offset Pagination offset, used to calculate the starting point for records to return.
* @param int|null $authorId Optional author ID for filtering memes by a specific author.
* @param int|null $memeId Optional meme ID for rendering a single meme.
* @param string|null $keyword Optional keyword for full-text search in meme titles and content.
* @return string Returns the complete HTML content of the meme gallery, optionally filtered.
*/ */
function renderMemeGallery(): string function renderMemeGallery(?int $offset = null, ?int $authorId = null, ?int $memeId = null, ?string $keyword = null): string {
{ global $mysqli, $routerConfig;
global $mysqli;
global $routerConfig;
$stmtlist = $mysqli->prepare('SELECT Memes.ID, Memes.Title, Memes.TextContent, Memes.CreatedAt, Memes.AuthorID, Files.Path, Files.Width, Files.Height, Files.Type, Users.Nickname FROM Memes INNER JOIN Users ON Memes.AuthorID = Users.ID INNER JOIN Files ON Memes.FileID = Files.ID');
// Execute the prepared statement // Start building the SQL query
$memeID = 0; $query = 'SELECT Memes.ID, Memes.Title, Memes.TextContent, Memes.CreatedAt, Memes.AuthorID,
$authorID = 0; Files.Path, Files.Width, Files.Height, Users.Nickname
$title = ""; FROM Memes
$textContent = ""; INNER JOIN Users ON Memes.AuthorID = Users.ID
$filePath = ""; INNER JOIN Files ON Memes.FileID = Files.ID';
$fileType = "";
$userNickname = "";
$createdAt = "";
$imageWidth = 0;
$imageHeight = 0;
// Bind the result variables
$stmtlist->bind_result($memeID, $title, $textContent, $createdAt, $authorID, $filePath, $imageWidth, $imageHeight, $fileType, $userNickname);
$stmtlist->execute();
$meme_gallery_template = file_get_contents($routerConfig['template_dir'] . 'meme_gallery.html'); $conditions = [];
$params = [];
$types = '';
// Fetch the results // Add conditions based on provided parameters
$memes_out = ''; if ($authorId !== null) {
$meme_template = file_get_contents($routerConfig['template_dir'] . "meme.html"); $conditions[] = 'Memes.AuthorID = ?';
$stmtlist->store_result(); $params[] = $authorId;
while ($stmtlist->fetch()) { $types .= 'i';
if (str_starts_with($fileType, 'image')) { }
$memes_out .= renderMeme($memeID, $authorID, $title, $textContent, $createdAt, $filePath, $imageWidth, $imageHeight, $userNickname, $meme_template); if ($memeId !== null) {
} $conditions[] = 'Memes.ID = ?';
$params[] = $memeId;
$types .= 'i';
}
if ($keyword !== null) {
$conditions[] = '(Memes.Title LIKE CONCAT("%", ?, "%") OR Memes.TextContent LIKE CONCAT("%", ?, "%"))';
$params[] = $keyword;
$params[] = $keyword;
$types .= 'ss';
} }
$meme_add = isLoggedIn() ? file_get_contents($routerConfig['template_dir'] . 'meme_add.html') : '';
$meme_gallery_out = str_replace('__TEMPLATE_MEMES_HERE__', $memes_out, $meme_gallery_template);
$meme_gallery_out = str_replace('__TEMPLATE_MEME_ADD__', $meme_add, $meme_gallery_out);
// Close the statement // Append conditions to the query
$stmtlist->close(); if (!empty($conditions)) {
return $meme_gallery_out; $query .= ' WHERE ' . join(' AND ', $conditions);
}
if($offset == null) {
$offset = 0;
}
// Add pagination and limit
$query .= ' LIMIT ? OFFSET ?';
$params[] = $routerConfig['meme']['per_page'];
$params[] = $routerConfig['meme']['per_page'] * $offset;
$types .= 'ii';
$stmt = $mysqli->prepare($query);
$stmt->bind_param($types, ...$params);
return executeAndRenderMemes($stmt);
} }
/** /**
* Deletes a meme from the database if the current user has the right permissions. * Deletes a meme from the database if the current user has the right permissions.
* *
* @param int $memeID The ID of the meme to delete. * @param int $memeID The ID of the meme to delete.
* @global mysqli $mysqli The database connection object.
* @return array Returns an associative array with the status of the operation. * @return array Returns an associative array with the status of the operation.
* @global mysqli $mysqli The database connection object.
*/ */
function deleteMeme(int $memeID): array function deleteMeme(int $memeID): array
{ {
@ -161,13 +199,14 @@ function deleteMeme(int $memeID): array
} }
return $out; return $out;
} }
/** /**
* Records or updates a vote on a meme by the current user. * Records or updates a vote on a meme by the current user.
* *
* @param int $memeID The ID of the meme to be voted on. * @param int $memeID The ID of the meme to be voted on.
* @param int $isUpvote Indicates whether the vote is an upvote (1) or downvote (0). * @param int $isUpvote Indicates whether the vote is an upvote (1) or downvote (0).
* @global mysqli $mysqli The database connection object.
* @return array Returns an associative array with the status of the vote operation. * @return array Returns an associative array with the status of the vote operation.
* @global mysqli $mysqli The database connection object.
*/ */
function voteMeme(int $memeID, int $isUpvote): array function voteMeme(int $memeID, int $isUpvote): array
{ {
@ -185,12 +224,13 @@ function voteMeme(int $memeID, int $isUpvote): array
$memeVoteConn->close(); $memeVoteConn->close();
return $out; return $out;
} }
/** /**
* Deletes a vote previously made by the current user on a meme. * Deletes a vote previously made by the current user on a meme.
* *
* @param int $memeID The ID of the meme whose vote is to be deleted. * @param int $memeID The ID of the meme whose vote is to be deleted.
* @global mysqli $mysqli The database connection object.
* @return array Returns an associative array with the status of the deletion. * @return array Returns an associative array with the status of the deletion.
* @global mysqli $mysqli The database connection object.
*/ */
function deleteVoteMeme(int $memeID): array function deleteVoteMeme(int $memeID): array
{ {
@ -205,13 +245,14 @@ function deleteVoteMeme(int $memeID): array
$memeVoteConn->close(); $memeVoteConn->close();
return $out; return $out;
} }
/** /**
* Calculates the net votes for a meme and determines if the current user has voted on it. * Calculates the net votes for a meme and determines if the current user has voted on it.
* The array has both the net votes and the user vote(0 when the user hasn't voted) * The array has both the net votes and the user vote(0 when the user hasn't voted)
* *
* @param int $memeID The ID of the meme for which votes are being calculated. * @param int $memeID The ID of the meme for which votes are being calculated.
* @global mysqli $mysqli The database connection object.
* @return array Returns an array with net votes and the user's vote status. * @return array Returns an array with net votes and the user's vote status.
* @global mysqli $mysqli The database connection object.
*/ */
function calculateNetVotes(int $memeID): array function calculateNetVotes(int $memeID): array
{ {