From 0dfd613aec2e0490f7711af00d33672e58a90ebc Mon Sep 17 00:00:00 2001 From: ztk <support@ztk.me> Date: Wed, 14 Nov 2018 23:40:36 +0100 Subject: [PATCH] consider change stuff to pdo aswell --- adcheck.php | 6 +- adclick.php | 7 +- class/campaigns.php | 32 +++++ class/database.php | 281 ++++++++++++++++++++++++++++++++++++++++ class/databaseTable.php | 114 ++++++++++++++++ ext/ap/ads.inc.php | 26 ---- lib/datenbank.inc.php | 25 +++- lib/functions.lib.php | 9 ++ 8 files changed, 464 insertions(+), 36 deletions(-) create mode 100644 class/campaigns.php create mode 100644 class/database.php create mode 100644 class/databaseTable.php diff --git a/adcheck.php b/adcheck.php index 388fc4a..71ee05e 100644 --- a/adcheck.php +++ b/adcheck.php @@ -9,7 +9,9 @@ require ('ext/ap/ads.inc.php'); list($art, $tan) = explode('-', $_GET['data']); // yeah sorry ;) $art = base64_decode($art); $tan = base64_decode($tan); -$kampdaten = getAdDataByArtAndTan( $art, $tan ); + +$kampdaten_rows = $campaigns->getCampaignByTanAndType( $tan, $art ); +$kampdaten = $kampdaten_rows[0]; $result_color = 'red'; @@ -32,7 +34,7 @@ if( $tan == $_SESSION['current_ad']['tan'] && <body bgcolor="<?php echo $result_color; ?>"> <?php if( 'green' == $result_color ) { ?> - Diese Anzeige wurde dir mit <?php echo $kampdaten['verdienst'] .' '. $pageconfig['waehrung']; ?> vergütet. + Diese Anzeige wurde dir mit <?php echo $kampdaten->verdienst .' '. $pageconfig['waehrung']; ?> vergütet. <?php } else { ?> Nope, das war nix <?php } ?> diff --git a/adclick.php b/adclick.php index 9abdf60..318daae 100644 --- a/adclick.php +++ b/adclick.php @@ -10,7 +10,8 @@ list($art, $tan) = explode('-', $_GET['data']); // yeah sorry ;) $art = base64_decode($art); $tan = base64_decode($tan); -$kampdaten = getAdDataByArtAndTan( $art, $tan ); +$kampdaten_rows = $campaigns->getCampaignByTanAndType( $tan, $art ); +$kampdaten = $kampdaten_rows[0]; // TODO prevent malicious ziel urls invalidateAlreadyRunningAd(); @@ -21,7 +22,7 @@ setCurrentRunningAd( $art, $tan ); <!-- never is old spec but will be ignored by new browsers //--> <meta name="referrer" content="never"> <meta name="referrer" content="no-referrer" /> - <meta http-equiv="refresh" content="0; URL=<?php echo $kampdaten['ziel']; ?>"> + <meta http-equiv="refresh" content="0; URL=<?php echo $kampdaten->ziel; ?>"> <title>Anzeige</title> </head> <body> @@ -38,6 +39,6 @@ setCurrentRunningAd( $art, $tan ); return true; } </script> - <a href="<?php echo $kampdaten['ziel']; ?>" rel="noopener noreferrer nofollow" onclick="notify();" >Hier weiter, falls keine automatische Weiterleitung erfolgt.</a> + <a href="<?php echo $kampdaten->ziel; ?>" rel="noopener noreferrer nofollow" onclick="notify();" >Hier weiter, falls keine automatische Weiterleitung erfolgt.</a> </body> </html> diff --git a/class/campaigns.php b/class/campaigns.php new file mode 100644 index 0000000..ca5973c --- /dev/null +++ b/class/campaigns.php @@ -0,0 +1,32 @@ +<?php + +class Campaigns +{ + + private $database; + + public function __construct( $database ) + { + $this->database = $database; + } + + + public function getCampaignByTanAndType( $tan, $type, $status = false ) + { + $where_status = ( false !== $status ) ? ' AND `status` = :status ' : ''; + + $sql = '`uid`, `tan`, `kid`, `ziel`, `banner`, `verdienst`, `preis`, `aufendhalt`, `menge`, `reload`, `sponsor`, `werbeart`, `status` + FROM `'.DB_PREFIX.'_gebuchte_werbung` WHERE `tan` = :tan AND `werbeart` = :type '.$where_status.' LIMIT 1'; + $sql_params = array( + ':tan' => $tan, + ':type' => $type, + ); + if( false !== $status ) + { + $sql_params[':status'] = $status; + } + + return $this->database->select($sql, $sql_params); + } + +} diff --git a/class/database.php b/class/database.php new file mode 100644 index 0000000..a0605bd --- /dev/null +++ b/class/database.php @@ -0,0 +1,281 @@ +<?php +// https://raw.githubusercontent.com/daveismyname/pdo-wrapper/master/database.php + +require_once( __DIR__ .'/databaseTable.php' ); + +class DaveDatabase extends PDO +{ + /** + * @var array Array of saved databases for reusing + */ + protected static $instances = array(); + + /** + * Static method get + * + * @param array $group + * @return \helpers\database + */ + public static function get($group = false) + { + // Determining if exists or it's not empty, then use default group defined in config + $group = !$group ? array ( + 'type' => DB_TYPE, + 'host' => DB_HOST, + 'name' => DB_NAME, + 'user' => DB_USER, + 'pass' => DB_PASS + ) : $group; + + // Group information + $type = $group['type']; + $host = $group['host']; + $name = $group['name']; + $user = $group['user']; + $pass = $group['pass']; + + // ID for database based on the group information + $id = "$type.$host.$name.$user.$pass"; + + // Checking if the same + if (isset(self::$instances[$id])) { + return self::$instances[$id]; + } + + $instance = new Database("$type:host=$host;dbname=$name;charset=utf8", $user, $pass); + $instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + // Setting Database into $instances to avoid duplication + self::$instances[$id] = $instance; + + //return the pdo instance + return $instance; + + } + + /** + * run raw sql queries + * @param string $sql sql command + * @return none + */ + public function raw($sql) + { + $this->query($sql); + } + + /** + * method for selecting records from a database + * @param string $sql sql query + * @param array $array named params + * @param object $fetchMode + * @param string $class class name + * @return array returns an array of records + */ + public function select($sql, $array = array(), $fetchMode = PDO::FETCH_OBJ, $class = '') + { + // Append select if it isn't appended. + if (strtolower(substr($sql, 0, 7)) !== 'select ') { + $sql = "SELECT " . $sql; + } + + $stmt = $this->prepare($sql); + foreach ($array as $key => $value) { + if (is_int($value)) { + $stmt->bindValue("$key", $value, PDO::PARAM_INT); + } else { + $stmt->bindValue("$key", $value); + } + } + + $stmt->execute(); + + if ($fetchMode === PDO::FETCH_CLASS) { + return $stmt->fetchAll($fetchMode, $class); + } else { + return $stmt->fetchAll($fetchMode); + } + } + + /** + * Count method + * @param string $table table name + * @param string $column optional + */ + public function count($table, $column= 'id') { + $stmt = $this->prepare("SELECT $column FROM $table"); + $stmt->execute(); + return $stmt->rowCount(); + } + + /** + * insert method + * @param string $table table name + * @param array $data array of columns and values + */ + public function insert($table, $data) + { + ksort($data); + + $fieldNames = implode(',', array_keys($data)); + $fieldValues = ':'.implode(', :', array_keys($data)); + + $stmt = $this->prepare("INSERT INTO $table ($fieldNames) VALUES ($fieldValues)"); + + foreach ($data as $key => $value) { + $stmt->bindValue(":$key", $value); + } + + $stmt->execute(); + return $this->lastInsertId(); + } + + /** + * update method + * @param string $table table name + * @param array $data array of columns and values + * @param array $where array of columns and values + */ + public function update($table, $data, $where) + { + ksort($data); + + $fieldDetails = null; + foreach ($data as $key => $value) { + $fieldDetails .= "$key = :$key,"; + } + $fieldDetails = rtrim($fieldDetails, ','); + + $whereDetails = null; + $i = 0; + foreach ($where as $key => $value) { + if ($i == 0) { + $whereDetails .= "$key = :$key"; + } else { + $whereDetails .= " AND $key = :$key"; + } + $i++; + } + $whereDetails = ltrim($whereDetails, ' AND '); + + $stmt = $this->prepare("UPDATE $table SET $fieldDetails WHERE $whereDetails"); + + foreach ($data as $key => $value) { + $stmt->bindValue(":$key", $value); + } + + foreach ($where as $key => $value) { + $stmt->bindValue(":$key", $value); + } + + $stmt->execute(); + return $stmt->rowCount(); + } + + /** + * Delete method + * @param string $table table name + * @param array $data array of columns and values + * @param array $where array of columns and values + * @param integer $limit limit number of records + */ + public function delete($table, $where, $limit = 1) + { + ksort($where); + + $whereDetails = null; + $i = 0; + foreach ($where as $key => $value) { + if ($i == 0) { + $whereDetails .= "$key = :$key"; + } else { + $whereDetails .= " AND $key = :$key"; + } + $i++; + } + $whereDetails = ltrim($whereDetails, ' AND '); + + //if limit is a number use a limit on the query + if (is_numeric($limit)) { + $uselimit = "LIMIT $limit"; + } + + $stmt = $this->prepare("DELETE FROM $table WHERE $whereDetails $uselimit"); + + foreach ($where as $key => $value) { + $stmt->bindValue(":$key", $value); + } + + $stmt->execute(); + return $stmt->rowCount(); + } + + /** + * truncate table + * @param string $table table name + */ + public function truncate($table) + { + return $this->exec("TRUNCATE TABLE $table"); + } +} + + +class Database extends DaveDatabase +{ + private $table_objects = array(); + + public function getTable( $table_name ) + { + if( !isset($this->table_objects[$table_name]) ) + { + $this->loadTableObject( $table_name ); + } + return ( isset($this->table_objects[$table_name]) ) ? $this->table_objects[$table_name] : false; + } + + private function loadTableObject( $table_name ) + { + $result = false; + + $filepath = __DIR__ .'/database/'.$table_name.'.ext.php'; + + if( !file_exists( $filepath ) ) + { + $this->tryCreateTableDefinition( $table_name ); + } + + if( file_exists( $filepath ) ) + { + require_once( $filepath ); + $class_name = 'Table'. $table_name; + if( class_exists( $class_name ) ) + { + $this->table_objects[$table_name] = new $class_name(); + $result = true; + } + } + return $result; + } + + + private function tryCreateTableDefinition( $table_name ) + { + $table_class = new DatabaseTable($this, $table_name); + $table_class->getColumnMeta(); + var_dump($table_class->fields); + var_dump($table_class->field_meta); + var_dump($table_class->primary_key); + } + + + /* + * $db->select("`username` FROM `members` WHERE `memberID` = :id and `email` = :email", array(':id' => 1, ':email' => 'someone@domain.com')); + * $db->selectAll("members", "WHERE `memberID` = :id and `email` = :email", array(':id' => 1, ':email' => 'someone@domain.com')); + */ + public function selectAll($sql, $array = array(), $fetchMode = PDO::FETCH_OBJ, $class = '') + { + + + } + +} diff --git a/class/databaseTable.php b/class/databaseTable.php new file mode 100644 index 0000000..3b48bbe --- /dev/null +++ b/class/databaseTable.php @@ -0,0 +1,114 @@ +<?php + +class DatabaseTable +{ + + public $fields = array(); + public $field_meta = array(); + public $primary_key = NULL; + + private $database; + private $table_name; + + public function __construct( $database, $table_name ) + { + $this->database = $database; + $this->table_name = $table_name; + } + + /** + * Will attempt to bind columns with datatypes based on parts of the column type name + * Any part of the name below will be picked up and converted unless otherwise sepcified + * Example: 'VARCHAR' columns have 'CHAR' in them, so 'char' => PDO::PARAM_STR will convert + * all columns of that type to be bound as PDO::PARAM_STR + * If there is no specification for a column type, column will be bound as PDO::PARAM_STR + */ + protected $pdo_bind_types = array( + 'char' => PDO::PARAM_STR, + 'int' => PDO::PARAM_INT, + 'bool' => PDO::PARAM_BOOL, + 'date' => PDO::PARAM_STR, + 'time' => PDO::PARAM_INT, + 'text' => PDO::PARAM_STR, + 'blob' => PDO::PARAM_LOB, + 'binary' => PDO::PARAM_LOB + ); + + + /** + * Parse PDO-produced column type + * [internal function] + */ + protected function parseColumnType($col_type) + { + $col_info = array(); + $col_parts = explode(" ", $col_type); + if( $fparen = strpos($colParts[0], "(") ) + { + $col_info['type'] = substr($col_parts[0], 0, $fparen); + $col_info['pdo_type'] = ''; + $col_info['length'] = str_replace(")", "", substr($col_parts[0], $fparen+1)); + $col_info['attributes'] = isset($col_parts[1]) ? $col_parts[1] : NULL; + } + else + { + $col_info['type'] = $col_parts[0]; + } + + // PDO Bind types + $pdo_type = ''; + foreach($this->pdo_bind_types as $pKey => $pType) + { + if(strpos(' '.strtolower($col_info['type']).' ', $pKey)) + { + $col_info['pdo_type'] = $pType; + break; + } + else + { + $col_info['pdo_type'] = PDO::PARAM_STR; + } + } + return $col_info; + } + + + /** + * Automatically get column metadata + */ + protected function getColumnMeta($refresh = false) + { + if( $refresh ) + { + // Clear any previous column/field info + $this->fields = array(); + $this->field_meta = array(); + $this->primary_key = NULL; + } + + // Automatically retrieve column information if column info not specified + if( count($this->fields) == 0 || count($this->field_meta) == 0 ) + { + // Fetch all columns and store in $this->fields + // TODO prepared statement ... + $columns = $this->database->query("SHOW COLUMNS FROM " . $this->table_name, PDO::FETCH_ASSOC); + foreach( $columns as $key => $col ) + { + // Insert into fields array + $col_name = $col['Field']; + $this->fields[$col_name] = $col; + if( $col['Key'] == "PRI" && empty($this->primary_key) ) + { + $this->primary_key = $col_name; + } + + // Set field types + $col_type = $this->parseColumnType($col['Type']); + $this->field_meta[$col_name] = $col_type; + } + } + return true; + } + + +} diff --git a/ext/ap/ads.inc.php b/ext/ap/ads.inc.php index 89007c0..1a7d51b 100644 --- a/ext/ap/ads.inc.php +++ b/ext/ap/ads.inc.php @@ -138,29 +138,3 @@ function getNewAdData( $dbArt ) return $result; } - -function getAdDataByArtAndTan( $art, $tan ) -{ - global $db_prefix, $sql_open; - $row = false; - $sql = 'SELECT `uid`, `tan`, `kid`, `ziel`, `banner`, `verdienst`, `preis`, `aufendhalt`, `menge`, `reload`, `sponsor`, `werbeart`, `status` FROM `' . $db_prefix . '_gebuchte_werbung` WHERE `tan` = ? AND `werbeart` = ? LIMIT 1'; - - $statement = mysqli_prepare( $sql_open, $sql ); - - mysqli_stmt_bind_param( $statement, "ss", $tan, $art ); - if( mysqli_stmt_execute( $statement ) ) - { - mysqli_stmt_store_result( $statement ); - if ( mysqli_stmt_num_rows( $statement ) > 0 ) - { - $rows = db_fetch( $statement ); - $row = $rows[0]; // should be there ... > 0 - } - } - mysqli_stmt_close( $statement ); - return $row; - - //return array( 'uid' => $uid, 'tan' => $tan, 'kid' => $kid, 'ziel' => $ziel, 'banner' => $banner, 'verdienst' => $verdienst, 'preis' => $preis, 'aufendhalt' => $aufendhalt, - // 'menge' => $menge, 'reload' => $reload, 'sponsor' => $sponsor, 'werbeart' => $werbeart, 'status' => $status ); - -} diff --git a/lib/datenbank.inc.php b/lib/datenbank.inc.php index f439921..0122673 100644 --- a/lib/datenbank.inc.php +++ b/lib/datenbank.inc.php @@ -1,10 +1,25 @@ <?php - require_once( __DIR__ .'/db_config.php' ); + +require_once( __DIR__ .'/db_config.php' ); +require_once( __DIR__ .'/../class/database.php' ); - //Datenbankverbindung herstellen - $sql_open = @mysqli_connect( DB_HOST, DB_USER, DB_PASS, DB_BASE ) or die('Verbindung zum Mysql Server fehlgeschlagen! <br>Tipp: <a href="http://www.vms-tutorial.de/wiki//Lib/Functions">http://www.vms-tutorial.de/wiki//Lib/Functions</a>'); - // why?: - $sql_base = @mysqli_select_db($sql_open, DB_BASE ) or die("Keine oder falsche Datenbank gewhlt! Tipp: <br><a href='http://www.vms-tutorial.de/wiki//Lib/Functions'>http://www.vms-tutorial.de/wiki//Lib/Functions</a>"); +//Datenbankverbindung herstellen +$sql_open = @mysqli_connect( DB_HOST, DB_USER, DB_PASS, DB_BASE ) or die('Verbindung zum Mysql Server fehlgeschlagen! <br>Tipp: <a href="http://www.vms-tutorial.de/wiki//Lib/Functions">http://www.vms-tutorial.de/wiki//Lib/Functions</a>'); +// why?: +$sql_base = @mysqli_select_db($sql_open, DB_BASE ) or die("Keine oder falsche Datenbank gewhlt! Tipp: <br><a href='http://www.vms-tutorial.de/wiki//Lib/Functions'>http://www.vms-tutorial.de/wiki//Lib/Functions</a>"); + +// please use global $database, $GLOBALs['database'] or pass $database to class/function +// avoid cluttering the code with silly singleton calls, except when really needed, +// for example when connectiong to a different database, thank you +$database = Database::get( + array( + 'type' => 'mysql', + 'host' => DB_HOST, + 'name' => DB_BASE, + 'user' => DB_USER, + 'pass' => DB_PASS, + ) + ); /** * db_connect() diff --git a/lib/functions.lib.php b/lib/functions.lib.php index 92271e7..a7a61ca 100644 --- a/lib/functions.lib.php +++ b/lib/functions.lib.php @@ -1,5 +1,14 @@ <?php +if( isset($database) ) +{ + require_once( __DIR__ . '/../class/campaigns.php' ); + $campaigns = new Campaigns($database); + +} else { + throw new Exception( 'Please include lib/datenbank.inc.php before lib/functions.lib.php' ); +} + /** * create_code() * -- GitLab