Added SVG to PNG conversion tool, Added tool page and code

Update .gitignore, sidebar.php, and 17 more files...
This commit is contained in:
2023-05-26 05:50:37 +02:00
parent e6e00ad02f
commit 6e9bf25866
19 changed files with 559 additions and 38 deletions

View File

@@ -41,7 +41,11 @@ function printSidebarEntry($url, $title, $icon) {
printSidebarEntry(l10n_url_abs('/content/?tags=electronic'), localize("sidebar.text.electronics"), "fad fa-microchip");
?>
</div>
<hr class="subtle">
<hr class="subtle">
<?php
printSidebarEntry(l10n_url_abs('/tools/'), localize("sidebar.text.tools"), "fad fa-tools");
?>
<hr class="subtle">
<?php
printSidebarEntry(l10n_url_abs('/links/'), localize("sidebar.text.links"), "fad fa-link");
?>

View File

@@ -10,7 +10,7 @@ $host_uri = "https://nibblepoker.lu";
$dir_commons = dirname(__FILE__);
$dir_root = realpath($dir_commons . "/../");
$config_dir_content = realpath($dir_commons . "/../" . "content/");
$config_dir_tools = realpath($dir_commons . "/../" . "content/");
$config_dir_tools = realpath($dir_commons . "/../" . "tools/");
// Optional features
$enable_grids = false;

View File

@@ -31,7 +31,7 @@ class ContentIndexEntry {
$this->priority = is_null($priority) ? 0 : $priority;
}
static function from_json(array $json_data) : ?ContentIndexEntry {
static function from_json(array $json_data): ?ContentIndexEntry {
if(!key_exists("id", $json_data)) {
return null;
}
@@ -70,7 +70,7 @@ class ContentManager {
if(!$this->hasError) {
if($this->displayType == ContentDisplayType::SEARCH) {
$this->loadRootIndex(realpath($contentRootPath . "/index.json"));
} else if($this->displayType == ContentDisplayType::CONTENT) {
} elseif($this->displayType == ContentDisplayType::CONTENT) {
$this->prepareContentFilePath($contentRootPath);
}
}
@@ -80,7 +80,7 @@ class ContentManager {
// Doing some dark magic whose inner workings are lost to times...
$requestedUrlPart = explode(
"?",
explode("#", preg_replace("^\/(content)^", "", $requestedUrl))[0]
explode("#", preg_replace("^\/(content|tools)^", "", $requestedUrl))[0]
)[0];
if(strcmp($requestedUrlPart, "/") == 0) {
@@ -111,7 +111,7 @@ class ContentManager {
}
} else {
$this->displayType = ContentDisplayType::CONTENT;
$this->requestedId = ltrim($requestedUrlPart, "/");
$this->requestedId = ltrim(rtrim($requestedUrlPart, "/"), "/");
}
}
@@ -154,7 +154,7 @@ class ContentManager {
}
// Sorting entries based on their priority
usort($this->rootIndexEntries, function (ContentIndexEntry $a, ContentIndexEntry $b) {
usort($this->rootIndexEntries, function(ContentIndexEntry $a, ContentIndexEntry $b) {
if($a->priority == $b->priority) {
return 0;
}
@@ -182,7 +182,7 @@ class ContentManager {
}
// Common utilities
function get_content_file_path(string $contentRootPath, string $contentId) : ?string {
function get_content_file_path(string $contentRootPath, string $contentId): ?string {
if(ctype_alnum(str_replace("-", "", $contentId))) {
return realpath($contentRootPath . "/items/" . $contentId . ".json");
}

124
commons/content/tools.php Normal file
View File

@@ -0,0 +1,124 @@
<?php
// Making sure the file is included and not accessed directly.
if(basename(__FILE__) == basename($_SERVER["SCRIPT_FILENAME"])) {
header('HTTP/1.1 403 Forbidden');
die();
}
// Including required helpers.
include_once 'commons/config.php';
include_once 'commons/langs.php';
include_once 'commons/content.php';
// Required to make headings
include_once 'commons/DOM/utils.php';
// Defining the template types.
class ToolInfoFile {
public string $domFile;
public ?string $langFile;
public array $codeFilesPaths;
public array $styleFilesPaths;
public string $icon;
public string $titleKey;
public ?string $subTitleKey;
function __construct(string $domFile, ?string $langFile, ?array $codeFilesPaths, ?array $styleFilesPaths,
?string $icon, ?string $titleKey, ?string $subTitleKey) {
$this->domFile = $domFile;
$this->langFile = $langFile;
$this->codeFilesPaths = is_null($codeFilesPaths) ? array() : $codeFilesPaths;
$this->styleFilesPaths = is_null($styleFilesPaths) ? array() : $styleFilesPaths;
$this->icon = is_null($icon) ? "fad fa-question" : $icon;
$this->titleKey = is_null($titleKey) ? "unset" : $titleKey;
$this->subTitleKey = $subTitleKey;
}
static function from_json(array $json_data): ?ToolInfoFile {
if(!key_exists("dom", $json_data)) {
return null;
}
return new ToolInfoFile(
$json_data["dom"],
key_exists("lang", $json_data) ? $json_data["lang"] : null,
key_exists("code", $json_data) ? $json_data["code"] : null,
key_exists("styles", $json_data) ? $json_data["styles"] : null,
key_exists("icon", $json_data) ? $json_data["icon"] : null,
key_exists("title", $json_data) ? $json_data["title"] : null,
key_exists("subtitle", $json_data) ? $json_data["subtitle"] : null
);
}
function validateFiles(ContentManager $contentManager): void {
if(!(file_exists($this->domFile) && is_file($this->domFile))) {
$contentManager->hasError = true;
$contentManager->errorMessageKey = "content.error.message.missing.file.dom";
return;
}
if(!is_null($this->langFile)) {
if(!(file_exists($this->langFile) && is_file($this->langFile))) {
$contentManager->hasError = true;
$contentManager->errorMessageKey = "content.error.message.missing.file.lang";
return;
}
}
foreach($this->codeFilesPaths as $codeFilePath) {
if(!(file_exists($codeFilePath) && is_file($codeFilePath))) {
$contentManager->hasError = true;
$contentManager->errorMessageKey = "content.error.message.missing.file.code";
return;
}
}
foreach($this->styleFilesPaths as $styleFilePath) {
if(!(file_exists($styleFilePath) && is_file($styleFilePath))) {
$contentManager->hasError = true;
$contentManager->errorMessageKey = "content.error.message.missing.file.style";
return;
}
}
}
}
abstract class ToolsContent {
static function loadItemIndexFile(ContentManager $contentManager, string $contentRootPath): ?ToolInfoFile {
// Preliminary check
if(!$contentManager->displayType == ContentDisplayType::CONTENT) {
$contentManager->hasError = true;
$contentManager->errorMessageKey = "content.error.message.cannot.load.item.as.not.content";
return null;
}
// Loading the index file
$itemIndexJsonData = json_decode(file_get_contents($contentManager->contentFilepath), true);
if(is_null($itemIndexJsonData)) {
return null;
}
$toolInfo = ToolInfoFile::from_json($itemIndexJsonData);
unset($itemIndexJsonData);
// Making paths absolute
if(!is_null($toolInfo)) {
$toolInfo->domFile = realpath($contentRootPath . "/items/" . $toolInfo->domFile);
if(!is_null($toolInfo->langFile)) {
$toolInfo->langFile = realpath($contentRootPath . "/items/" . $toolInfo->langFile);
}
for($iCodeFilePath = 0; $iCodeFilePath < count($toolInfo->codeFilesPaths); $iCodeFilePath++) {
$toolInfo->codeFilesPaths[$iCodeFilePath] = realpath(
$contentRootPath . "/items/" . $toolInfo->codeFilesPaths[$iCodeFilePath]);
}
for($iStyleFilePath = 0; $iStyleFilePath < count($toolInfo->styleFilesPaths); $iStyleFilePath++) {
$toolInfo->styleFilesPaths[$iStyleFilePath] = realpath(
$contentRootPath . "/items/" . $toolInfo->styleFilesPaths[$iStyleFilePath]);
}
} else {
$contentManager->hasError = true;
$contentManager->errorMessageKey = "content.error.message.cannot.load";
}
return $toolInfo;
}
}
?>

File diff suppressed because one or more lines are too long

View File

@@ -32,11 +32,18 @@
"content.error.message.id.alphanumeric": "The requested resource's ID isn't a valid alphanumeric string.",
"content.error.message.data.not.exist": "The requested content doesn't have an internal item file associated to it.",
"content.error.message.cannot.load": "The requested content couldn't be loaded on our end !",
"__": "Messages returned by 'commons/composer.php'",
"content.error.message.data.no.tags": "No tags found !",
"content.error.message.data.no.title": "No title found !",
"___": "Messages returned by 'commons/content/tools.php'",
"_content.error.message.cannot.load.item.as.not.content": "",
"_content.error.message.missing.file.dom": "",
"_content.error.message.missing.file.lang": "",
"_content.error.message.missing.file.code": "",
"_content.error.message.missing.file.style": "",
"content.item.head.title.prefix": "",
"content.item.head.title.suffix": " - NibblePoker",

View File

@@ -5,6 +5,7 @@
"sidebar.text.applications": "Applications",
"sidebar.text.libraries": "Libraries",
"sidebar.text.electronics": "Electronics",
"sidebar.text.tools": "Tools",
"sidebar.text.links": "Links",
"sidebar.text.downloads": "Downloads",
"sidebar.text.gitea": "Git Repos.",

View File

@@ -5,6 +5,7 @@
"sidebar.text.applications": "Applications",
"sidebar.text.libraries": "Librairies",
"sidebar.text.electronics": "Électronique",
"sidebar.text.tools": "Outils",
"sidebar.text.links": "Liens",
"sidebar.text.downloads": "Téléchargements",
"sidebar.text.gitea": "Dépôts Git",