forked from Adleraci/adlerka.top
Add PHPDocs generated by ChatGPT,
add additional clarification to some functions, add addNewsComment function and API, currently untested and not implemented in the client, fix a bunch of stuff that PHPStorm pointed out
This commit is contained in:
parent
6e7df7f034
commit
1c9f5cf3c0
@ -9,7 +9,7 @@ let config =
|
||||
|
||||
function isLoggedIn() {
|
||||
"use strict";
|
||||
return UserInfo.Email && 0 < UserInfo.Email.length;
|
||||
return UserInfo.Email && UserInfo.Email.length > 0;
|
||||
}
|
||||
|
||||
async function handleResponse(data, successMessage, failureMessage) {
|
||||
@ -19,7 +19,7 @@ async function handleResponse(data, successMessage, failureMessage) {
|
||||
const statusMessage = document.createElement("div");
|
||||
statusMessage.classList.add("status-message");
|
||||
|
||||
if ('Success' === data.Status) {
|
||||
if (data.Status === 'Success') {
|
||||
statusMessage.innerText = successMessage;
|
||||
statusMessage.classList.add("success");
|
||||
} else {
|
||||
@ -104,10 +104,10 @@ async function displayList(data, elementId, deleteFunction) {
|
||||
headerRow.appendChild(th);
|
||||
}
|
||||
|
||||
if ("function" === typeof deleteFunction) {
|
||||
if (typeof deleteFunction === "function") {
|
||||
const th = document.createElement("th");
|
||||
let deleteBtn = document.createElement('i');
|
||||
deleteBtn.classList = ["ri-delete-bin-line"];
|
||||
deleteBtn.classList.add("ri-delete-bin-line");
|
||||
th.appendChild(deleteBtn);
|
||||
headerRow.appendChild(th);
|
||||
}
|
||||
@ -119,7 +119,7 @@ async function displayList(data, elementId, deleteFunction) {
|
||||
td.appendChild(document.createTextNode(line[key]));
|
||||
dataRow.appendChild(td);
|
||||
}
|
||||
if ("function" === typeof deleteFunction) {
|
||||
if (typeof deleteFunction === "function") {
|
||||
const td = document.createElement("td");
|
||||
const deleteButton = document.createElement('button');
|
||||
deleteButton.innerHTML = "<i class='ri-delete-bin-line'></i>";
|
||||
@ -234,13 +234,13 @@ async function articleInit() {
|
||||
let articleContainerElement = document.getElementById("articlecreatecontainer");
|
||||
let articleCreateOpenElement = document.getElementById("articlecreateopen");
|
||||
articleContainerElement.addEventListener("keyup", function (ev) {
|
||||
if ("Escape" === ev.key) {
|
||||
if (ev.key === "Escape") {
|
||||
togglearticlecreate();
|
||||
}
|
||||
});
|
||||
PageIntervals.push(setInterval(renderarticles, config.articleRefresh));
|
||||
document.getElementById("articleprivilegeinput").setAttribute("max", UserInfo.Privileges);
|
||||
if (2 > UserInfo.Privileges) {
|
||||
if (UserInfo.Privileges < 2) {
|
||||
articleContainerElement.style.display = "none";
|
||||
articleCreateOpenElement.style.display = "none";
|
||||
} else {
|
||||
@ -258,7 +258,7 @@ async function onPageLoad() {
|
||||
clearInterval(interval);
|
||||
}
|
||||
|
||||
if ("home" === currentSite && "settings" === currentPage) {
|
||||
if (currentSite === "home" && currentPage === "settings") {
|
||||
if (document.getElementById("user-settings")) {
|
||||
await populateUserInfoFields(UserInfo);
|
||||
}
|
||||
@ -267,16 +267,16 @@ async function onPageLoad() {
|
||||
await listUsers(true);
|
||||
}
|
||||
}
|
||||
if ("account" === currentSite && "index" === currentPage && isLoggedIn()) {
|
||||
if (currentSite === "account" && currentPage === "index" && isLoggedIn()) {
|
||||
await showDashboardGreeting();
|
||||
}
|
||||
if ("news" === currentSite && "index" === currentPage) {
|
||||
if (currentSite === "news" && currentPage === "index") {
|
||||
await articleInit();
|
||||
}
|
||||
if ("account" === currentSite && "files" === currentPage) {
|
||||
if (currentSite === "account" && currentPage === "files") {
|
||||
await listFiles();
|
||||
}
|
||||
if ("memes" === currentSite && "index" === currentPage) {
|
||||
if (currentSite === "memes" && currentPage === "index") {
|
||||
await getMemeImages();
|
||||
}
|
||||
}
|
||||
@ -461,7 +461,7 @@ async function getUserInfo() {
|
||||
};
|
||||
const result = await doAction('/account', data, "User info retrieved Successfully!", "User info retrieval failed.", true);
|
||||
|
||||
if (result && "Success" === result.Status) {
|
||||
if (result && result.Status === "Success") {
|
||||
Object.keys(result.UserInfo).forEach(index => {
|
||||
let value = result.UserInfo[index];
|
||||
localStorage.setItem("UserInfo_" + index, value);
|
||||
@ -498,7 +498,7 @@ async function listUsers(silent) {
|
||||
|
||||
doAction('/account', data, "User list retrieved Successfully!", "User list retrieval failed.", silent).then((result) => {
|
||||
|
||||
if (result && "Success" === result.Status) {
|
||||
if (result && result.Status === "Success") {
|
||||
displayList(result.Users, "userListTable", deleteUser);
|
||||
}
|
||||
});
|
||||
@ -541,7 +541,7 @@ async function deleteActivationCode(activationCode) {
|
||||
|
||||
//Admin settings end
|
||||
|
||||
if ("loading" === document.readyState) {
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", initAjax);
|
||||
} else {
|
||||
setTimeout(initAjax, 0);
|
||||
@ -574,7 +574,7 @@ async function getFileList() {
|
||||
action: "getAllFiles"
|
||||
}, "Zoznam súborov bol úspešne stiahnutý", "Nastala chyba pri sťahovaní zoznamu súborov", true);
|
||||
|
||||
if ("Success" === resp.Status) {
|
||||
if (resp.Status === "Success") {
|
||||
return resp.Files;
|
||||
} else {
|
||||
return false;
|
||||
@ -642,10 +642,10 @@ async function reloadMemeVotes(memeID) {
|
||||
memeVoteCounterElement.innerText = memeVotes;
|
||||
memeVoteCounterElement.classList.remove("positive", "negative", "neutral");
|
||||
|
||||
if (memeVotes > 0) {
|
||||
if (0 < memeVotes) {
|
||||
memeVoteCounterElement.classList.add("positive");
|
||||
}
|
||||
else if (memeVotes < 0) {
|
||||
else if (0 > memeVotes) {
|
||||
memeVoteCounterElement.classList.add("negative");
|
||||
}
|
||||
else {
|
||||
@ -654,20 +654,15 @@ async function reloadMemeVotes(memeID) {
|
||||
|
||||
memeVoteUpvoteButtonElement.classList.remove('visual_hover');
|
||||
memeVoteDownvoteButtonElement.classList.remove('visual_hover');
|
||||
if (userVote > 0) {
|
||||
let memeUpvoteVariant = "line";
|
||||
let memeDownvoteVariant = "line";
|
||||
if (0 < userVote) {
|
||||
memeUpvoteVariant = "fill";
|
||||
memeDownvoteVariant = "line";
|
||||
memeVoteUpvoteButtonElement.classList.add('visual_hover');
|
||||
}
|
||||
else if (userVote < 0) {
|
||||
memeUpvoteVariant = "line";
|
||||
} else if (0 > userVote) {
|
||||
memeDownvoteVariant = "fill";
|
||||
memeVoteDownvoteButtonElement.classList.add('visual_hover');
|
||||
}
|
||||
else {
|
||||
memeUpvoteVariant = "line";
|
||||
memeDownvoteVariant = "line";
|
||||
}
|
||||
|
||||
memeVoteUpvoteElement.classList = [`ri-arrow-up-circle-${memeUpvoteVariant}`];
|
||||
memeVoteDownvoteElement.classList = [`ri-arrow-down-circle-${memeDownvoteVariant}`];
|
||||
@ -680,13 +675,13 @@ async function voteMeme(memeID, isUpvote){
|
||||
let memeVoteDelete = false;
|
||||
if(isUpvote) {
|
||||
if(memeVoteUpvoteElement.classList.contains("ri-arrow-up-circle-fill")){
|
||||
deleteVoteMeme(memeID);
|
||||
await deleteVoteMeme(memeID);
|
||||
memeVoteDelete = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(memeVoteDownvoteElement.classList.contains("ri-arrow-down-circle-fill")){
|
||||
deleteVoteMeme(memeID);
|
||||
await deleteVoteMeme(memeID);
|
||||
memeVoteDelete = true;
|
||||
}
|
||||
}
|
||||
|
@ -371,11 +371,11 @@ div#articleslist>article{
|
||||
}
|
||||
|
||||
.positive {
|
||||
color: green;
|
||||
color: #008000;
|
||||
}
|
||||
|
||||
.negative {
|
||||
color: red;
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.neutral {
|
||||
@ -390,12 +390,12 @@ div#articleslist>article{
|
||||
}
|
||||
|
||||
.visual_hover.meme_upvote {
|
||||
--pico-background-color: green;
|
||||
--pico-background-color: #008000;
|
||||
--pico-border-color: unset;
|
||||
}
|
||||
|
||||
.visual_hover.meme_downvote {
|
||||
--pico-background-color: red;
|
||||
--pico-background-color: #ff0000;
|
||||
--pico-border-color: unset;
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,12 @@ function endpoint($endpoint_data): array
|
||||
$endpoint_data["title"],
|
||||
$endpoint_data["body"]
|
||||
),
|
||||
"addNewsComment" => addNewsComment(
|
||||
$endpoint_data["user_id"],
|
||||
$endpoint_data['news_article_id'],
|
||||
$endpoint_data["comment_text"],
|
||||
$endpoint_data["parent_id"]
|
||||
),
|
||||
default => ["Status" => "Fail", "message" => "Invalid action"],
|
||||
};
|
||||
}
|
42
index.php
42
index.php
@ -1,32 +1,40 @@
|
||||
<?php
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
require_once 'secrets/config.php';
|
||||
require_once 'lib/config.php';
|
||||
require_once 'lib/navigation.php';
|
||||
require_once 'lib/router.php';
|
||||
require_once 'lib/page.php';
|
||||
require_once 'lib/endpoint.php';
|
||||
require_once 'lib/account.php';
|
||||
// Include essential configuration and function libraries.
|
||||
require_once 'secrets/config.php'; // Load sensitive configuration such as database credentials.
|
||||
require_once 'lib/config.php'; // Load general site configuration settings.
|
||||
require_once 'lib/navigation.php'; // Include functions related to navigation generation.
|
||||
require_once 'lib/router.php'; // Include routing functionality to manage URL routing.
|
||||
require_once 'lib/page.php'; // Functions related to page content generation and management.
|
||||
require_once 'lib/endpoint.php'; // Functions for handling API endpoints.
|
||||
require_once 'lib/account.php'; // Include user account management functionality.
|
||||
|
||||
// Load configuration for the router from the configuration files.
|
||||
$routerConfig = loadRouterConfig();
|
||||
|
||||
// Initialize the router to parse the request URI and determine the requested site/page.
|
||||
$routerRequest = initRouter();
|
||||
|
||||
// Start or resume a session to manage user sessions across requests.
|
||||
session_start();
|
||||
|
||||
// Set default session data if the user is not logged in.
|
||||
if (!isLoggedIn()) {
|
||||
setDefaultSessionData();
|
||||
setDefaultSessionData();
|
||||
}
|
||||
|
||||
if($routerRequest["site_name"] == "sitemap.xml") {
|
||||
require "lib/sitemap.php";
|
||||
generateSitemap();
|
||||
exit();
|
||||
// Handle requests for the sitemap.
|
||||
if ($routerRequest["site_name"] == "sitemap.xml") {
|
||||
require "lib/sitemap.php"; // Include sitemap generation functions.
|
||||
echo generateSitemap(); // Generate and output the sitemap XML.
|
||||
exit(); // Stop script execution after sitemap generation.
|
||||
}
|
||||
|
||||
// Handle API type requests by fetching and outputting the endpoint response.
|
||||
if ($routerRequest["type"] == "api") {
|
||||
echo getEndpoint($routerRequest["site_name"]);
|
||||
|
||||
} elseif ($routerRequest["type"] == "page") {
|
||||
echo getPage($routerRequest["site_name"], $routerRequest["page_name"]);
|
||||
}
|
||||
echo getEndpoint($routerRequest["site_name"]);
|
||||
}
|
||||
// Handle page type requests by fetching and rendering the page content.
|
||||
elseif ($routerRequest["type"] == "page") {
|
||||
echo getPage($routerRequest["site_name"], $routerRequest["page_name"]);
|
||||
}
|
||||
|
201
lib/account.php
201
lib/account.php
@ -1,52 +1,95 @@
|
||||
<?php
|
||||
|
||||
use Random\RandomException;
|
||||
|
||||
/**
|
||||
* Checks if the current session represents a logged-in user.
|
||||
*
|
||||
* @global array $routerConfig Global configuration array containing permission thresholds.
|
||||
* @return bool Returns true if the user is logged in and meets the minimum privilege level; otherwise, false.
|
||||
*/
|
||||
function isLoggedIn(): bool
|
||||
{
|
||||
global $routerConfig;
|
||||
return $_SESSION["ID"] > 0 && !empty($_SESSION["email"]) && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["logged_in_default"];
|
||||
}
|
||||
/**
|
||||
* Checks if the logged-in user is verified.
|
||||
*
|
||||
* @global array $routerConfig Global configuration array containing permission thresholds.
|
||||
* @return bool Returns true if the user is logged in and verified; otherwise, false.
|
||||
*/
|
||||
function isVerified(): bool
|
||||
{
|
||||
global $routerConfig;
|
||||
return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["verified"];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the logged-in user is trustworthy.
|
||||
*
|
||||
* @global array $routerConfig Global configuration array containing permission thresholds.
|
||||
* @return bool Returns true if the user is logged in and considered trustworthy; otherwise, false.
|
||||
*/
|
||||
function isTrustWorthy(): bool
|
||||
{
|
||||
global $routerConfig;
|
||||
return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["trustworthy"];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the logged-in user is a moderator.
|
||||
*
|
||||
* @global array $routerConfig Global configuration array containing permission thresholds.
|
||||
* @return bool Returns true if the user is logged in and a moderator; otherwise, false.
|
||||
*/
|
||||
function isModerator(): bool
|
||||
{
|
||||
global $routerConfig;
|
||||
return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["moderator"];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the logged-in user is a user admin.
|
||||
*
|
||||
* @global array $routerConfig Global configuration array containing permission thresholds.
|
||||
* @return bool Returns true if the user is logged in and a user admin; otherwise, false.
|
||||
*/
|
||||
function isUserAdmin(): bool
|
||||
{
|
||||
global $routerConfig;
|
||||
return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["user_admin"];
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the logged-in user is an admin.
|
||||
*
|
||||
* @global array $routerConfig Global configuration array containing permission thresholds.
|
||||
* @return bool Returns true if the user is logged in and an admin; otherwise, false.
|
||||
*/
|
||||
function isAdmin(): bool
|
||||
{
|
||||
global $routerConfig;
|
||||
return isLoggedIn() && $_SESSION["privilege_level"] >= $routerConfig["permissions"]["admin"];
|
||||
}
|
||||
|
||||
|
||||
function generateActivationToken(): string
|
||||
/**
|
||||
* Generates a secure token for account activation or other purposes using cryptographic methods.
|
||||
*
|
||||
* @return string|null Returns a hexadecimal token or null in case of an error.
|
||||
*/
|
||||
function generateActivationToken(): ?string
|
||||
{
|
||||
try {
|
||||
return bin2hex(random_bytes(16));
|
||||
} catch (RandomException) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function isEmailAvailable($email): bool
|
||||
/**
|
||||
* Checks if an email address is available for registration.
|
||||
*
|
||||
* @param string $email The email address to check.
|
||||
* @return bool Returns true if the email is not already registered; otherwise, false.
|
||||
*@global mysqli $mysqli Global mysqli object for database access.
|
||||
*/
|
||||
function isEmailAvailable(string $email): bool
|
||||
{
|
||||
global $mysqli;
|
||||
$stmt = $mysqli->prepare("SELECT COUNT(*) FROM Users WHERE Email = ?");
|
||||
@ -59,7 +102,12 @@ function isEmailAvailable($email): bool
|
||||
|
||||
return $count === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets default session data typically used for a logged-out user(includes users that have just visited the page).
|
||||
*
|
||||
* @global array $routerConfig Global configuration array used for setting initial privilege levels.
|
||||
* @return void
|
||||
*/
|
||||
function setDefaultSessionData(): void
|
||||
{
|
||||
global $routerConfig;
|
||||
@ -71,8 +119,15 @@ function setDefaultSessionData(): void
|
||||
$_SESSION["minecraft_nickname"] = "";
|
||||
$_SESSION["privilege_level"] = $routerConfig["permissions"]["logged_out"];
|
||||
}
|
||||
|
||||
function verifyPassword($userID, $password): bool
|
||||
/**
|
||||
* Verifies if the provided password matches the stored hash for the user.
|
||||
*
|
||||
* @param int $userID The user ID whose password is to be verified.
|
||||
* @param string $password The password to verify.
|
||||
* @return bool Returns true if the password matches the stored hash; otherwise, false.
|
||||
*@global mysqli $mysqli Global mysqli object for database access.
|
||||
*/
|
||||
function verifyPassword(int $userID, string $password): bool
|
||||
{
|
||||
global $mysqli;
|
||||
$stmt = $mysqli->prepare("SELECT PasswordHash FROM Users WHERE ID = ?");
|
||||
@ -85,7 +140,12 @@ function verifyPassword($userID, $password): bool
|
||||
|
||||
return !empty($password_hash) && !empty($password) && password_verify($password, $password_hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates session data from the database for the logged-in user.
|
||||
*
|
||||
* @global mysqli $mysqli Global mysqli object for database access.
|
||||
* @return void
|
||||
*/
|
||||
function UpdateSession(): void
|
||||
{
|
||||
global $mysqli;
|
||||
@ -118,8 +178,15 @@ function UpdateSession(): void
|
||||
$_SESSION["favorite_color"] = $favorite_color;
|
||||
|
||||
}
|
||||
|
||||
function doLogin($email, $password): array
|
||||
/**
|
||||
* Attempts to log in a user with the given credentials.
|
||||
*
|
||||
* @param string $email The user's email address.
|
||||
* @param string $password The user's password.
|
||||
* @global mysqli $mysqli Global database connection object.
|
||||
* @return array An array containing the status of the login attempt ('Success' or 'Fail').
|
||||
*/
|
||||
function doLogin(string $email, string $password): array
|
||||
{
|
||||
global $mysqli;
|
||||
$found = false;
|
||||
@ -149,7 +216,12 @@ function doLogin($email, $password): array
|
||||
}
|
||||
return $found ? ["Status" => "Success"] : ["Status" => "Fail"];
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs out the current user by resetting session data.
|
||||
* Fails when the user wasn't logged in
|
||||
*
|
||||
* @return array An array with the logout status ('Success' if logged out, 'Fail' otherwise).
|
||||
*/
|
||||
function doLogout(): array
|
||||
{
|
||||
if(isLoggedIn()){
|
||||
@ -159,8 +231,19 @@ function doLogout(): array
|
||||
return ["Status" => "Fail"];
|
||||
}
|
||||
}
|
||||
|
||||
function doRegister($firstname, $lastname, $email, $password, $activation_token): array
|
||||
/**
|
||||
* Registers a new user with provided personal details and activation token.
|
||||
*
|
||||
* @param string $firstname The user's first name.
|
||||
* @param string $lastname The user's last name.
|
||||
* @param string $email The user's email.
|
||||
* @param string $password The user's password.
|
||||
* @param string $activation_token The activation token to verify the registration.
|
||||
* @global mysqli $mysqli Global database connection object.
|
||||
* @global array $routerConfig Global configuration settings.
|
||||
* @return array An array with the registration status ('Success' or 'Fail').
|
||||
*/
|
||||
function doRegister(string $firstname, string $lastname, string $email, string $password, string $activation_token): array
|
||||
{
|
||||
global $mysqli, $routerConfig;
|
||||
$status = ["Status" => "Fail"];
|
||||
@ -186,8 +269,15 @@ function doRegister($firstname, $lastname, $email, $password, $activation_token)
|
||||
return $status;
|
||||
}
|
||||
|
||||
|
||||
function changePassword($oldPassword, $newPassword): array
|
||||
/**
|
||||
* Changes the user's password after verifying the old password.
|
||||
*
|
||||
* @param string $oldPassword The current password for verification.
|
||||
* @param string $newPassword The new password to be set.
|
||||
* @return array An array indicating whether the password change was successful ('Success' or 'Fail').
|
||||
*@global mysqli $mysqli Global database connection object.
|
||||
*/
|
||||
function changePassword(string $oldPassword, string $newPassword): array
|
||||
{
|
||||
global $mysqli;
|
||||
$status = ["Status" => "Fail"];
|
||||
@ -206,8 +296,17 @@ function changePassword($oldPassword, $newPassword): array
|
||||
}
|
||||
|
||||
|
||||
// Function to update user profile
|
||||
function updateUserProfile($firstName, $lastName, $nickname, $minecraft_nickname): array
|
||||
/**
|
||||
* Updates user profile information in the database.
|
||||
*
|
||||
* @param string $firstName The new first name.
|
||||
* @param string $lastName The new last name.
|
||||
* @param string $nickname The new nickname.
|
||||
* @param string $minecraft_nickname The new Minecraft nickname.
|
||||
* @return array Status of the profile update ('Success' or 'Fail').
|
||||
*@global mysqli $mysqli Global database connection object.
|
||||
*/
|
||||
function updateUserProfile(string $firstName, string $lastName, string $nickname, string $minecraft_nickname): array
|
||||
{
|
||||
global $mysqli;
|
||||
$status = ["Status" => "Fail"];
|
||||
@ -230,8 +329,14 @@ function updateUserProfile($firstName, $lastName, $nickname, $minecraft_nickname
|
||||
return $status;
|
||||
}
|
||||
|
||||
// Function to update user email
|
||||
function updateUserEmail($email): array
|
||||
/**
|
||||
* Updates the email address of the logged-in user after validation.
|
||||
*
|
||||
* @param string $email The new email address to update.
|
||||
* @return array Status of the email update ('Success' or 'Fail').
|
||||
*@global mysqli $mysqli Global database connection object.
|
||||
*/
|
||||
function updateUserEmail(string $email): array
|
||||
{
|
||||
global $mysqli;
|
||||
$status = ["Status" => "Fail"];
|
||||
@ -274,7 +379,11 @@ function updateUserEmail($email): array
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves and updates the current session with user information from the database.
|
||||
*
|
||||
* @return array Contains user information and status if the user is logged in.
|
||||
*/
|
||||
function getUserInfo(): array
|
||||
{
|
||||
$output = ["Status" => "Fail"];
|
||||
@ -310,8 +419,14 @@ function getUserInfo(): array
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
function addActivationCodes($count): array
|
||||
/**
|
||||
* Generates a specified number of activation codes for user registration and adds them to the database.
|
||||
*
|
||||
* @param int $count Number of activation codes to generate.
|
||||
* @return array An array containing the generated codes and status ('Success' or 'Fail').
|
||||
*@global mysqli $mysqli Global database connection object.
|
||||
*/
|
||||
function addActivationCodes(int $count): array
|
||||
{
|
||||
global $mysqli;
|
||||
$activationCodes = [];
|
||||
@ -342,7 +457,12 @@ function addActivationCodes($count): array
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists all registered users, available only to user admins.
|
||||
*
|
||||
* @global mysqli $mysqli Global database connection object.
|
||||
* @return array An array containing user data and status.
|
||||
*/
|
||||
function listUsers(): array
|
||||
{
|
||||
global $mysqli;
|
||||
@ -364,7 +484,12 @@ function listUsers(): array
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists activation codes available for assigning to new users, available only for user admins.
|
||||
*
|
||||
* @global mysqli $mysqli Global database connection object.
|
||||
* @return array An array containing activation codes and status.
|
||||
*/
|
||||
function listActivationCodes(): array
|
||||
{
|
||||
global $mysqli;
|
||||
@ -409,8 +534,14 @@ function listActivationCodes(): array
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
||||
function deleteUser($userID): array
|
||||
/**
|
||||
* Deletes a user by their ID, available only to user admins.
|
||||
*
|
||||
* @param int $userID The ID of the user to delete.
|
||||
* @return array Status of the delete operation ('Success' or 'Fail').
|
||||
*@global mysqli $mysqli Global database connection object.
|
||||
*/
|
||||
function deleteUser(int $userID): array
|
||||
{
|
||||
global $mysqli;
|
||||
$status = ["Status" => "Fail"];
|
||||
@ -425,8 +556,14 @@ function deleteUser($userID): array
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
|
||||
function deleteActivationCode($activationCode): array
|
||||
/**
|
||||
* Deletes an activation code, available only to user admins.
|
||||
*
|
||||
* @param string $activationCode The activation code to delete.
|
||||
* @return array Status of the delete operation ('Success' or 'Fail').
|
||||
*@global mysqli $mysqli Global database connection object.
|
||||
*/
|
||||
function deleteActivationCode(string $activationCode): array
|
||||
{
|
||||
global $mysqli;
|
||||
$status = ["Status" => "Fail"];
|
||||
|
@ -1,4 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Loads and returns the configuration settings for the router.
|
||||
*
|
||||
* This configuration includes various paths, default settings, security levels, SEO settings,
|
||||
* and other parameters essential for the operation of the router and the website's page management.
|
||||
* The configuration array is structured to provide easy access to paths, protocols, permissions,
|
||||
* and other critical settings that define how the router handles requests and serves content.
|
||||
*
|
||||
* @return array Returns an associative array containing all router configuration settings, such as:
|
||||
* - 'inlining': Boolean value determining if CSS/JS should be inlined.
|
||||
* - 'domain': The primary domain name of the website.
|
||||
* - 'tld': Top-level domain for the website.
|
||||
* - 'default_page': Default page to load if no specific page is requested.
|
||||
* - 'default_site': Default site to load if no specific site is requested.
|
||||
* - 'template_dir': Directory path where templates are stored.
|
||||
* - 'endpoint_dir': Directory path for endpoint scripts.
|
||||
* - 'page_dir': Directory path where site pages are stored.
|
||||
* - 'protocol': Protocol to be used (e.g., 'https://').
|
||||
* - 'site_prefix': Prefix for the site title.
|
||||
* - 'permissions': Associative array of user permissions by role.
|
||||
* - 'page': Default settings for pages including secret status and permissions.
|
||||
* - 'newsarticle': Default permissions for news articles.
|
||||
* - 'seo': Search engine optimization settings like author, description, and keywords.
|
||||
*/
|
||||
function loadRouterConfig(): array
|
||||
{
|
||||
|
||||
|
@ -1,5 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Generates dynamic CSS styling based on user preferences stored in the session.
|
||||
* Specifically, it creates a CSS rule for the user's favorite color if it's specified in their session data.
|
||||
*
|
||||
* @return string Returns a string containing a `<style>` tag with custom CSS if a favorite color is set
|
||||
* and the user is logged in. Returns an empty string if no conditions are met.
|
||||
*/
|
||||
function doDynamicStyling() :string
|
||||
{
|
||||
$dynamic_style = "";
|
||||
|
@ -1,6 +1,16 @@
|
||||
<?php
|
||||
|
||||
function runEndpoint($endpoint_file): ?array
|
||||
/**
|
||||
* Executes an endpoint script and returns the results.
|
||||
*
|
||||
* This function includes an endpoint PHP file that defines a function named `endpoint` which
|
||||
* is expected to accept an array parameter and return an array result.
|
||||
* It simply scopes an external file into a function to prevent variable conflicts.
|
||||
*
|
||||
* @param string $endpoint_file The path to the endpoint PHP file.
|
||||
* @return array|null Returns the result of the endpoint function if successful, or null if the
|
||||
* endpoint function or file does not behave as expected.
|
||||
*/
|
||||
function runEndpoint(string $endpoint_file): ?array
|
||||
{
|
||||
|
||||
$endpoint_data = $_POST;
|
||||
@ -9,8 +19,20 @@ function runEndpoint($endpoint_file): ?array
|
||||
return endpoint($endpoint_data);
|
||||
}
|
||||
|
||||
|
||||
function getEndpoint($endpoint_name): string
|
||||
/**
|
||||
* Retrieves and processes the output of a specified endpoint.
|
||||
*
|
||||
* This function determines the appropriate endpoint PHP file based on the provided endpoint name,
|
||||
* executes the endpoint, and returns its results as a JSON-encoded string. It handles and
|
||||
* translates different return types into a JSON format and manages HTTP response codes based on
|
||||
* success or failure of the endpoint execution.
|
||||
*
|
||||
* @param string $endpoint_name The name of the endpoint, which is used to construct the file path to the endpoint script.
|
||||
* @return string A JSON-encoded string representing the result of the endpoint, including a status indicator and any relevant data or error messages.
|
||||
*@global array $routerRequest Current request data that might influence the endpoint processing.
|
||||
* @global array $routerConfig Global configuration that contains paths and settings.
|
||||
*/
|
||||
function getEndpoint(string $endpoint_name): string
|
||||
{
|
||||
$output = array();
|
||||
$output["Status"] = "Fail";
|
||||
|
@ -1,6 +1,13 @@
|
||||
<?php
|
||||
|
||||
function inlineLocalStylesFromHref($inputString): string
|
||||
/**
|
||||
* Processes an HTML string to inline all linked stylesheets by replacing <link> tags
|
||||
* with corresponding <style> tags containing the CSS content.
|
||||
* Might be broken, currently disabled in the config
|
||||
*
|
||||
* @param string $inputString The HTML content containing <link> tags to stylesheets.
|
||||
* @return string The modified HTML content with stylesheets inlined within <style> tags.
|
||||
*/
|
||||
function inlineLocalStylesFromHref(string $inputString): string
|
||||
{
|
||||
$pattern = '/<link[^>]*?\srel=["\']?stylesheet["\'].*?\shref=["\']?\/(.*?)["\'][^>]*?>/i';
|
||||
|
||||
@ -30,8 +37,15 @@ function inlineLocalStylesFromHref($inputString): string
|
||||
return "<style>$cssContent</style>";
|
||||
}, $inputString);
|
||||
}
|
||||
|
||||
function inlineScriptFromSrc($inputString): string
|
||||
/**
|
||||
* Processes an HTML string to inline all external JavaScript files by replacing <script src="..."> tags
|
||||
* with <script> tags containing the JavaScript content.
|
||||
* Might be broken, currently disabled in the config
|
||||
*
|
||||
* @param string $inputString The HTML content containing <script src=""> tags.
|
||||
* @return string The modified HTML content with external scripts inlined within <script> tags.
|
||||
*/
|
||||
function inlineScriptFromSrc(string $inputString): string
|
||||
{
|
||||
$pattern = '/<script.*?src=["\']\/(.*?)["\'].*?>\s*<\/script>/i';
|
||||
|
||||
@ -44,8 +58,14 @@ function inlineScriptFromSrc($inputString): string
|
||||
return "<script>$jsContent</script>";
|
||||
}, $inputString);
|
||||
}
|
||||
|
||||
function minifyCss($css): string
|
||||
/**
|
||||
* Minifies CSS content by removing comments, unnecessary whitespaces, semicolons, and optimizing other aspects of the stylesheet.
|
||||
* Might be broken, currently disabled in the config
|
||||
*
|
||||
* @param string $css The original CSS content.
|
||||
* @return string The minified CSS content.
|
||||
*/
|
||||
function minifyCss(string $css): string
|
||||
{
|
||||
// Remove comments
|
||||
$css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $css);
|
||||
@ -64,8 +84,14 @@ function minifyCss($css): string
|
||||
|
||||
return trim($css);
|
||||
}
|
||||
|
||||
function minifyJs($js): string
|
||||
/**
|
||||
* Minifies JavaScript content by removing comments, unnecessary whitespaces, and optimizing spaces around operators.
|
||||
* Might be broken, currently disabled in the config
|
||||
*
|
||||
* @param string $js The original JavaScript content.
|
||||
* @return string The minified JavaScript content.
|
||||
*/
|
||||
function minifyJs(string $js): string
|
||||
{
|
||||
|
||||
// Remove newlines and tabs
|
||||
|
77
lib/meme.php
77
lib/meme.php
@ -2,7 +2,15 @@
|
||||
|
||||
require_once "lib/upload.php";
|
||||
require_once "lib/account.php";
|
||||
|
||||
/**
|
||||
* Adds a meme to the database with associated image and text content.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
function addMeme(string $title, string $memeText, int $imageID): array
|
||||
{
|
||||
global $mysqli;
|
||||
@ -17,7 +25,21 @@ function addMeme(string $title, string $memeText, int $imageID): array
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a meme into HTML based on provided data and a template.
|
||||
*
|
||||
* @param int $id The ID of the meme.
|
||||
* @param int $authorId The author's user ID.
|
||||
* @param string $title The title of the meme.
|
||||
* @param string $textContent The text content of the meme.
|
||||
* @param string $createdAt The creation timestamp of the meme.
|
||||
* @param string $filePath The file path of the associated image.
|
||||
* @param int $imageWidth The width of the image.
|
||||
* @param int $imageHeight The height of the image.
|
||||
* @param string $userNickname The nickname of the meme's author.
|
||||
* @param string $meme_template The HTML template for a meme. (used to not read the template over and over when rendering more memes)
|
||||
* @return string Returns the rendered HTML of the meme.
|
||||
*/
|
||||
function renderMeme(int $id, int $authorId, string $title, string $textContent, string $createdAt, string $filePath, int $imageWidth, int $imageHeight, string $userNickname, string $meme_template): string
|
||||
{
|
||||
|
||||
@ -64,7 +86,14 @@ 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.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
function renderMemeGallery(): string
|
||||
{
|
||||
global $mysqli;
|
||||
@ -105,7 +134,13 @@ function renderMemeGallery(): string
|
||||
$stmtlist->close();
|
||||
return $meme_gallery_out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
function deleteMeme(int $memeID): array
|
||||
{
|
||||
global $mysqli;
|
||||
@ -126,7 +161,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.
|
||||
*/
|
||||
function voteMeme(int $memeID, int $isUpvote): array
|
||||
{
|
||||
global $mysqli;
|
||||
@ -143,7 +185,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.
|
||||
*/
|
||||
function deleteVoteMeme(int $memeID): array
|
||||
{
|
||||
global $mysqli;
|
||||
@ -157,7 +205,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.
|
||||
*/
|
||||
function calculateNetVotes(int $memeID): array
|
||||
{
|
||||
global $mysqli;
|
||||
@ -193,7 +248,13 @@ function calculateNetVotes(int $memeID): array
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetches the net votes and user's vote status for a specific meme.
|
||||
* Essentially just a wrapper of getMemeVotes for an API call
|
||||
*
|
||||
* @param int $memeID The ID of the meme to fetch votes for.
|
||||
* @return array Returns an array with the net votes and the user's vote status, along with operation status.
|
||||
*/
|
||||
function getMemeVotes(int $memeID): array
|
||||
{
|
||||
$voteData = calculateNetVotes($memeID);
|
||||
|
@ -1,11 +1,24 @@
|
||||
<?php
|
||||
|
||||
|
||||
function getDynamicMetadata($file): array{
|
||||
/**
|
||||
* Includes a PHP file that returns metadata associated with a dynamic page.
|
||||
* It simply scopes an external file into a function to prevent variable conflicts.
|
||||
*
|
||||
* @param string $file The file path to the PHP file that contains metadata.
|
||||
* @return array Returns an associative array of metadata from the included PHP file.
|
||||
*/
|
||||
function getDynamicMetadata(string $file): array{
|
||||
return include($file);
|
||||
}
|
||||
|
||||
function getDynamicPermission($metadata): int {
|
||||
/**
|
||||
* Extracts and validates the minimal permission level required to access certain content,
|
||||
* defaulting to system configuration if not properly set or in case of an error.
|
||||
*
|
||||
* @param array $metadata Metadata array that should include a 'parameters' key with 'minimal_permission_level'.
|
||||
* @return int Returns the minimal permission level required to access a page.
|
||||
*@global array $routerConfig Global router configuration settings.
|
||||
*/
|
||||
function getDynamicPermission(array $metadata): int {
|
||||
global $routerConfig;
|
||||
$params = $metadata["parameters"];
|
||||
try {
|
||||
@ -21,7 +34,14 @@ function getDynamicPermission($metadata): int {
|
||||
return $permission_level;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates HTML navigation links for all sites and pages configured in the router,
|
||||
* adjusting active states based on current request and filtering links by user permissions.
|
||||
*
|
||||
* @global array $routerConfig Global configuration that includes directory paths and default settings.
|
||||
* @global array $routerRequest Current request details including site and page name.
|
||||
* @return string Returns the HTML string of the navigation menu.
|
||||
*/
|
||||
function generateNavigation(): string
|
||||
{
|
||||
global $routerConfig;
|
||||
@ -107,7 +127,12 @@ function generateNavigation(): string
|
||||
|
||||
return str_replace("__NAV_PAGES__", $nav_out, $nav);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a simple API endpoint-like response for fetching generated navigation HTML.
|
||||
* Wraps generateNavigation for an API.
|
||||
*
|
||||
* @return array Returns an associative array with the navigation HTML and a status indicating success.
|
||||
*/
|
||||
function getNavigationEndpoint() :array{
|
||||
return [
|
||||
"Status" => "Success",
|
||||
|
@ -1,4 +1,15 @@
|
||||
<?php
|
||||
require_once "lib/account.php";
|
||||
/**
|
||||
* Retrieves news articles based on the current user's privilege level.
|
||||
* The function queries the NewsArticles and Users tables to fetch articles
|
||||
* that the user has the privilege to view. Articles are joined with user
|
||||
* information to include the author's nickname.
|
||||
*
|
||||
* @global mysqli $mysqli The mysqli database connection object.
|
||||
* @return array Returns an associative array with a status key indicating the success or failure,
|
||||
* and an 'Articles' key containing an array of articles if successful.
|
||||
*/
|
||||
function getNewsArticles() :array
|
||||
{
|
||||
global $mysqli;
|
||||
@ -39,7 +50,18 @@ function getNewsArticles() :array
|
||||
return $output;
|
||||
}
|
||||
|
||||
function addNewsArticle($title="Nazov", $body="Obsah", $privilegeLevel=0) :array
|
||||
/**
|
||||
* Adds a new news article to the database if the user is logged in and has the appropriate
|
||||
* privilege level. The function sanitizes the title and body of the article to prevent XSS attacks.
|
||||
*
|
||||
* @global mysqli $mysqli The mysqli database connection object.
|
||||
* @global array $routerConfig Configuration array that includes default permission settings.
|
||||
* @param string $title The title of the news article. Default value is "Nazov".
|
||||
* @param string $body The body of the news article. Default value is "Obsah".
|
||||
* @param int $privilegeLevel The privilege level required to view the article. If set to 0, uses default from configuration.
|
||||
* @return array Returns an associative array with a status key that indicates the success or failure of the operation.
|
||||
*/
|
||||
function addNewsArticle(string $title="Nazov", string $body="Obsah", int $privilegeLevel=0) :array
|
||||
{
|
||||
global $mysqli;
|
||||
global $routerConfig;
|
||||
@ -61,4 +83,48 @@ function addNewsArticle($title="Nazov", $body="Obsah", $privilegeLevel=0) :array
|
||||
$query->close();
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a comment to a news article.
|
||||
*
|
||||
* @param int $userId User who is commenting.
|
||||
* @param int $newsArticleId ID of the news article.
|
||||
* @param string $commentText The content of the comment.
|
||||
* @param int|null $parentId ID of the parent comment if it's a reply.
|
||||
* @return array Status array indicating success or failure.
|
||||
* @global mysqli $mysqli The mysqli database connection object.
|
||||
*/
|
||||
function addNewsComment(int $userId, int $newsArticleId, string $commentText, ?int $parentId = null): array {
|
||||
global $mysqli;
|
||||
|
||||
$output = ["Status" => "Fail"]; // Default Status is "Fail"
|
||||
|
||||
if (!isLoggedIn()) {
|
||||
$output['Error'] = "User must be logged in.";
|
||||
return $output;
|
||||
}
|
||||
|
||||
// Prepare the SQL statement to prevent SQL injection
|
||||
$stmt = $mysqli->prepare("INSERT INTO NewsComments (ParentID, UserID, NewsArticleID, CommentText) VALUES (?, ?, ?, ?);");
|
||||
|
||||
// Bind parameters. 'i' denotes an integer and 's' denotes a string.
|
||||
$stmt->bind_param("iiis", $parentId, $userId, $newsArticleId, $commentText);
|
||||
|
||||
// Execute the query
|
||||
if ($stmt->execute()) {
|
||||
// Check if any rows were affected
|
||||
if ($stmt->affected_rows > 0) {
|
||||
$output["Status"] = "Success";
|
||||
} else {
|
||||
$output["Error"] = "No rows affected.";
|
||||
}
|
||||
} else {
|
||||
$output["Error"] = $stmt->error;
|
||||
}
|
||||
|
||||
// Close statement
|
||||
$stmt->close();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
63
lib/page.php
63
lib/page.php
@ -1,16 +1,37 @@
|
||||
<?php
|
||||
require_once "lib/dynamic_style.php";
|
||||
require_once "lib/script_data.php";
|
||||
function renderDynamicPage($page_file): array
|
||||
/**
|
||||
* Loads and returns the result of a PHP file.
|
||||
* This function is typically used to process dynamic content of a page.
|
||||
* It simply scopes an external file into a function to prevent variable conflicts.
|
||||
*
|
||||
* @param string $page_file The file path to the dynamic page.
|
||||
* @return array Returns the array of data generated by including the PHP file.
|
||||
*/
|
||||
function renderDynamicPage(string $page_file): array
|
||||
{
|
||||
return require $page_file;
|
||||
}
|
||||
|
||||
function removeHtmlComments($content = '') :string {
|
||||
/**
|
||||
* Removes all HTML comments from the provided content string.
|
||||
*
|
||||
* @param string $content The HTML content from which to remove comments.
|
||||
* @return string The content without any HTML comments.
|
||||
*/
|
||||
function removeHtmlComments(string $content = '') :string {
|
||||
return preg_replace('/<!--(.|\s)*?-->/', '', $content);
|
||||
}
|
||||
|
||||
function parsePageTag($input): array
|
||||
/**
|
||||
* Parses custom `<page>` tags from the given input string and extracts parameters.
|
||||
* Returns the input string with `<page>` tags removed and a list of parameters.
|
||||
*
|
||||
* @param string $input The input HTML or text containing `<page>` tags.
|
||||
* @return array Returns an associative array with 'parameters' (parsed from the tag)
|
||||
* and 'output' (the modified input string with `<page>` tags removed).
|
||||
*/
|
||||
function parsePageTag(string $input): array
|
||||
{
|
||||
// Define the pattern for the tag
|
||||
$pattern = '/<page\s+([^>]+)><\/page>/i';
|
||||
@ -34,8 +55,15 @@ function parsePageTag($input): array
|
||||
// If no match is found, return the original input
|
||||
return ['parameters' => [], 'output' => $input];
|
||||
}
|
||||
|
||||
function renderPage($page_name = null, $site_name = null): array
|
||||
/**
|
||||
* Renders a page based on specified page and site names, handling dynamic and static content,
|
||||
* permissions, and error pages.
|
||||
*
|
||||
* @param string|null $page_name The name of the page to render. If null, uses default from request.
|
||||
* @param string|null $site_name The name of the site to render. If null, uses default from request.
|
||||
* @return array Returns an associative array containing the rendered page content, page name, site name, and page title.
|
||||
*/
|
||||
function renderPage(string $page_name = null, string $site_name = null): array
|
||||
{
|
||||
global $routerConfig;
|
||||
global $routerRequest;
|
||||
@ -138,8 +166,16 @@ function renderPage($page_name = null, $site_name = null): array
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
function getPage($site_name_in = null, $page_name_in = null): string
|
||||
/**
|
||||
* Compiles a complete web page by injecting dynamic elements into a template skeleton,
|
||||
* including headers, footers, and SEO tags.
|
||||
* It is used when not going to a page by AJAX to initialize everything.
|
||||
*
|
||||
* @param string|null $site_name_in The site name to be used; defaults from global configuration if null.
|
||||
* @param string|null $page_name_in The page name to be used; defaults from global configuration if null.
|
||||
* @return string The complete HTML content of the web page ready for display.
|
||||
*/
|
||||
function getPage(string $site_name_in = null, string $page_name_in = null): string
|
||||
{
|
||||
$page_tmp = renderPage($page_name_in, $site_name_in);
|
||||
|
||||
@ -223,8 +259,15 @@ function getPage($site_name_in = null, $page_name_in = null): string
|
||||
}
|
||||
return str_replace("__TEMPLATE_PAGE_TITLE__", $page_title, $out);
|
||||
}
|
||||
|
||||
function getPageEndpoint($page_name, $site_name) :array
|
||||
/**
|
||||
* Provides an API interface to get page details including content and meta-information for routing purposes.
|
||||
* This is what enables the page to never refresh.
|
||||
*
|
||||
* @param string $page_name The name of the page.
|
||||
* @param string $site_name The name of the site.
|
||||
* @return array Returns an array with status, page content, location URL, and title for the requested page.
|
||||
*/
|
||||
function getPageEndpoint(string $page_name, string $site_name) :array
|
||||
{
|
||||
$page_location = "/" . $site_name . "/" . $page_name;
|
||||
$page_tmp = renderPage($page_name, $site_name);
|
||||
|
@ -1,6 +1,14 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the routing system for a web application. This function processes the incoming
|
||||
* URL and determines the site name and page name based on the configuration and the URL structure.
|
||||
* It handles default configurations and supports different types of requests like API or page requests.
|
||||
*
|
||||
* @global array $routerConfig The global configuration array that includes default site and page settings.
|
||||
* @return array Returns an associative array containing the routing information, including the site name,
|
||||
* page name, request type, and parsed request address from the HTTP host.
|
||||
*/
|
||||
function initRouter(): array
|
||||
{
|
||||
global $routerConfig;
|
||||
|
@ -1,5 +1,15 @@
|
||||
<?php
|
||||
function generateScriptData($phpArray):string {
|
||||
/**
|
||||
* Generates a JavaScript script tag containing commands to store PHP array key-value pairs in local storage.
|
||||
* This function is designed to translate PHP associative array data into JavaScript local storage items.
|
||||
* It ensures that the array is associative and single-level before proceeding with the JavaScript code generation.
|
||||
* This is used when dumping session data into local storage for use by the client script.
|
||||
*
|
||||
* @param array $phpArray The associative array whose data will be converted into JavaScript local storage setItem calls.
|
||||
* @return string Returns a script tag with JavaScript code. If the input is not a valid single-level associative array,
|
||||
* it returns a script with an error logged to the console.
|
||||
*/
|
||||
function generateScriptData(array $phpArray):string {
|
||||
// Check if the array is associative and single-level
|
||||
if (is_array($phpArray) && count($phpArray) > 0 && count(array_filter(array_keys($phpArray), 'is_string')) === count($phpArray)) {
|
||||
// Generate JavaScript code to save each array element to local storage
|
||||
|
@ -1,8 +1,16 @@
|
||||
<?php
|
||||
require_once "lib/account.php";
|
||||
|
||||
|
||||
function generateSitemap(): void{
|
||||
/**
|
||||
* Generates an XML sitemap as a string for a website, considering only pages that the current session
|
||||
* has sufficient privileges to access. It scans directories specified in the router configuration
|
||||
* for .html and .php files, and constructs a sitemap entry for each accessible page based on their
|
||||
* required permission levels. This function returns the sitemap as a string and
|
||||
* sets the appropriate header for XML content.
|
||||
*
|
||||
* @global array $routerConfig The global configuration array containing directory paths and default settings.
|
||||
* @return string The XML sitemap content, properly formatted in accordance with the sitemap protocol.
|
||||
*/
|
||||
function generateSitemap(): string{
|
||||
global $routerConfig;
|
||||
|
||||
$site_dirs = array_diff(scandir($routerConfig["page_dir"]), array('.', '..'));
|
||||
@ -54,5 +62,5 @@ function generateSitemap(): void{
|
||||
$sitemap .= '</urlset>' . PHP_EOL;
|
||||
|
||||
header('Content-type: application/xml');
|
||||
echo $sitemap;
|
||||
return $sitemap;
|
||||
}
|
102
lib/upload.php
102
lib/upload.php
@ -1,6 +1,12 @@
|
||||
<?php
|
||||
|
||||
function makePathSafe($userInput): string
|
||||
/**
|
||||
* Sanitizes user input to be used as a part of a file path to prevent security vulnerabilities such as directory traversal.
|
||||
*
|
||||
* @param string $userInput The input string to be sanitized.
|
||||
* @return string Returns a safe string where only alphanumeric characters, underscores, and hyphens are retained.
|
||||
* Special characters and potential path traversal payloads are removed or replaced.
|
||||
*/
|
||||
function makePathSafe(string $userInput): string
|
||||
{
|
||||
// Keep only alphanumeric characters, underscores, and hyphens
|
||||
$safeString = preg_replace('/[^\w\-]/', '', $userInput);
|
||||
@ -17,7 +23,12 @@ function makePathSafe($userInput): string
|
||||
// Limit length for safety
|
||||
return substr($safeString, 0, 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically rotates an image based on its EXIF data to adjust its orientation.
|
||||
*
|
||||
* @param Imagick $imagick An Imagick object representing the image to be rotated.
|
||||
* @return void
|
||||
*/
|
||||
function autoRotateImage(Imagick $imagick): void {
|
||||
// Get the current orientation of the image
|
||||
try {
|
||||
@ -42,7 +53,11 @@ function autoRotateImage(Imagick $imagick): void {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the global $_FILES array to normalize the structure and filter out any files with errors.
|
||||
*
|
||||
* @return array Returns an array of files that are ready for further processing, structured uniformly.
|
||||
*/
|
||||
function getIncomingFiles(): array
|
||||
{
|
||||
$files = $_FILES;
|
||||
@ -67,7 +82,16 @@ function getIncomingFiles(): array
|
||||
}
|
||||
return $files3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves file metadata in the database.
|
||||
* This creates the only record of the file existing.
|
||||
*
|
||||
* @param string $filePath The path where the file is stored.
|
||||
* @param string $fileType The MIME type of the file.
|
||||
* @param int $width The width of the image file.
|
||||
* @param int $height The height of the image file.
|
||||
* @return bool Returns true if the file metadata was successfully saved to the database, false otherwise.
|
||||
*/
|
||||
function saveUploadedFileInDatabase(string $filePath, string $fileType, int $width, int $height): bool
|
||||
{
|
||||
global $mysqli;
|
||||
@ -78,8 +102,14 @@ function saveUploadedFileInDatabase(string $filePath, string $fileType, int $wid
|
||||
$stmt->close();
|
||||
return $stat;
|
||||
}
|
||||
|
||||
function doImageUpload($inFile, $outFile): bool
|
||||
/**
|
||||
* Handles the uploading process of an image, including its conversion to webp format, rotation based on orientation, and saving.
|
||||
*
|
||||
* @param string $inFile The temporary file path of the uploaded file.
|
||||
* @param string $outFile The target file path where the processed image should be saved.
|
||||
* @return bool Returns true if the file was successfully processed and saved, false otherwise.
|
||||
*/
|
||||
function doImageUpload(string $inFile, string $outFile): bool
|
||||
{
|
||||
// Create Imagick object
|
||||
$width = 0;
|
||||
@ -96,15 +126,22 @@ function doImageUpload($inFile, $outFile): bool
|
||||
} catch (ImagickException) {
|
||||
}
|
||||
|
||||
// Check if the reencoding was successful
|
||||
// Check if the reencoding was successful, if yes, save into the database.
|
||||
if (file_exists($outFile)) {
|
||||
return saveUploadedFileInDatabase($outFile, 'image/webp', $width, $height);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Retrieves a list of files from the database, optionally filtered to include only files uploaded by the current user.
|
||||
* Access to an unfiltered list (files of all users) is only available to moderators.
|
||||
*
|
||||
* @param bool $onlyMine Whether to retrieve only files uploaded by the logged-in user. If false, files from all users are returned if the user is a moderator.
|
||||
* @return array Returns an array containing file data along with a status message.
|
||||
*/
|
||||
|
||||
function listFiles($onlyMine = true): array
|
||||
function listFiles(bool $onlyMine = true): array
|
||||
{
|
||||
$output = ["Status" => "Success"];
|
||||
require_once "lib/account.php";
|
||||
@ -156,6 +193,12 @@ function listFiles($onlyMine = true): array
|
||||
return $output;
|
||||
|
||||
}
|
||||
/**
|
||||
* Processes incoming files from the $_FILES global (after processed by getIncomingFiles), performs checks, and attempts to upload a file based on its type.
|
||||
* Currently only supports valid image files.
|
||||
*
|
||||
* @return array Returns an array indicating the success or failure ('Status' key) of the file processing operations.
|
||||
*/
|
||||
|
||||
function parseIncomingFiles(): array
|
||||
{
|
||||
@ -183,8 +226,15 @@ function parseIncomingFiles(): array
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
/**
|
||||
* Generates a file path for uploading based on the type of the file, the ID of the uploader and the date and time of uploading.
|
||||
*
|
||||
* @param string $type The type of the file, typically used to categorize the file.
|
||||
* @param string $filename The base name of the file, used in generating the final path.
|
||||
* @return string Returns the full path for storing the file or an empty string if the type is not recognized.
|
||||
*/
|
||||
|
||||
function getUploadPath($type = "unknown", $filename = "hehe"): string
|
||||
function getUploadPath(string $type = "unknown", string $filename = "hehe"): string
|
||||
{
|
||||
$type = makePathSafe($type);
|
||||
$id = makePathSafe($_SESSION["ID"]);
|
||||
@ -202,6 +252,15 @@ function getUploadPath($type = "unknown", $filename = "hehe"): string
|
||||
return "";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Checks if a file with a given ID exists in the database and does permission checks.
|
||||
* Access is granted to only the user's files, in order to access all files the onlyMine parameter
|
||||
* must be false and the user must be a moderator.
|
||||
*
|
||||
* @param int $fileId The ID of the file to check.
|
||||
* @param bool $onlyMine Whether to limit the search to files uploaded by the logged-in user.
|
||||
* @return bool|string Returns the path of the file if it exists and meets the criteria, false otherwise.
|
||||
*/
|
||||
|
||||
function fileExists(int $fileId, bool $onlyMine = true): bool|string
|
||||
{
|
||||
@ -230,7 +289,14 @@ function fileExists(int $fileId, bool $onlyMine = true): bool|string
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a file to a specified group, if the user created the group or creates a new group if
|
||||
* a group with a specified ID does not exist yet
|
||||
*
|
||||
* @param int $groupId The ID of the group to which the file should be added.
|
||||
* @param int $fileId The ID of the file to add to the group.
|
||||
* @return array Returns an associative array with a 'Status' key indicating success or failure.
|
||||
*/
|
||||
function addToGroup(int $groupId, int $fileId): array
|
||||
{
|
||||
$output = ["Status" => "Fail"];
|
||||
@ -253,16 +319,22 @@ function addToGroup(int $groupId, int $fileId): array
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a file entry from the database and the file system, a user can only delete his own files,
|
||||
* except when he is a moderator, in that case he can delete all files.
|
||||
*
|
||||
* @param int $fileID The ID of the file to be deleted.
|
||||
* @return array Returns an array with a 'Status' key indicating the success or failure of the deletion operation.
|
||||
*/
|
||||
function deleteFile(int $fileID): array
|
||||
{
|
||||
global $mysqli;
|
||||
$out = ["Status" => "Fail"];
|
||||
if (isLoggedIn()) {
|
||||
$file_location = fileExists($fileID, !isAdmin());
|
||||
$query = !isAdmin() ? 'DELETE FROM Files WHERE ID = ? AND UploadedBy = ?' : 'DELETE FROM Files WHERE ID = ?';
|
||||
$file_location = fileExists($fileID, !isModerator());
|
||||
$query = !isModerator() ? 'DELETE FROM Files WHERE ID = ? AND UploadedBy = ?' : 'DELETE FROM Files WHERE ID = ?';
|
||||
$stmtDelete = $mysqli->prepare($query);
|
||||
if (!isAdmin()) {
|
||||
if (!isModerator()) {
|
||||
$stmtDelete->bind_param('ii', $fileID, $_SESSION['ID']);
|
||||
} else {
|
||||
$stmtDelete->bind_param('i', $fileID);
|
||||
|
Loading…
Reference in New Issue
Block a user