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"]) {
"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']),
"getMemeVotes" => getMemeVotes($endpoint_data['meme_id']),
"deleteVoteMeme" => deleteVoteMeme($endpoint_data['meme_id']),

@ -54,6 +54,9 @@ function loadRouterConfig(): array
'newsarticle' => [
'default_permissions' => 255,
],
'meme' => [
'per_page' => 10
],
'seo' => [
'author' => 'Tím AdlerkaTop',
'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 $memeText The text content of 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.
* @global mysqli $mysqli The database connection object.
*/
function addMeme(string $title, string $memeText, int $imageID): array
{
@ -25,6 +25,28 @@ function addMeme(string $title, string $memeText, int $imageID): array
}
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.
*
@ -60,15 +82,13 @@ function renderMeme(int $id, int $authorId, string $title, string $textContent,
$meme_vote_counter_class = 'positive';
$meme_upvote_button_class = ' visual_hover';
$meme_downvote_button_class = '';
}
elseif (($meme_votes['UserVote'] < 0)) {
} elseif (($meme_votes['UserVote'] < 0)) {
$meme_upvote_active = 'line';
$meme_downvote_active = 'fill';
$meme_vote_counter_class = 'negative';
$meme_upvote_button_class = '';
$meme_downvote_button_class = ' visual_hover';
}
else {
} else {
$meme_downvote_active = 'line';
$meme_upvote_active = 'line';
$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);
}
/**
* Generates an HTML representation of a gallery of memes from the database.
* Renders the memes using renderMeme.
* Renders a gallery of memes, optionally filtered by author ID, meme ID, or a keyword.
*
* @global mysqli $mysqli The database connection object.
* @global array $routerConfig Configuration settings including paths to templates.
* @return string Returns the complete HTML content of the meme gallery.
* This function retrieves memes from the database and returns an HTML string representation.
* It supports filtering by author ID, meme ID, or a keyword that is searched in titles and text content.
* 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
{
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');
function renderMemeGallery(?int $offset = null, ?int $authorId = null, ?int $memeId = null, ?string $keyword = null): string {
global $mysqli, $routerConfig;
// Execute the prepared statement
$memeID = 0;
$authorID = 0;
$title = "";
$textContent = "";
$filePath = "";
$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();
// Start building the SQL query
$query = 'SELECT Memes.ID, Memes.Title, Memes.TextContent, Memes.CreatedAt, Memes.AuthorID,
Files.Path, Files.Width, Files.Height, Users.Nickname
FROM Memes
INNER JOIN Users ON Memes.AuthorID = Users.ID
INNER JOIN Files ON Memes.FileID = Files.ID';
$meme_gallery_template = file_get_contents($routerConfig['template_dir'] . 'meme_gallery.html');
$conditions = [];
$params = [];
$types = '';
// Fetch the results
$memes_out = '';
$meme_template = file_get_contents($routerConfig['template_dir'] . "meme.html");
$stmtlist->store_result();
while ($stmtlist->fetch()) {
if (str_starts_with($fileType, 'image')) {
$memes_out .= renderMeme($memeID, $authorID, $title, $textContent, $createdAt, $filePath, $imageWidth, $imageHeight, $userNickname, $meme_template);
// Add conditions based on provided parameters
if ($authorId !== null) {
$conditions[] = 'Memes.AuthorID = ?';
$params[] = $authorId;
$types .= 'i';
}
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
$stmtlist->close();
return $meme_gallery_out;
// Append conditions to the query
if (!empty($conditions)) {
$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.
*
* @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.
* @global mysqli $mysqli The database connection object.
*/
function deleteMeme(int $memeID): array
{
@ -161,13 +199,14 @@ function deleteMeme(int $memeID): array
}
return $out;
}
/**
* 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 $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.
* @global mysqli $mysqli The database connection object.
*/
function voteMeme(int $memeID, int $isUpvote): array
{
@ -185,12 +224,13 @@ function voteMeme(int $memeID, int $isUpvote): array
$memeVoteConn->close();
return $out;
}
/**
* 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.
* @global mysqli $mysqli The database connection object.
* @return array Returns an associative array with the status of the deletion.
* @global mysqli $mysqli The database connection object.
*/
function deleteVoteMeme(int $memeID): array
{
@ -205,13 +245,14 @@ function deleteVoteMeme(int $memeID): array
$memeVoteConn->close();
return $out;
}
/**
* 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)
*
* @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.
* @global mysqli $mysqli The database connection object.
*/
function calculateNetVotes(int $memeID): array
{