WIP refactoring newsLib - successfull connection to db

This commit is contained in:
marko
2025-05-11 15:02:19 +02:00
parent 91c0b3ba7a
commit 003310623f
7 changed files with 470 additions and 39 deletions

View File

@@ -16,15 +16,16 @@ LN = ln -f
.PHONY: all
all: build/css/cwsvJudo.css pages images
# @todo This should only be temporary. Better outsource the graphics to it's own Makefile.
# @todo This should only be temporary. Better outsource the graphics to it's own Makefile.
make -j graphiken
make build/css/cwsvJudo.css
# minimizing wallpaper sizes
build/graphiken/wallpapers/%.jpg: graphiken/wallpapers/%.jpg
guetzli $^ $@
# guetzli $^ $@
$(LN) $^ $@
build/graphiken/wallpapers/%.svg: graphiken/wallpapers/%.svg
cp $^ $@
$(LN) $^ $@
.PHONY: images
images: $(wallpapers)
@@ -37,7 +38,7 @@ clean:
$(RM) -rf build
.PHONY: installDependencies
installDependencies:
installDependencies:
if [ ! -d "submodules" ]; then mkdir submodules; fi
# - nodejs
# - maybye needed to get latest nodejs version for some features
@@ -48,7 +49,7 @@ installDependencies:
cd submodules/materialize; git fetch; git checkout $(VERSION_MATERIALIZE); npm install; npm audit fix; npm run release;
# - google material icons
mkdir -p submodules/google-material-icons
if [ ! -f submodules/google-material-icons/$(GOOGLE_MATERIAL_ICONS_VERSION).tar.gz ]; then wget --directory-prefix=submodules/google-material-icons $(GOOGLE_MATERIAL_ICONS_URL)/archive/refs/tags/$(GOOGLE_MATERIAL_ICONS_VERSION).tar.gz; fi
if [ ! -f submodules/google-material-icons/$(GOOGLE_MATERIAL_ICONS_VERSION).tar.gz ]; then wget --directory-prefix=submodules/google-material-icons $(GOOGLE_MATERIAL_ICONS_URL)/archive/refs/tags/$(GOOGLE_MATERIAL_ICONS_VERSION).tar.gz; fi
cd submodules/google-material-icons; tar zxf $(GOOGLE_MATERIAL_ICONS_VERSION).tar.gz material-design-icons-$(GOOGLE_MATERIAL_ICONS_VERSION)/font
# - lazyload (load small sized placeholder image before loading large full quality image)
if [ ! -d "submodules/lazysizes" ]; then cd submodules; git clone https://github.com/aFarkas/lazysizes.git; fi
@@ -81,6 +82,13 @@ dist: all
mkdir -p $(distDir)/httpdocs/pages/shared
find ./src/shared/ -type f -exec $(LN) {} $(distDir)/httpdocs/pages/shared \;
# testing/development pages
mkdir -p $(distDevPages)
mkdir -p $(distDevPages)/phpLibs/cwsvJudo
find src/pages/test -type f -exec $(LN) {} $(distDevPages) \;
find src/pages/test/phpLibs/cwsvJudo -type f -exec $(LN) {} $(distDevPages)/phpLibs/cwsvJudo \;
# structured data
mkdir -p $(distDir)/httpdocs/ressourcen/structuredData/json
find src/jsonSd -type f -exec $(LN) {} $(distDir)/httpdocs/ressourcen/structuredData/json \;
@@ -116,8 +124,6 @@ dist: all
# css
mkdir -p $(distDir)/httpdocs/ressourcen/css
$(LN) ./build/css/cwsvJudo.css $(distDir)/httpdocs/ressourcen/css/cwsvJudo.css
# testing/development
mkdir -p $(distDir)/httpdocs/pages/test
# fonts
mkdir -p $(distDir)/httpdocs/ressourcen/fonts
@@ -131,19 +137,12 @@ dist: all
# config files
$(LN) ./configs/heliohost/pages.config.inc.php $(distDir)/httpdocs/pages/responsive/config.inc.php
# new test page
mkdir -p $(distDir)/httpdocs/test
find ./src/pages/test -type f -exec $(LN) {} $(distDir)/httpdocs/test \;
# @todo shouldn't be used any more
mkdir -p $(distDir)/.local
$(LN) configs/heliohost/config.json $(distDir)/.local/config.json
$(LN) configs/heliohost/secrets.json $(distDir)/.local/secrets.json
$(LN) configs/local/db.config.php $(distDir)/.local/db.config.php
# testing/development
mkdir -p $(distDir)/httpdocs/pages/test
find src/pages/test -type f -exec $(LN) {} $(distDir)/httpdocs/pages/test \;
docker-compose restart
@@ -181,4 +180,3 @@ build/css/cwsvJudo.css: $(cssFiles)
.PHONY: upload
upload: all
lftp -f scripts/upload-heliohost

View File

@@ -13,7 +13,12 @@ GOOGLE_MATERIAL_ICONS_VERSION = 4.0.0
VERSION_LAZYSIZES = 5.3.1
# where to put the distribution
# - the root directory of the page structure
distDir = ./build/dist/heliohost
# - root directory for the web pages
distWebRoot = $(distDir)/httpdocs
# - development pages
distDevPages = $(distWebRoot)/testing
# css optimizer to use
CSSO = node_modules/csso-cli/bin/csso

View File

@@ -1,7 +1,8 @@
<?
require_once("config.php");
require_once("phpLibs/cwsvjudo/news.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"),
@@ -13,20 +14,26 @@ $secrets = json_decode(
associative: true
);
try {
$conn = new PDO(
dsn: join(separator: ";",array: [
"mysql:host=".$config['cwsvJudo']['db']['host'],
"port=3306",
"dbname=".$config['cwsvJudo']['db']['name']
]),
username: $config['cwsvJudo']['db']['user'],
$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']]
);
// 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();
}
);
// try {
// $conn = new PDO(
// dsn: join(separator: ";",array: [
// "mysql:host=".$config['cwsvJudo']['db']['host'],
// "port=3306",
// "dbname=".$config['cwsvJudo']['db']['name']
// ]),
// username: $config['cwsvJudo']['db']['user'],
// password: $secrets['cwsvJudo']['db'][$config['cwsvJudo']['db']['user']]
// );
// // 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

@@ -0,0 +1,209 @@
<?php
namespace CwsvJudo\Db;
/**
* interface for connecting and communicating with a database
*/
class Connector
{
public function __construct(
string $hostname,
string $dbName,
string $user,
string $password,
int $port=3306,
)
{
$this->db = self::connectToPdo(
hostname: $hostname,
port: $port,
dbName: $dbName,
user: $user,
password: $password
);
}
// public
// - variables (none)
// - functions
public function connect(
string $hostname,
string $dbName,
string $user,
string $password,
int $port = 3306,
): bool
{
return self::setDbConnection(
dbConnection: self::connectToPdo(
hostname: $hostname,
dbName: $dbName,
user: $user,
password: $password,
)
);
}
// private
// - variables
/**
* pointer to the database connection
* @var
*
* Handle to interact with the database
*/
private ?\PDO $db = null;
// - functions
/** @todo Docu
* Establish a connection to the database
* @param mixed $hostname
* @param mixed $dbName
* @param mixed $user
* @param mixed $password
* @return \PDO|null
*/
private static function connectToPdo(
string $hostname,
string $dbName,
string $user,
string $password,
int $port = 3306,
): \PDO|null
{
$dbConnection = null;
try {
$dbConnection = new \PDO(
dsn: 'mysql:'.join(
';',
[
'host=' . $hostname,
'port=' . strval($port),
'dbname=' . $dbName
]
),
username: $user,
password: $password
);
} catch(\PDOException $dbError) {
echo('Error whilst getting a dbConnection!: ' . $dbError->getMessage());
}
return $dbConnection;
}
public function getDbConnection() : \PDO|null
{
return $this->db;
}
/// perform a \PDO-query
///
/// @param $aQueryString
/// @param $aBindArray e.g. array(
/// ':userId' => array('value'=>$anUserId, 'data_type'=>\PDO::PARAM_INT),
/// ':attributeId'=> array('value'=>$anAttributeId, 'data_type'=>\PDO::PARAM_INT) )
/// @param $someOption
public static function query($aQueryString, $aBindArray = [], $someOptions = [])
{
// var_dump($aQueryString, $aBindArray);
// Standardbelegungen
if (empty($someOptions['dbCharset'])) {
$someOptions['dbCharset'] = 'ISO-8859-1';
}
if (empty($someOptions['outCharset'])) {
$someOptions['outCharset'] = 'UTF-8';
}
if (empty($someOptions['dontFetch'])) {
$someOptions['dontFetch'] = false;
}
$ignoreErrors = $someOptions['ignoreErrors'] ?? false;
/// @toDo: Bisher wird nur die Rückgabe konvertiert. Eigentlich muss
/// doch auch die Eingabe konvertiert werden. Aber das jetzt
/// umzustellen wird schwer! Die User im Wettkampfplaner sind ja z.B.
/// als UTF8 in latin1(?) gespeichert.
/// @toDo: Die Standardwerte sollten vielleicht aus einer config
/// kommen, nicht hardcoded
try {
$PDOStatement = self::$db->prepare($aQueryString);
foreach ($aBindArray as $bindName => $bind) {
if ($bind['data_type'] == \PDO::PARAM_STR) {
$bind['value'] = iconv(
$someOptions['outCharset'],
$someOptions['dbCharset'],
$bind['value']
);
}
$PDOStatement->bindValue(
$bindName,
$bind['value'],
(isset($bind['data_type']) ? $bind['data_type'] : \PDO::PARAM_STR)
);
}
$PDOResult = $PDOStatement->execute();
if (!$ignoreErrors && !$PDOResult) {
echo("Error during dbQuery!\n");
echo("DB-Error:\n");
var_dump(self::$db->errorInfo());
}
if ($someOptions['dontFetch']) {
$ret = null;
} else {
$ret = $PDOStatement->fetchAll(\PDO::FETCH_ASSOC);
}
} catch(\PDOException $db_error) {
print 'Error!: ' . $db_error->getMessage() . '<br/>';
return null;
}
// Zeichensatzkonvertierung
if (is_array($ret)) {
foreach ($ret as &$entry) {
array_walk(
$entry,
function (&$value, $key, $someOptions) {
$value = iconv($someOptions['dbCharset'], $someOptions['outCharset'], $value);
},
$someOptions
);
}
}
return $ret;
}
// @todo docu
public static function getLastInsertId()
{
return self::$db->lastInsertId();
}
// set the dbConnection (just setting, no establishing)
private function setDbConnection($dbConnection): bool
{
$success = false;
if ($dbConnection instanceof \PDO) {
self::$db = $dbConnection;
$success = true;
} else {
self::$db = null;
}
return $success;
}
public static function debugEchoQuery($query, $params)
{
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

@@ -1,16 +1,20 @@
<?php
namespace cwsvJudo\News;
namespace CwsvJudo\News;
use DateTime;
// swap the values of two variables
function swap(mixed &$x, mixed &$y) : void{
$tmp=$x;
$x=$y;
$y=$tmp;
}
// input sanitation for integers in a range
function filter_integer_range(mixed $value, ?int $min = null, ?int $max = null) : ?int {
$options = ["options"=>["flags"=> FILTER_NULL_ON_FAILURE]];
if (!is_null($min) && !is_null($max)){
if( $min > $max ){
swap($min, $max);
@@ -30,17 +34,19 @@ function filter_integer_range(mixed $value, ?int $min = null, ?int $max = null)
FILTER_VALIDATE_INT,
$options,
);
}
// input sanitation for integers
function filter_integer(mixed $value) : ?int {
return filter_integer_range($value);
}
// input sanitation for id-s
function filter_id(mixed $value, int $min = 0) : ?int {
return filter_integer_range($value, $min, null);
}
// input sanitation for URL
function filter_url(mixed $value){
return filter_var(
$value,
@@ -50,7 +56,8 @@ function filter_url(mixed $value){
}
class PromoImage {
public function __construct(array $data) {
public function __construct(array $data) {
$this->src = filter_url($data["src"]);
$this->height = filter_integer_range(
value: $data["height"],
@@ -58,31 +65,43 @@ class PromoImage {
max: null
);
$this->width = filter_integer_range($data["width"], 0, null);
$this->data = $data;
}
public function to_json(){
return json_encode(
public function to_json(): string|null{
$data = json_encode(
value: [
"src" => $this->src,
"width" => $this->width,
"height" => $this->height
]
);
if($data == false){
return null;
}
return $data;
}
private string $src;
private int $width;
private int $height;
public array $data;
}
// a single news entry
class Entry{
// public
// - functions
// private
// - member variables
private int $id;
private \DateTime $date;
private string $title;
private string $content;
private string $author;
private PromoImage $promo;
}
}

View File

@@ -0,0 +1,193 @@
<?php
namespace cwsvjudo\db;
/**
* interface for connecting and communicating with a database
*/
class Connector
{
// public
// - variables (none)
// - functions
public function connect(
string $hostname,
int $port = 3306,
string $dbName,
string $user,
string $password
): bool
{
return self::setDbConnection(
dbConnection: self::connectToPdo(
hostname: $hostname,
dbName: $dbName,
user: $user,
password: $password
)
);
}
// private
// - variables
/**
* pointer to the database connection
* @var
*
* Handle to interact with the database
*/
private $db = null;
// - functions
/** @todo Docu
* Establish a connection to the database
* @param mixed $hostname
* @param mixed $dbName
* @param mixed $user
* @param mixed $password
* @return \PDO|null
*/
private static function connectToPdo(
string $hostname,
int $port = 3306,
string $dbName,
string $user,
string $password
): \PDO|null
{
$dbConnection = null;
try {
$dbConnection = new \PDO(
dsn: 'mysql:'.join(
';',
[
'host=' . $hostname,
'port=' . strval($port),
'dbname=' . $dbName
]
),
username: $user,
password: $password
);
} catch(\PDOException $dbError) {
echo('Error whilst getting a dbConnection!: ' . $dbError->getMessage());
}
return $dbConnection;
}
public static function getDbConnection()
{
return self::$db;
}
/// perform a \PDO-query
///
/// @param $aQueryString
/// @param $aBindArray e.g. array(
/// ':userId' => array('value'=>$anUserId, 'data_type'=>\PDO::PARAM_INT),
/// ':attributeId'=> array('value'=>$anAttributeId, 'data_type'=>\PDO::PARAM_INT) )
/// @param $someOption
public static function query($aQueryString, $aBindArray = [], $someOptions = [])
{
// var_dump($aQueryString, $aBindArray);
// Standardbelegungen
if (empty($someOptions['dbCharset'])) {
$someOptions['dbCharset'] = 'ISO-8859-1';
}
if (empty($someOptions['outCharset'])) {
$someOptions['outCharset'] = 'UTF-8';
}
if (empty($someOptions['dontFetch'])) {
$someOptions['dontFetch'] = false;
}
$ignoreErrors = $someOptions['ignoreErrors'] ?? false;
/// @toDo: Bisher wird nur die Rückgabe konvertiert. Eigentlich muss
/// doch auch die Eingabe konvertiert werden. Aber das jetzt
/// umzustellen wird schwer! Die User im Wettkampfplaner sind ja z.B.
/// als UTF8 in latin1(?) gespeichert.
/// @toDo: Die Standardwerte sollten vielleicht aus einer config
/// kommen, nicht hardcoded
try {
$PDOStatement = self::$db->prepare($aQueryString);
foreach ($aBindArray as $bindName => $bind) {
if ($bind['data_type'] == \PDO::PARAM_STR) {
$bind['value'] = iconv(
$someOptions['outCharset'],
$someOptions['dbCharset'],
$bind['value']
);
}
$PDOStatement->bindValue(
$bindName,
$bind['value'],
(isset($bind['data_type']) ? $bind['data_type'] : \PDO::PARAM_STR)
);
}
$PDOResult = $PDOStatement->execute();
if (!$ignoreErrors && !$PDOResult) {
echo("Error during dbQuery!\n");
echo("DB-Error:\n");
var_dump(self::$db->errorInfo());
}
if ($someOptions['dontFetch']) {
$ret = null;
} else {
$ret = $PDOStatement->fetchAll(\PDO::FETCH_ASSOC);
}
} catch(\PDOException $db_error) {
print 'Error!: ' . $db_error->getMessage() . '<br/>';
return null;
}
// Zeichensatzkonvertierung
if (is_array($ret)) {
foreach ($ret as &$entry) {
array_walk(
$entry,
function (&$value, $key, $someOptions) {
$value = iconv($someOptions['dbCharset'], $someOptions['outCharset'], $value);
},
$someOptions
);
}
}
return $ret;
}
// @todo docu
public static function getLastInsertId()
{
return self::$db->lastInsertId();
}
// set the dbConnection (just setting, no establishing)
private function setDbConnection($dbConnection): bool
{
$success = false;
if ($dbConnection instanceof \PDO) {
self::$db = $dbConnection;
$success = true;
} else {
self::$db = null;
}
return $success;
}
public static function debugEchoQuery($query, $params)
{
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);
}
}