Ik heb ondertussen de getName-methode van Groups ook ge-implementeerd, met in het achterhoofd, 'baat het niet, dan schaadt het niet'.
Wel behalve dat die methode nu dus bestaat, is er niks veranderd aan de errors
De volledige relevante code:
index.php: doet een include van config.php, welke een aantal defines zet voor de databaseconnectie en tevens de $config[]-aanmaakt
include ook een database.php, deze file bevat een klasse Database welke in de constructor verbinding met de MySQL-server opzet, tevens bevat deze klasse een methode
sqlcontrole die injectie moet tegengaan, en een methode
doSQL die de opgegeven query uitvoert en het resultaat als gefetched array returned.
Last but not least bevat de Databaseklasse een methode
getContent met als parameters het id van de pagina, en de voorkeurstaal voor die pagina.
PHP:
<?php
session_start();
require_once("core/config.php");
require_once("core/database.php");
//the databasehandler
$db = new Database();
//check if there's a language set already
$lang = $config['defaultLanguage'];
if (isset($_COOKIE['languageCode'])) {
$lang = $_COOKIE['languageCode'];
//check if the language exists
if (!$db->isLang($lang))
$lang = $config['defaultLanguage'];
}
//keep cookie for 3 months
setcookie('languageCode', $lang, time()+60*60*24*90);
//PageID | 1 == homepage
$pageID = "";
if (isset($_GET['p']) && !empty($_GET['p'])) {
$pageID = $_GET['p'];
} else {
$pageID = 1;
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>BeLong</title>
</head>
<body>
<?php
//menu
require_once('core/menus.php');
?>
<br />
Your language: <strong><?php echo $lang; ?></strong><br />
<hr />
<?php
//check if contentID exists - if not show errormessage
// try to get the content in the correct language
// if not available - check for defaultlanguage
// if not available - check for any language
$content = $db->getContent($pageID, $lang);
echo eval($content);
?>
</body>
</html>
De getContent-methode uit de Databaseklasse:
PHP:
<?php
class Database {
public $ch=''; //connectionhandler -> holder for the connection with the database
//connectionspecific variables
//normally, they are defined in config.php
const HOST = mysql_host;
const USER = mysql_user;
const PWD = mysql_pass;
const DB = mysql_db; //which database should be selected on connect
const PREFIX = mysql_prefix; //table-prefix (can be useful when only one db is available, preventing conflicts)
public function __construct() {
//verbinden
$this->ch = @mysql_connect(self::HOST, self::USER, self::PWD) or die ('Could not connect to the database.');
//database selecteren
mysql_select_db(self::DB, $this->ch) or die ('Database is currently unavailable.');
}
public function __destruct() {
//close connection
@mysql_close($this->ch);
//empty the connectionhandler (prevents requests while closing/closed)
$this->ch = '';
}
public function doSQL($query) {
//execute query
$result = mysql_query($query, $this->ch) or die ('doSQL-request could not be completed<br />' . mysql_error($this->ch) . '<br /><br />The Query:<br /><pre>' . $query . '</pre>');
//Return requested rows as array
return $this->fetchRows($result);
}
private function fetchRows($result) {
$rows = null;
while ($row = mysql_fetch_array($result)) {
$rows[]=$row;
}
return $rows;
}
public function sqlcontrole($value)
{
//raw data
if (get_magic_quotes_gpc())
$value = stripslashes($value);
//check version
if (version_compare(phpversion(), "4.3.0") == "-1")
return mysql_escape_string($value);
else
return mysql_real_escape_string($value);
}
//checks if a language is known in the system
public function isLang($langCode)
{
$query = "SELECT fullname FROM " . self::PREFIX . "languages WHERE code='" . $this->sqlcontrole($langCode) . "'";
$result = $this->doSQL($query);
return (!empty($result));
}
//gets all languages
public function getLanguages()
{
$query = "SELECT * FROM " . self::PREFIX . "languages";
$result = $this->doSQL($query);
return $result;
}
//gets a page in the needed language
public function getContent($pageID, $langCode)
{
$pageID = $this->sqlcontrole($pageID);
//see if the page exists
$query = "SELECT id FROM " . self::PREFIX . "pages WHERE id='" . $pageID . "'";
$result = $this->doSQL($query);
if (empty($result)) {
return "?>The page could not be found";
exit();
}
//check the requested language
if ($this->isLang($langCode)) {
$query = "SELECT content FROM " . self::PREFIX . "pages_" . $this->sqlcontrole($langCode) . " WHERE id='" . $pageID . "'";
$result = $this->doSQL($query);
if (!empty($result)) {
return $result[0]['content'];
exit();
}
//check the defaultlanguage
include_once("config.php");
if ($config['defaultLanguage'] != $this->sqlcontrole($langCode)) {
$query = "SELECT content FROM " .self::PREFIX . "pages_" . $config['defaultLanguage'] . " WHERE id='" . $pageID;
$result = $this->doSQL($query);
if (!empty($result)) {
return $result[0]['content'];
exit();
}
}
//go for all languages
$langs = $this->getLanguages();
foreach($langs as $lang) {
$query = "SELECT content FROM " .self::PREFIX . "pages_" . $lang['code'] . " WHERE id='" . $pageID;
$result = $this->doSQL($query);
if (!empty($result)) {
return $result[0]['content'];
exit();
}
}
} else {
return "?>The page could not be found";
}
}
}
?>
Dan is er de code van de pagina zoals eerder al gegeven, dit is zoals ze in de database staat:
PHP:
require_once("core/inc/checklogin.php");
require_once("core/classes/members.php");
checkLogin();
$userObject = Members::getUserProfile($_SESSION['nick']);
?>
<h1>Profile: <?php echo $userObject['nick']; ?></h1>
<br />
<table border="0" style="margin-left: 20px;">
<tr>
<td class="label">E-mail</td>
<td><?php echo $userObject['email']; ?></td>
</tr>
<tr>
<td class="label">Registered on </td>
<td><?php echo date("j.m.Y", (int)$userObject['registerDate']); ?></td>
</tr>
<tr>
<td class="label">Last Login</td>
<td><?php echo date("j.m.Y - G:i", ((int)$userObject['lastLogin'] + 9*3600)); ?> (GMT+01h00)</td>
</tr>
</table>
Member of the following groups:
<?php
$gIDs = Members::getGroups($userObject['nick']);
$allGroups = "";
if (!empty($gIDs)) {
//fetch groups
require_once("core/classes/groups.php");
foreach ($gIDs as $group) {
$gName = Groups::getName($group['gid'], $_SESSION['languageCode']);
if (!empty(gName)) {
$allGroups .= '<a href="?p=groups&gid=' . $group['gid'] . '">' . $gName . '</a>, ';
} else {
//we should never have an 'else'-condition here
echo "<br />error requesting name on gid " . $group['gid'] . "<br />, ";
}
}
//cut off the last ', '
$allGroups = substr($allGroups, 0, -2);
} else {
$allGroups = "none";
}
echo $allGroups;
?>
Aangezien de pagina geen fouten gaf toen het tweede deel (vanaf 'Member of the following groups:') nog niet bestond, gok ik erop dat de fout zich dan dus ook daar ergens moet bevinden.
Dat brengt de mogelijkheden tot volgende methodes terug:
$gIDs = Members::getGroups($userObject['nick']);
of
$gName = Groups::getName($group['gid'], $_SESSION['languageCode']);
de getGroups-methode uit de klasse Members:
PHP:
public static function getGroups($nick)
{
global $db;
$nick = $db->sqlcontrole($nick);
$query = "SELECT gid FROM " . mysql_prefix . "user_groups WHERE uid IN (SELECT id FROM " . mysql_prefix . "login WHERE nick='" . $nick . "'";
$gids = $db->doSQL($query);
return $gids;
}
en tenslotte ook nog de getName-methode van de klasse Groups (gelijkaardig aan getContent uit de klasse Database):
PHP:
public static function getName($id, $lang)
{
global $db;
$id = $db->sqlcontrole($id);
//see if the group exists
$query = "SELECT id FROM " . mysql_prefix . "groups WHERE id='" . $id . "'";
$result = $db->doSQL($query);
if (empty($result)) {
return "";
exit();
}
//check the requested language
if ($db->isLang($lang)) {
$lang = $db->sqlcontrole($lang);
$query = "SELECT name FROM " . mysql_prefix . "groups_" . $lang . " WHERE id='" . $id . "'";
$result = $this->doSQL($query);
if (!empty($result)) {
return $result[0]['name'];
exit();
}
//check the defaultlanguage
include_once("config.php");
if ($config['defaultLanguage'] != $lang) {
$query = "SELECT name FROM " . mysql_prefix . "groups_" . $config['defaultLanguage'] . " WHERE id='" . $id;
$result = $db->doSQL($query);
if (!empty($result)) {
return $result[0]['name'];
exit();
}
}
//go for all languages
$langs = $db->getLanguages();
foreach($langs as $lang) {
$query = "SELECT name FROM " . mysql_prefix . "groups_" . $lang['code'] . " WHERE id='" . $id;
$result = $db->doSQL($query);
if (!empty($result)) {
return $result[0]['name'];
exit();
}
}
} else {
return "";
}
}
Hiermee heb je alle code van toepassing voor die pagina, wat nu toch wel een hele lap is geworden. In elk geval al bedankt dat je er de tijd wil insteken.
Indien je deze code 'live' aan het werk wil zien, het is de code van
http://belonger.be/ en het probleem bevindt zich bij de profiel-pagina die getoond moet worden wanneer je inlogd. (registreren maakt gebruik van e-mailverificatie..)
EDIT: best wel grappig dat bij de ene code er dubbele regeleindes worden toegepast en op een andere, vanuit de zelfde editor gekopiëerd, niet