WIP refactoring newsLib - not pretty, but news ar on the testpage

This commit is contained in:
marko
2025-05-11 18:57:34 +02:00
parent 003310623f
commit 107bdf4fdb
6 changed files with 402 additions and 247 deletions

View File

@@ -51,6 +51,7 @@ ampTest: $(ampFiles)
INSTALL_DEPENDENCIES: INSTALL_DEPENDENCIES:
npm install csso-cli npm install csso-cli
npm install --save-dev --save-exact prettier npm install --save-dev --save-exact prettier
npm install --save-dev prettier @prettier/plugin-php
build/css/cwsvJudo.css: $(cssFiles) build/css/cwsvJudo.css: $(cssFiles)
cat $^ | $(CSSO) -o $@ cat $^ | $(CSSO) -o $@

View File

@@ -0,0 +1,22 @@
<?php
require_once "config.php";
require_once "phpLibs/cwsvJudo/dbConnector.php";
require_once "phpLibs/cwsvJudo/news.php";
$config = json_decode(
json: file_get_contents(filename: $home . "/.local/config.json"),
associative: true
);
$secrets = json_decode(
json: file_get_contents(filename: $home . "/.local/secrets.json"),
associative: true
);
$dbHandle = new \CwsvJudo\Db\Connector(
hostname: $config["cwsvJudo"]["db"]["host"],
dbName: $config["cwsvJudo"]["db"]["name"],
user: $config["cwsvJudo"]["db"]["user"],
password: $secrets["cwsvJudo"]["db"][$config["cwsvJudo"]["db"]["user"]]
);

View File

@@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<?php <?php
require_once "bootstrap.php";
$directory_paths = [ $directory_paths = [
"wallpapers" => "/ressourcen/graphiken/wallpapers", "wallpapers" => "/ressourcen/graphiken/wallpapers",
@@ -9,32 +10,40 @@ $mainNav = [
[ [
"url" => "training", "url" => "training",
"caption" => "Training", "caption" => "Training",
"title" => "Trainingszeiten und -orte der Judoka des Chemnitzer WSV" "title" => "Trainingszeiten und -orte der Judoka des Chemnitzer WSV",
] ],
]; ];
$sections = [ $sections = [
"Lorem ipsum", \CwsvJudo\News\newsBoard(
dbHandle: $dbHandle,
options: [
"limit" => 6,
// "dbCharset" => "ISO-8859-1",
"dbCharset" => "UTF-8",
// "outCharset" => "ISO-8859-1",
"outCharset" => "UTF-8",
]
),
"dolor sit amet", "dolor sit amet",
"consectetur adipiscing elit" "consectetur adipiscing elit",
]; ];
$wallpapers = [ $wallpapers = [
[ [
"src" => $directory_paths['wallpapers']. "/osae-komi.svg", "src" => $directory_paths["wallpapers"] . "/osae-komi.svg",
"data-src" => $directory_paths['wallpapers']. "/osae-komi.jpg" "data-src" => $directory_paths["wallpapers"] . "/osae-komi.jpg",
], ],
[ [
"src" => $directory_paths['wallpapers']. "/nage.svg", "src" => $directory_paths["wallpapers"] . "/nage.svg",
"data-src" => $directory_paths['wallpapers']. "/nage.jpg" "data-src" => $directory_paths["wallpapers"] . "/nage.jpg",
], ],
[ [
"src" => $directory_paths['wallpapers']. "/kata.svg", "src" => $directory_paths["wallpapers"] . "/kata.svg",
"data-src" => $directory_paths['wallpapers']. "/kata.jpg" "data-src" => $directory_paths["wallpapers"] . "/kata.jpg",
], ],
]; ];
// helper functions // helper functions
// -html output // -html output
@@ -43,40 +52,41 @@ $wallpapers = [
* @param mixed $mainNav * @param mixed $mainNav
* @return void * @return void
*/ */
function mainNavTargets($mainNav){ function mainNavTargets($mainNav)
echo('<ul id="nav-mobile" class="right">'); {
echo '<ul id="nav-mobile" class="right">';
foreach ($mainNav as $nav) { foreach ($mainNav as $nav) {
echo('<li>'); echo "<li>";
echo('<a'); echo "<a";
echo(' href="' . $nav['url']. '"'); echo ' href="' . $nav["url"] . '"';
echo(' title="' . $nav['caption']. '"'); echo ' title="' . $nav["caption"] . '"';
echo('>'); echo ">";
echo('<span>'.$nav['caption'].'</span>'); echo "<span>" . $nav["caption"] . "</span>";
echo('</a>'); echo "</a>";
echo('</li>'); echo "</li>";
} }
echo('</ul>'); echo "</ul>";
} }
function main($sections, $wallpapers){ function main($sections, $wallpapers)
{
foreach ($sections as $idx => $section) { foreach ($sections as $idx => $section) {
echo( echo '<div class="parallax-container">' .
'<div class="parallax-container">' '<div class="parallax">' .
.'<div class="parallax">' "<img" .
.'<img' ' class="lazyload" ' .
. ' class="lazyload" ' ' src="' .
. ' src="'.$wallpapers[$idx]['src'].'" ' $wallpapers[$idx]["src"] .
. ' data-src="'.$wallpapers[$idx]['data-src'].'" ' '" ' .
.'>' ' data-src="' .
.'</div>' $wallpapers[$idx]["data-src"] .
.'</div>' '" ' .
); ">" .
echo( "</div>" .
'<div class="section">'.$section.'</div>' "</div>";
); echo '<div class="section">' . $section . "</div>";
} }
} }
?> ?>
<html> <html>
@@ -147,7 +157,15 @@ function main($sections, $wallpapers){
const instances = M.Parallax.init(elems, { const instances = M.Parallax.init(elems, {
// specify options here // specify options here
}); });
})
// const elems = document.querySelectorAll('.carousel');
// const instances = M.Carousel.init(elems, {
// // fullWidth: true,
// // indicators: true,
// // noWrap: true,
// // numVisible: 6,
// });
});
</script> </script>
</body> </body>

View File

@@ -21,19 +21,15 @@ $dbHandle = new \CwsvJudo\Db\Connector(
password: $secrets['cwsvJudo']['db'][$config['cwsvJudo']['db']['user']] password: $secrets['cwsvJudo']['db'][$config['cwsvJudo']['db']['user']]
); );
// try { var_dump(
// $conn = new PDO( \CwsvJudo\News\newsBoard(
// dsn: join(separator: ";",array: [ dbHandle: $dbHandle,
// "mysql:host=".$config['cwsvJudo']['db']['host'], options: [
// "port=3306", 'limit' => 6,
// "dbname=".$config['cwsvJudo']['db']['name'] // "dbCharset" => "ISO-8859-1",
// ]), "dbCharset" => "UTF-8",
// username: $config['cwsvJudo']['db']['user'], // "outCharset" => "ISO-8859-1",
// password: $secrets['cwsvJudo']['db'][$config['cwsvJudo']['db']['user']] "outCharset" => "UTF-8",
// ); ],
// // set the PDO error mode to exception )
// $conn->setAttribute(attribute: PDO::ATTR_ERRMODE, value: PDO::ERRMODE_EXCEPTION); );
// echo "Connected successfully";
// } catch(PDOException $e) {
// echo "Connection failed: " . $e->getMessage();
// }

View File

@@ -12,9 +12,8 @@ class Connector
string $dbName, string $dbName,
string $user, string $user,
string $password, string $password,
int $port=3306, int $port = 3306
) ) {
{
$this->db = self::connectToPdo( $this->db = self::connectToPdo(
hostname: $hostname, hostname: $hostname,
port: $port, port: $port,
@@ -31,15 +30,14 @@ class Connector
string $dbName, string $dbName,
string $user, string $user,
string $password, string $password,
int $port = 3306, int $port = 3306
): bool ): bool {
{
return self::setDbConnection( return self::setDbConnection(
dbConnection: self::connectToPdo( dbConnection: self::connectToPdo(
hostname: $hostname, hostname: $hostname,
dbName: $dbName, dbName: $dbName,
user: $user, user: $user,
password: $password, password: $password
) )
); );
} }
@@ -66,25 +64,23 @@ class Connector
string $dbName, string $dbName,
string $user, string $user,
string $password, string $password,
int $port = 3306, int $port = 3306
): \PDO|null ): \PDO|null {
{
$dbConnection = null; $dbConnection = null;
try { try {
$dbConnection = new \PDO( $dbConnection = new \PDO(
dsn: 'mysql:'.join( dsn: "mysql:" .
';', join(";", [
[ "host=" . $hostname,
'host=' . $hostname, "port=" . strval($port),
'port=' . strval($port), "dbname=" . $dbName,
'dbname=' . $dbName ]),
]
),
username: $user, username: $user,
password: $password password: $password
); );
} catch (\PDOException $dbError) { } catch (\PDOException $dbError) {
echo('Error whilst getting a dbConnection!: ' . $dbError->getMessage()); echo "Error whilst getting a dbConnection!: " .
$dbError->getMessage();
} }
return $dbConnection; return $dbConnection;
} }
@@ -100,22 +96,24 @@ class Connector
/// @param $aBindArray e.g. array( /// @param $aBindArray e.g. array(
/// ':userId' => array('value'=>$anUserId, 'data_type'=>\PDO::PARAM_INT), /// ':userId' => array('value'=>$anUserId, 'data_type'=>\PDO::PARAM_INT),
/// ':attributeId'=> array('value'=>$anAttributeId, 'data_type'=>\PDO::PARAM_INT) ) /// ':attributeId'=> array('value'=>$anAttributeId, 'data_type'=>\PDO::PARAM_INT) )
/// @param $someOption /// @param $options
public static function query($aQueryString, $aBindArray = [], $someOptions = []) public function query(
{ string $aQueryString,
// var_dump($aQueryString, $aBindArray); array $aBindArray = [],
array $options = []
) {
// Standardbelegungen // Standardbelegungen
if (empty($someOptions['dbCharset'])) { if (empty($options["dbCharset"])) {
$someOptions['dbCharset'] = 'ISO-8859-1'; $options["dbCharset"] = "ISO-8859-1";
} }
if (empty($someOptions['outCharset'])) { if (empty($options["outCharset"])) {
$someOptions['outCharset'] = 'UTF-8'; $options["outCharset"] = "UTF-8";
} }
if (empty($someOptions['dontFetch'])) { if (empty($options["dontFetch"])) {
$someOptions['dontFetch'] = false; $options["dontFetch"] = false;
} }
$ignoreErrors = $someOptions['ignoreErrors'] ?? false; $ignoreErrors = $options["ignoreErrors"] ?? false;
/// @toDo: Bisher wird nur die Rückgabe konvertiert. Eigentlich muss /// @toDo: Bisher wird nur die Rückgabe konvertiert. Eigentlich muss
/// doch auch die Eingabe konvertiert werden. Aber das jetzt /// doch auch die Eingabe konvertiert werden. Aber das jetzt
@@ -125,34 +123,36 @@ class Connector
/// kommen, nicht hardcoded /// kommen, nicht hardcoded
try { try {
$PDOStatement = self::$db->prepare($aQueryString); $PDOStatement = $this->getDbConnection()->prepare($aQueryString);
foreach ($aBindArray as $bindName => $bind) { foreach ($aBindArray as $bindName => $bind) {
if ($bind['data_type'] == \PDO::PARAM_STR) { if ($bind["data_type"] == \PDO::PARAM_STR) {
$bind['value'] = iconv( $bind["value"] = iconv(
$someOptions['outCharset'], $options["outCharset"],
$someOptions['dbCharset'], $options["dbCharset"],
$bind['value'] $bind["value"]
); );
} }
$PDOStatement->bindValue( $PDOStatement->bindValue(
$bindName, $bindName,
$bind['value'], $bind["value"],
(isset($bind['data_type']) ? $bind['data_type'] : \PDO::PARAM_STR) isset($bind["data_type"])
? $bind["data_type"]
: \PDO::PARAM_STR
); );
} }
$PDOResult = $PDOStatement->execute(); $PDOResult = $PDOStatement->execute();
if (!$ignoreErrors && !$PDOResult) { if (!$ignoreErrors && !$PDOResult) {
echo("Error during dbQuery!\n"); echo "Error during dbQuery!\n";
echo("DB-Error:\n"); echo "DB-Error:\n";
var_dump(self::$db->errorInfo()); var_dump($this->getDbConnection()->errorInfo());
} }
if ($someOptions['dontFetch']) { if ($options["dontFetch"]) {
$ret = null; $ret = null;
} else { } else {
$ret = $PDOStatement->fetchAll(\PDO::FETCH_ASSOC); $ret = $PDOStatement->fetchAll(\PDO::FETCH_ASSOC);
} }
} catch (\PDOException $db_error) { } catch (\PDOException $db_error) {
print 'Error!: ' . $db_error->getMessage() . '<br/>'; print "Error!: " . $db_error->getMessage() . "<br/>";
return null; return null;
} }
@@ -161,10 +161,14 @@ class Connector
foreach ($ret as &$entry) { foreach ($ret as &$entry) {
array_walk( array_walk(
$entry, $entry,
function (&$value, $key, $someOptions) { function (&$value, $key, $options) {
$value = iconv($someOptions['dbCharset'], $someOptions['outCharset'], $value); $value = iconv(
$options["dbCharset"],
$options["outCharset"],
$value
);
}, },
$someOptions $options
); );
} }
} }
@@ -172,22 +176,20 @@ class Connector
} }
// @todo docu // @todo docu
public static function getLastInsertId() public function getLastInsertId()
{ {
return self::$db->lastInsertId(); return $this->getDbConnection()->lastInsertId();
} }
// set the dbConnection (just setting, no establishing) // set the dbConnection (just setting, no establishing)
private function setDbConnection($dbConnection): bool private function setDbConnection($dbConnection): bool
{ {
$success = false; $success = false;
if ($dbConnection instanceof \PDO) { if ($dbConnection instanceof \PDO) {
self::$db = $dbConnection; $this->db = $dbConnection;
$success = true; $success = true;
} else { } else {
self::$db = null; $this->db = null;
} }
return $success; return $success;
} }
@@ -195,15 +197,17 @@ class Connector
public static function debugEchoQuery($query, $params) public static function debugEchoQuery($query, $params)
{ {
foreach ($params as $key => $value) { foreach ($params as $key => $value) {
switch($value['data_type']) { switch ($value["data_type"]) {
case \PDO::PARAM_STR:{ case \PDO::PARAM_STR:
$query = str_replace($key, '\'' . $value['value'] . '\'', $query); $query = str_replace(
} $key,
default:{ '\'' . $value["value"] . '\'',
$query = str_replace($key, $value['value'], $query); $query
);
default:
$query = str_replace($key, $value["value"], $query);
} }
} }
}; echo "query: " . $query . PHP_EOL;
echo('query: ' . $query . PHP_EOL);
} }
} }

View File

@@ -5,14 +5,22 @@ namespace CwsvJudo\News;
use DateTime; use DateTime;
// swap the values of two variables // swap the values of two variables
function swap(mixed &$x, mixed &$y) : void{ function swap(mixed &$x, mixed &$y): void
{
$tmp = $x; $tmp = $x;
$x = $y; $x = $y;
$y = $tmp; $y = $tmp;
} }
// input sanitation for integers in a range // input sanitation for integers in a range
function filter_integer_range(mixed $value, ?int $min = null, ?int $max = null) : ?int { function filter_integer_range(
mixed $value,
?int $min = null,
?int $max = null
): ?int {
if (is_null($value)) {
return null;
}
$options = ["options" => ["flags" => FILTER_NULL_ON_FAILURE]]; $options = ["options" => ["flags" => FILTER_NULL_ON_FAILURE]];
if (!is_null($min) && !is_null($max)) { if (!is_null($min) && !is_null($max)) {
@@ -29,35 +37,33 @@ function filter_integer_range(mixed $value, ?int $min = null, ?int $max = null)
$options["options"]["max_range"] = $max; $options["options"]["max_range"] = $max;
} }
return filter_var( return filter_var($value, FILTER_VALIDATE_INT, $options);
$value,
FILTER_VALIDATE_INT,
$options,
);
} }
// input sanitation for integers // input sanitation for integers
function filter_integer(mixed $value) : ?int { function filter_integer(mixed $value): ?int
{
return filter_integer_range($value); return filter_integer_range($value);
} }
// input sanitation for id-s // input sanitation for id-s
function filter_id(mixed $value, int $min = 0) : ?int { function filter_id(mixed $value, int $min = 0): ?int
{
return filter_integer_range($value, $min, null); return filter_integer_range($value, $min, null);
} }
// input sanitation for URL // input sanitation for URL
function filter_url(mixed $value){ function filter_url(mixed $value)
return filter_var( {
$value, return filter_var($value, FILTER_VALIDATE_URL, [
FILTER_VALIDATE_URL, "options" => ["flags" => FILTER_NULL_ON_FAILURE],
["options" => ["flags" => FILTER_NULL_ON_FAILURE]] ]);
);
} }
class PromoImage { class PromoImage
{
public function __construct(array $data) { public function __construct(array $data)
{
$this->src = filter_url($data["src"]); $this->src = filter_url($data["src"]);
$this->height = filter_integer_range( $this->height = filter_integer_range(
value: $data["height"], value: $data["height"],
@@ -68,12 +74,13 @@ class PromoImage {
$this->data = $data; $this->data = $data;
} }
public function to_json(): string|null{ public function to_json(): string|null
{
$data = json_encode( $data = json_encode(
value: [ value: [
"src" => $this->src, "src" => $this->src,
"width" => $this->width, "width" => $this->width,
"height" => $this->height "height" => $this->height,
] ]
); );
@@ -92,10 +99,34 @@ class PromoImage {
} }
// a single news entry // a single news entry
class Entry{ class Entry
{
// public // public
// - functions // - functions
function __construct(array $data)
{
$this->id = filter_id($data["nr"]);
$this->date = new \DateTime($data["datum"]);
$this->title = $data["betreff"];
$this->content = $data["nachricht"];
$this->author = $data["autor"];
// $this->promo = new PromoImage(
// json_encode($data["promoImg"]));
}
function as_card(): string
{
return '<div class="col s12 m6 l3"><div class="card">' .
'<div class="card-content">' .
'<span class="card-title">' .
$this->title .
"</span>" .
"<p>" .
$this->content .
"</p>" .
"</div>" .
"</div></div>";
}
// private // private
// - member variables // - member variables
private int $id; private int $id;
@@ -105,3 +136,86 @@ class Entry{
private string $author; private string $author;
private PromoImage $promo; private PromoImage $promo;
} }
/// Eine Liste mit News abfragen
///
/// Der Rückgabewert sollte vor Verwendung (und zur Fehlerbeheandlung)
/// auf NULL und/oder leeres Array getestet werden.
/// Der Zeichensatz wird von "ISO-8859-1" auf "UTF-8" gesetzt
///
/// @return Array mit News (die wiederum assoziative arrays sind
function getNews(
\CwsvJudo\Db\Connector $dbHandle,
array $options = [
"dbCharset" => "ISO-8859-1",
"outCharset" => "UTF-8",
"limit" => "1",
]
): array|null {
if (!$dbHandle->getDbConnection()) {
return null;
}
if (empty($options["dbCharset"])) {
$options["dbCharset"] = "ISO-8859-1";
}
if (empty($options["outCharset"])) {
$options["outCharset"] = "UTF-8";
}
$newsId = filter_id($options["newsId"] ?? null);
$limit = filter_id($options["limit"] ?? 1);
$year = filter_id($options["jahr"] ?? null);
$query = "SELECT * FROM nachrichten ";
$bindArray = [
":limit" => ["value" => $limit, "data_type" => \PDO::PARAM_INT],
];
// Falls eine konkrete newsId angegeben wurde, wollen wir ab dieser News haben
if (!is_null($newsId)) {
$query .=
"WHERE nachrichten.datum <= (SELECT nachrichten.datum FROM nachrichten WHERE nachrichten.nr = :newsId ) ORDER BY nachrichten.datum DESC LIMIT :limit OFFSET 0;";
$bindArray[":newsId"] = [
"value" => $newsId,
"data_type" => \PDO::PARAM_INT,
];
}
// Ansonsten die aktuellsten
else {
if (!is_null($year)) {
$query .= " WHERE DATE_FORMAT( datum, '%Y') = :year";
$bindArray["year"] = [
"value" => $year,
"data_type" => \PDO::PARAM_INT,
];
}
$query .= " ORDER BY datum DESC, nr DESC LIMIT :limit;";
}
$ret = $dbHandle->query(
aQueryString: $query,
aBindArray: $bindArray,
options: [
"dbCharset" => $options["dbCharset"],
"outCharset" => $options["outCharset"],
]
);
return $ret;
}
function newsBoard(\CwsvJudo\Db\Connector $dbHandle, array $options): string
{
$boardHtml = '<div class="container"><div class="row">';
$entries = getNews(dbHandle: $dbHandle, options: $options);
if (!is_null($entries)) {
foreach ($entries as $entryData) {
$entry = new \CwsvJudo\News\Entry($entryData);
$boardHtml .= $entry->as_card();
}
}
$boardHtml .= "</div></div>";
return $boardHtml;
}