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,7 +1,8 @@
<!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">'); {
foreach($mainNav as $nav){ echo '<ul id="nav-mobile" class="right">';
echo('<li>'); foreach ($mainNav as $nav) {
echo('<a'); echo "<li>";
echo(' href="' . $nav['url']. '"'); echo "<a";
echo(' title="' . $nav['caption']. '"'); echo ' href="' . $nav["url"] . '"';
echo('>'); echo ' title="' . $nav["caption"] . '"';
echo('<span>'.$nav['caption'].'</span>'); echo ">";
echo('</a>'); echo "<span>" . $nav["caption"] . "</span>";
echo('</li>'); echo "</a>";
echo "</li>";
} }
echo('</ul>'); echo "</ul>";
} }
function main($sections, $wallpapers){ function main($sections, $wallpapers)
foreach($sections as $idx => $section){ {
echo( foreach ($sections as $idx => $section) {
'<div class="parallax-container">' echo '<div class="parallax-container">' .
.'<div class="parallax">' '<div class="parallax">' .
.'<img' "<img" .
. ' class="lazyload" ' ' class="lazyload" ' .
. ' src="'.$wallpapers[$idx]['src'].'" ' ' src="' .
. ' data-src="'.$wallpapers[$idx]['data-src'].'" ' $wallpapers[$idx]["src"] .
.'>' '" ' .
.'</div>' ' data-src="' .
.'</div>' $wallpapers[$idx]["data-src"] .
); '" ' .
echo( ">" .
'<div class="section">'.$section.'</div>' "</div>" .
); "</div>";
echo '<div class="section">' . $section . "</div>";
} }
} }
?> ?>
<html> <html>
@@ -101,7 +111,7 @@ function main($sections, $wallpapers){
<a href="/" class="brand-logo"> <a href="/" class="brand-logo">
<span>cwsvJudo</span> <span>cwsvJudo</span>
</a> </a>
<?php mainNavTargets($mainNav);?> <?php mainNavTargets($mainNav); ?>
</div> </div>
<!-- <div class="nav-content"> <!-- <div class="nav-content">
$if(subNav)$ $if(subNav)$
@@ -130,7 +140,7 @@ function main($sections, $wallpapers){
</header> </header>
<main> <main>
<?php main($sections, $wallpapers);?> <?php main($sections, $wallpapers); ?>
</main> </main>
<!--JavaScript at end of body for optimized loading--> <!--JavaScript at end of body for optimized loading-->
@@ -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,
@@ -23,187 +22,192 @@ class Connector
password: $password password: $password
); );
} }
// public // public
// - variables (none) // - variables (none)
// - functions // - functions
public function connect( public function connect(
string $hostname, string $hostname,
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
) )
); );
} }
// private // private
// - variables // - variables
/** /**
* pointer to the database connection * pointer to the database connection
* @var * @var
* *
* Handle to interact with the database * Handle to interact with the database
*/ */
private ?\PDO $db = null; private ?\PDO $db = null;
// - functions // - functions
/** @todo Docu /** @todo Docu
* Establish a connection to the database * Establish a connection to the database
* @param mixed $hostname * @param mixed $hostname
* @param mixed $dbName * @param mixed $dbName
* @param mixed $user * @param mixed $user
* @param mixed $password * @param mixed $password
* @return \PDO|null * @return \PDO|null
*/ */
private static function connectToPdo( private static function connectToPdo(
string $hostname, string $hostname,
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:" .
dsn: 'mysql:'.join( join(";", [
';', "host=" . $hostname,
[ "port=" . strval($port),
'host=' . $hostname, "dbname=" . $dbName,
'port=' . strval($port), ]),
'dbname=' . $dbName username: $user,
] password: $password
), );
username: $user, } catch (\PDOException $dbError) {
password: $password echo "Error whilst getting a dbConnection!: " .
); $dbError->getMessage();
} catch(\PDOException $dbError) { }
echo('Error whilst getting a dbConnection!: ' . $dbError->getMessage()); return $dbConnection;
} }
return $dbConnection;
}
public function getDbConnection() : \PDO|null public function getDbConnection(): \PDO|null
{ {
return $this->db; return $this->db;
} }
/// perform a \PDO-query /// perform a \PDO-query
/// ///
/// @param $aQueryString /// @param $aQueryString
/// @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 = [],
// Standardbelegungen array $options = []
if (empty($someOptions['dbCharset'])) { ) {
$someOptions['dbCharset'] = 'ISO-8859-1'; // Standardbelegungen
} if (empty($options["dbCharset"])) {
if (empty($someOptions['outCharset'])) { $options["dbCharset"] = "ISO-8859-1";
$someOptions['outCharset'] = 'UTF-8'; }
} if (empty($options["outCharset"])) {
if (empty($someOptions['dontFetch'])) { $options["outCharset"] = "UTF-8";
$someOptions['dontFetch'] = false; }
} if (empty($options["dontFetch"])) {
$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
/// umzustellen wird schwer! Die User im Wettkampfplaner sind ja z.B. /// umzustellen wird schwer! Die User im Wettkampfplaner sind ja z.B.
/// als UTF8 in latin1(?) gespeichert. /// als UTF8 in latin1(?) gespeichert.
/// @toDo: Die Standardwerte sollten vielleicht aus einer config /// @toDo: Die Standardwerte sollten vielleicht aus einer config
/// 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(); );
if (!$ignoreErrors && !$PDOResult) { }
echo("Error during dbQuery!\n"); $PDOResult = $PDOStatement->execute();
echo("DB-Error:\n"); if (!$ignoreErrors && !$PDOResult) {
var_dump(self::$db->errorInfo()); echo "Error during dbQuery!\n";
} echo "DB-Error:\n";
if ($someOptions['dontFetch']) { var_dump($this->getDbConnection()->errorInfo());
$ret = null; }
} else { if ($options["dontFetch"]) {
$ret = $PDOStatement->fetchAll(\PDO::FETCH_ASSOC); $ret = null;
} } else {
} catch(\PDOException $db_error) { $ret = $PDOStatement->fetchAll(\PDO::FETCH_ASSOC);
print 'Error!: ' . $db_error->getMessage() . '<br/>'; }
return null; } catch (\PDOException $db_error) {
} print "Error!: " . $db_error->getMessage() . "<br/>";
return null;
}
// Zeichensatzkonvertierung // Zeichensatzkonvertierung
if (is_array($ret)) { if (is_array($ret)) {
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"],
$someOptions $options["outCharset"],
); $value
} );
} },
return $ret; $options
} );
}
}
return $ret;
}
// @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)
private function setDbConnection($dbConnection): bool
{
$success = false;
if ($dbConnection instanceof \PDO) {
$this->db = $dbConnection;
$success = true;
} else {
$this->db = null;
}
return $success;
}
public static function debugEchoQuery($query, $params)
// set the dbConnection (just setting, no establishing) {
private function setDbConnection($dbConnection): bool foreach ($params as $key => $value) {
{ switch ($value["data_type"]) {
$success = false; case \PDO::PARAM_STR:
if ($dbConnection instanceof \PDO) { $query = str_replace(
self::$db = $dbConnection; $key,
$success = true; '\'' . $value["value"] . '\'',
} else { $query
self::$db = null; );
} default:
return $success; $query = str_replace($key, $value["value"], $query);
} }
}
public static function debugEchoQuery($query, $params) echo "query: " . $query . PHP_EOL;
{ }
foreach ($params as $key => $value) {
switch($value['data_type']) {
case \PDO::PARAM_STR:{
$query = str_replace($key, '\'' . $value['value'] . '\'', $query);
}
default:{
$query = str_replace($key, $value['value'], $query);
}
}
};
echo('query: ' . $query . PHP_EOL);
}
} }

View File

@@ -5,59 +5,65 @@ 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; {
$x=$y; $tmp = $x;
$y=$tmp; $x = $y;
$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(
$options = ["options"=>["flags"=> FILTER_NULL_ON_FAILURE]]; mixed $value,
?int $min = null,
?int $max = null
): ?int {
if (is_null($value)) {
return null;
}
$options = ["options" => ["flags" => FILTER_NULL_ON_FAILURE]];
if (!is_null($min) && !is_null($max)){ if (!is_null($min) && !is_null($max)) {
if( $min > $max ){ if ($min > $max) {
swap($min, $max); swap($min, $max);
} }
} }
if(!is_null($min)){ if (!is_null($min)) {
$options["options"]["min_range"] = $min; $options["options"]["min_range"] = $min;
} }
if(!is_null($max)){ if (!is_null($max)) {
$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,16 +74,17 @@ 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,
] ]
); );
if($data == false){ if ($data == false) {
return null; return null;
} }
@@ -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;
}