Hallo,

Ik ga met iemand anders een projectje doen waarbij we een site gaan maken.
Aangezien we met z'n tweeën gaan werken leek het me handig om eens met OOP aan de slag te gaan, aangezien we al hebben ervaren dat de spaghetti code voor ons beiden vervelend kan zijn.

Ik heb redelijk wat over OOP gelezen maar ik kom heel moeilijk aan praktijk voorbeelden.
Al te vaak lees je over een auto classe of over een hond classe, die je kunt extenden naar een poedel bijvoorbeeld.

Ik heb in ieder geval geprobeert een beginnetje maken maar ik vraag me nu al af of ik wel op de goede weg zit en niet verkeerd aan het denken ben.
Ik heb op verschillende plekken gelezen dat setter en getter 'evil' zijn en ik betrap mezelf erop er al veelvuldig gebruik van te maken.

Ik was bezig met een Gebruiker classe voor de site, simpelweg omdat ik geen idee had waar ik anders moest beginnen.
Ik zal hieronder posten wat ik tot nu toe heb gedaan en zou graag commentaar hebben op het geheel (ook de foutafhandeling bijvoorbeeld, ik heb vrij veel gebruikt van jorendewit.nl)
Zoals je kunt zien gebruik ik in de Gebruikers classe al vrij veel setter en getters, en blijkbaar is dit niet goed maar ik vraag me af hoe ik dit anders moet aanpakken.

Ik hoor graag wat jullie te vertellen hebben!

index.php

<?php

ini_set('display_errors', 'On');
error_reporting(E_ALL);


require 'includes/db_config.php';
require 'includes/error_handler.php';


function __autoload($class_name) {
require_once 'classes/' . strtolower($class_name) . '.class.php';
}



try
{
$db = new PDO('mysql:host=' . $db_host . ';dbname=' . $db_name,$db_user,$db_pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);



$user = new Gebruiker(1, $db);

if($user->get_tussenvoegsel() != NULL)
{
$tussenvoegsel = ' ' . $user->get_tussenvoegsel() . ' ';
}
else{
$tussenvoegsel = ' ';
}
// GEWOON TESTEN
echo 'Naam: ' . $user->get_voornaam() . $tussenvoegsel . $user->get_achternaam();



}

catch(PDOException $e)
{
echo 'PDOEXCEPTION';
echo '<pre>';
echo 'Regel: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage();
echo '</pre>';

}

catch(Exception $e)
{
echo '<pre>';
echo 'Regel: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage();
echo '</pre>';

}
?>


classes/gebruiker.class.php
(hier was ik nog mee bezig)

<?php

class Gebruiker {

private $id;
private $voornaam;
private $tussenvoegsel;
private $achternaam;
private $email;
private $rechten;
private $geslacht;
private $regip;
private $regdatetime;
private $werknemer;
private $werkgever;
private $db;

public function __construct($id, $db){

if(!is_int($id)){
throw new Exception('Aanmaken instantie van "'.__CLASS__.'" mislukt. $id is geen INT');
}

$this->set_id($id);
$this->db = $db;
}

// ID SETTER & GETTER
private function set_id($id){
// Deze moet nog verder uitgewerkt worden uiteraard
$this->id = $id;
}
public function get_id(){
// Deze moet nog verder uitgewerkt worden uiteraard
return $this->id;
}

public function set_voornaam($voornaam){

if(!is_string($voornaam)){
throw new Exception('Kon voornaam niet veranderen. Waarde is geen STRING');
}

$sql = "UPDATE tbl_gebruikers SET voornaam = :voornaam WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':voornaam', $voornaam);
$stmt->bindParam(':id', $this->id);
$stmt->execute();

if($stmt->rowCount() == 0)
{
throw new Exception('Er zijn geen rijen gewijzigd in de UPDATE query "'. $sql . '"');
}

}
public function get_voornaam(){

$sql = "SELECT voornaam FROM tbl_gebruikers WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':id', $this->id);
$stmt->execute();

$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row['voornaam'];

}




public function set_tussenvoegsel($tussenvoegsel){

if(!is_string($tussenvoegsel)){
throw new Exception('Kon tussenvoegsel niet veranderen. Waarde is geen STRING');
}

$sql = "UPDATE tbl_gebruikers SET tussenvoegsel = :tussenvoegsel WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':tussenvoegsel', $tussenvoegsel);
$stmt->bindParam(':id', $this->id);
$stmt->execute();

if($stmt->rowCount() == 0)
{
throw new Exception('Er zijn geen rijen gewijzigd in de UPDATE query "'. $sql . '"');
}

}

public function get_tussenvoegsel(){


$sql = "SELECT tussenvoegsel FROM tbl_gebruikers WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':id', $this->id);
$stmt->execute();

$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row['tussenvoegsel'];

}



public function set_achternaam($achternaam){

if(!is_string($achternaam)){
throw new Exception('Kon achternaam niet veranderen. Waarde is geen STRING');
}

$sql = "UPDATE tbl_gebruikers SET achternaam = :achternaam WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':achternaam', $achternaam);
$stmt->bindParam(':id', $this->id);
$stmt->execute();

if($stmt->rowCount() == 0)
{
throw new Exception('Er zijn geen rijen gewijzigd in de UPDATE query "'. $sql . '"');
}

}

public function get_achternaam(){


$sql = "SELECT achternaam FROM tbl_gebruikers WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':id', $this->id);
$stmt->execute();

$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row['achternaam'];

}




public function set_email($email){

if(!is_string($email)){
throw new Exception('Kon email niet veranderen. Waarde is geen STRING');
}

$sql = "UPDATE tbl_gebruikers SET email = :email WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':email', $email);
$stmt->bindParam(':id', $this->id);
$stmt->execute();

if($stmt->rowCount() == 0)
{
throw new Exception('Er zijn geen rijen gewijzigd in de UPDATE query "'. $sql . '"');
}

}

public function get_email(){


$sql = "SELECT email FROM tbl_gebruikers WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':id', $this->id);
$stmt->execute();

$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row['email'];

}



public function set_rechten($rechten){

if(!is_int($rechten)){
throw new Exception('Kon rechten niet veranderen. Waarde is geen INT');
}

$sql = "UPDATE tbl_gebruikers SET rechten = :rechten WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':rechten', $rechten);
$stmt->bindParam(':id', $this->id);
$stmt->execute();

if($stmt->rowCount() == 0)
{
throw new Exception('Er zijn geen rijen gewijzigd in de UPDATE query "'. $sql . '"');
}

}


public function get_rechten(){

$sql = "SELECT rechten FROM tbl_gebruikers WHERE id = :id";
$stmt = $this->db->prepare($sql);
$stmt->bindParam(':id', $this->id);
$stmt->execute();

$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row['rechten'];

}






}
?>


includes/db_config.php

<?php

$db_host = XXX;
$db_name = XXX;
$db_user = XXX;
$db_pass = XXXX;

?>

includes/error_handler.php

<?php

function myErrorHandler($iLevel, $sMessage, $sFile, $iLine)
{
$aLevels = array(
2 => 'WARNING',
8 => 'NOTICE',
256 => 'FATAL ERROR',
512 => 'WARNING',
1024 => 'NOTICE' );

if(array_key_exists($iLevel, $aLevels))
{
$sLevel = $aLevels[$iLevel];
}
else
{
$sLevel = 'ONBEKENDE FOUT';
}

echo 'FOUT<br />';
echo '<b>Foutsoort:</b> '.$sLevel.'<br />';
echo '<b>Foutmelding:</b> '.$sMessage.'<br />';
echo '<b>Bestand:</b> '.$sFile.'<br />';
echo '<b>Regel:</b> '.$iLine.'<br />';

if($iLevel == 256)
{
echo 'Script wordt gestopt...';
exit();
}
}

set_error_handler('myErrorHandler');

// EXCEPTIONS

function myExceptionHandler($e)
{
echo 'FOUT: Er is een exception niet opgevangen.<br />';
echo 'Melding: '.$e->getMessage();
}

set_exception_handler('myExceptionHandler');

?>
Ik was bezig met een Gebruiker classe voor de site, simpelweg omdat ik geen idee had waar ik anders moest beginnen.
Zomaar ergens beginnen is vaak niet erg handig, zeker niet als OO wilt programmeren.

Zeker als je een hele site (applicatie) OO wilt programmeren, is het handig om met een design pattern te werken. Een die veel gebruikt wordt, is het Model-View-Controller, ofwel MVC design pattern. Ik zou je zeker aanraden om je daar eens over in te lezen.

Verder zou je kunnen overwegen om een framework te gebruiken om je website op te zetten. Een heel uitgebreid (en daarmee voor beginners vrij complex) framework is het Zend Framework. Er zijn ook eenvoudigere maar daarmee minder uitgebreide frameworks te vinden, zoals bijvoorbeeld CakePHP.

Kortom, voordat je echt kunt beginnen zul je eerst nog een paar (belangrijke) beslissingen moeten nemen en je waarschijnlijk nog iets verder in moeten lezen...

Succes in ieder geval!

ps. Wat betreft die setters en getters, bedenk vooraf altijd welke functionaliteit een klasse moet hebben. Ik zie nu een method set_tussenvoegsel(), maar ik vraag me echt af wanneer je ooit alleen een tussenvoegsel wilt wijzigen. Meestal worden er dan veel meer gegevens gewijzigd, iets dat prima in 1 database query en dus in bijvoorbeeld 1 method changeUserData() zou kunnen.
Een gastenboek in 130 regels als voorbeeld:
<?php

class Berichten_Store
{
protected $pdo;

public function __construct($pdo)
{
$this->pdo = $pdo;
}

public function all()
{
$stmt = $this->pdo->query("SELECT id, naam, inhoud, geplaatst_op FROM berichten");

$berichten = array();

while($bericht = $this->fetch_bericht($stmt))
{
$berichten[] = $bericht;
}

return $berichten;
}

protected function fetch_bericht(PDOStatement $stmt)
{
$data = $stmt->fetch(PDO::FETCH_ASSOC);

if(!$data)
return false;

return Bericht::restore($data);
}

public function insert(Bericht $bericht)
{
$stmt = $this->pdo->prepare("INSERT INTO berichten (naam, inhoud, geplaatst_op) VALUES(:naam, :inhoud, datetime('now'))");

$stmt->bindValue(':naam', $bericht->naam());
$stmt->bindValue(':inhoud', $bericht->inhoud());

return $stmt->execute();
}
}

class Bericht
{
private $id;

private $naam;

private $inhoud;

private $geplaatst_op;


public function __construct($naam, $inhoud)
{
$this->naam = $naam;

$this->inhoud = $inhoud;

$this->geplaatst_op = new DateTime('now');
}

static public function restore(array $data)
{
$bericht = new self($data['naam'], $data['inhoud']);

$bericht->id = $data['id'];

$bericht->geplaatst_op = new DateTime($data['geplaatst_op']);

return $bericht;
}

public function id()
{
return $this->id;
}

public function naam()
{
return $this->naam;
}

public function inhoud()
{
return $this->inhoud;
}

public function geplaatst_op()
{
return $this->geplaatst_op;
}
}
/*
Dit is even intialisatie voor dit testscript. Database aanmaken, PHP instellingen
goed zetten, dat soort dingen
*/
error_reporting(E_ALL ^ E_STRICT);
ini_set('display_errors', true);

date_default_timezone_set('Europe/Amsterdam');

//$pdo = new PDO('sqlite::memory:');
$pdo = new PDO('sqlite:/tmp/gastenboek.db');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->query("
CREATE TABLE IF NOT EXISTS berichten (
id integer not null default 0,
naam varchar(100) not null,
inhoud text not null,
geplaatst_op datetime not null,
PRIMARY KEY(id)
)");

$berichten = new Berichten_Store($pdo);

$bericht = new Bericht('Jelmer', 'Testberichtje');
$berichten->insert($bericht);

foreach($berichten->all() as $bericht)
{
printf('"%s" door %s om %s' . "\n",
$bericht->inhoud(),
$bericht->naam(),
$bericht->geplaatst_op()->format('H:i'));
}
?>
Bedankt voor je reactie Blanche, ik ga me even inlezen in MVC en dan reageer ik hier weer op.

@Jelmer
Ik dacht dat een object/class altijd een zelfstandig naamwoord moest zijn?
Dus Berichten_Store lijkt me niet goed of wel?
Store is ook een zelfstandig naamwoord, engels voor winkel ;)

Het staat wat stom inderdaad, die mixin van Engels en Nederlands, maar het is zeg maar een conventie voor mezelf. Net als dat ik set_xxx en get_xxx zou schrijven in plaats van zet_xxx en verkrijg_xxx. Een ding dat dingen voor mij vasthoudt noem ik meestal een store. Repository, Provider, Table, Store... het maakt niet zoveel uit :)

Maar het is inderdaad zo dat je een zelfstandig naamwoord neemt als naam van een class.
Ik ben even in de weer geweest, en ik heb nu een klein MVC framework gemaakt.
Voordat ik hier mee verder ga, zou ik wel graag wat commentaar erop hebben.

Mijn excuses als deze post veel te lang word, maar ik denk dat ik niet zomaar dingen kan weglaten, anders klopt het geheel niet. :P

Zo ziet het er uit:
index.php
dir application
dir includes
dir model
dir views
dir controller

index.php
<?php
/* error reporting aan */
ini_set('display_errors', 'On');
error_reporting(E_ALL);

/* site path instellen */
$site_path = realpath(dirname(__FILE__));
define ('__SITE_PATH', $site_path);



/* probeer het onderstaande */
try {

/* init includen */
require 'includes/init.php';
require 'includes/error_handler.php';

/* laad de router */
$registry->router = new router($registry);

/* set controller path */
$registry->router->setPath (__SITE_PATH . '/controller');

/*** laad Smarty ***/
$registry->smarty = new Smarty();
$registry->smarty->template_dir = __SITE_PATH . '/views/templates';
$registry->smarty->compile_dir = __SITE_PATH . '/views/templates_c';
$registry->smarty->cache_dir = __SITE_PATH . '/views/cache';
$registry->smarty->config_dir = __SITE_PATH . '/views/configs';

/*** laad controller ***/
$registry->router->loader();

} /* PDO fouten opvangen */
catch(PDOException $e)
{
echo 'PDOEXCEPTION';
echo '<pre>';
echo 'Regel: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage();
echo '</pre>';

}

/* eventuele andere fouten opvangen */
catch(Exception $e)
{
echo '<pre>';
echo 'Regel: '.$e->getLine().'<br>';
echo 'Bestand: '.$e->getFile().'<br>';
echo 'Foutmelding: '.$e->getMessage();
echo '</pre>';

}

?>

application/smarty <-- smarty dir


application/registry.class.php
<?php

class registry {

/**
* @vars array
* @access private
*/
private $vars = array();

/**
*
* @set undefined vars
*
* @param string $index
*
* @param mixed $value
*
* @return void;
*
*/

public function __set($index, $value)
{
$this->vars[$index] = $value;
}

/**
*
* @get vars
*
* @param mixed $index
*
* @return mixed
*
*/

public function __get($index)
{
return $this->vars[$index];
}


}



?>

application/router.class.php
<?php

class router {

/*
* @registry
*/
private $registry;

/*
* @ controller path
*/
private $path;

private $args = array();

public $file;

public $controller;

public $action;

function __construct($registry) {
$this->registry = $registry;
}

/**
*
* @set controller dir path
*
* @param string $path
*
* @return void
*
*/
function setPath($path) {

/*** check of het een dir is ***/
if (is_dir($path) == false)
{
throw new Exception ('Ongeldige controller path: `' . $path . '`');
}
/*** set path ***/
$this->path = $path;
}

/**
*
* @load controller
*
* @access public
*
* @return void
*
*/
public function loader()
{
/*** check route ***/
$this->getController();

/*** 404 geven als het bestand er niet is ***/
if (is_readable($this->file) == false)
{
$this->file = $this->path.'/error404.php';
$this->controller = 'error404';
}

/*** controller includen ***/
include $this->file;

/*** nieuw controller class instance ***/
$class = $this->controller . 'Controller';
$controller = new $class($this->registry);

/*** check of je de action kunt aanroepen ***/
if (is_callable(array($controller, $this->action)) == false)
{
$action = 'index';
}
else
{
$action = $this->action;
}
/*** run action ***/
$controller->$action();
}



/**
*
* @get controller
*
* @access private
*
* @return void
*
*/
private function getController() {

/*** route krijgen van url ***/
$route = (empty($_GET['rt'])) ? '' : $_GET['rt'];

if (empty($route))
{
$route = 'index';
}
else
{
/*** krijg route parts ***/
$parts = explode('/', $route);
$this->controller = $parts[0];
if(isset( $parts[1]))
{
$this->action = $parts[1];
}
}

if (empty($this->controller))
{
$this->controller = 'index';
}

/*** get action ***/
if (empty($this->action))
{
$this->action = 'index';
}

/*** set file path ***/
$this->file = $this->path .'/'. $this->controller . 'Controller.php';
}

}

?>


application/controller_base.class.php
<?php

abstract class baseController {

/*
* @registry object
*/

protected $registry;

function __construct($registry) {
$this->registry = $registry;
}

/**
* @alle controller moeten een index method hebben
*/
abstract function index();
}




?>

includes/init.php
<?php

/* controller class includen */
include __SITE_PATH . '/application/' . 'controller_base.class.php';

/* registry class includen */
include __SITE_PATH . '/application/' . 'registry.class.php';

/* router class includen */
include __SITE_PATH . '/application/' . 'router.class.php';

/* template class includen */
include __SITE_PATH . '/application/smarty/' . 'Smarty.class.php';



/* model classes auto-loaden */

function __autoload($class_name) {
$filename = strtolower($class_name) . '.class.php';
$file = __SITE_PATH . '/model/' . $filename;

if (file_exists($file) == false)
{
return false;
}
include ($file);
}

/* nieuw registry object */
$registry = new registry;

/* nieuwe database registry object */
$registry->db = db::getInstance();




?>

includes/error_handler.php
<?php

function myErrorHandler($iLevel, $sMessage, $sFile, $iLine, $errcontext)
{
//If error_reporting() was set to 0 by the @ suppressor, do not process the error
if( error_reporting() == 0 ) {
return true;
}
$aLevels = array(
2 => 'WARNING',
8 => 'NOTICE',
256 => 'FATAL ERROR',
512 => 'WARNING',
1024 => 'NOTICE' );

if(array_key_exists($iLevel, $aLevels))
{
$sLevel = $aLevels[$iLevel];
}
else
{
$sLevel = 'ONBEKENDE FOUT';
}

echo 'FOUT! <br /> (' . $iLevel . ')';
echo '<b>Foutsoort:</b> '.$sLevel.'<br />';
echo '<b>Foutmelding:</b> '.$sMessage.'<br />';
echo '<b>Bestand:</b> '.$sFile.'<br />';
echo '<b>Regel:</b> '.$iLine.'<br />';
echo '<pre>';
print_r($errcontext);
echo '</pre>';



if($iLevel == 256)
{
echo 'Script wordt gestopt...';
exit();
}

}

set_error_handler('myErrorHandler');

// EXCEPTIONS

function myExceptionHandler($e)
{
echo 'FOUT: Er is een exception niet opgevangen.<br />';
echo 'Melding: '.$e->getMessage();
}

set_exception_handler('myExceptionHandler');

?>

model/db.class.php
<?php

class db{

/*** instance declareren ***/
private static $instance = NULL;

/**
*
* private zodat je niet een nieuwe
* instance kan maken
*
*/
private function __construct() {

}

/**
*
* database instance returnen of nog maken
*
* @return object (PDO)
*
* @access public
*
*/
public static function getInstance() {

if (!self::$instance)
{
self::$instance = new PDO("mysql:host=localhost;dbname=****", '****', '****');;
self::$instance-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return self::$instance;
}

/**
*
* private zodat je de instance niet kan klonen
*
*
*/
private function __clone(){
}

}

?>

dir views --> smarty templates


controller/error404.php
<?php

Class error404Controller Extends baseController {

public function index()
{
// show error met smarty
}


}
?>


controller/indexController.php
<?php

class indexController extends baseController {

public function index() {
/*** set template vars ***/
$this->registry->smarty->assign('title','Home');
$this->registry->smarty->assign('var1', 'Dt is var 1');

/*** display template ***/
$this->registry->smarty->display('test.tpl');
}

public function test() {

$this->registry->smarty->assign('title','Home');


$this->registry->smarty->assign('test_var', $_GET['var']);


$this->registry->smarty->display('test.tpl');



}

}

?>


sorry voor de overkill aan code, maar ik wist niet hoe ik het anders moest doen :/
Goed begin. Het wordt vaak pas lastiger wanneer je iets serieus wilt bouwen. Bijvoorbeeld iets met een database, formulieren en terugkomende stukken pagina. Ik denk dat een gastenboek met navigatie (en dan in de navigatie aangeven of je op de bekijk- of de plaats-bericht-pagina bent) het makkelijkste probeersel is van die wat realistischere applicatie. Of een nieuwssysteem met categorieën.
Lijkt de basis je zo goed (genoeg)?
MVC is nogal nieuw voor me, maar ik begrijp wat er gebeurt maar ik vraag me af of dit goed genoeg is om mee te gaan werken.
Volgens mij klopt je implementatie tot nu toe wel. Misschien dat het logischer is om ook smarty en je router in init.php de instantiëren, zodat die configuratie niet in index.php komt (en daardoor verspreidt, ik zou alle configuratie in init.php doen. Dus ook je databasegegevens) maar dat is detail en persoonlijke voorkeur.
Jelmer schreef op 28.12.2009 17:06
Volgens mij klopt je implementatie tot nu toe wel. Misschien dat het logischer is om ook smarty en je router in init.php de instantiëren, zodat die configuratie niet in index.php komt (en daardoor verspreidt, ik zou alle configuratie in init.php doen. Dus ook je databasegegevens) maar dat is detail en persoonlijke voorkeur.

Dat heb ik gedaan ;)
Ik zal binnenkort met user class hier posten aangezien er waarschijnlijk wel het een en ander aan op te merken is ;P
Hier is mijn user class, ik had hier graag commentaar op ;)

<?php

require 'user_validator.class.php';

class User {

private $id;
private $loggedIn = false;
private $userInfo = array();
private $registry;


public function __construct($userInit, $registry){

if(!is_object($registry)){
throw new Exception('Aanmaken instantie van "'.__CLASS__.'" mislukt. $registry is geen object');
}

$this->registry = $registry;

if($userInit === true)
{
$this->userInit();
}
}

public function getId(){
return $this->id;
}

public function getLoggedIn(){
return $this->loggedIn;
}

private function userInit(){

if($this->registry->session->issetSession('loginId')) {
$this->id = $this->registry->session->getSession('loginId');
}else{
$this->id = NULL;
}
if($this->registry->session->issetSession('loggedIn')) {
$this->loggedIn = $this->registry->session->getSession('loggedIn');
}else{
$this->loggedIn = false;
}


}

public function logIn($username, $password){

if($this->loggedIn == true)
{
throw new Exception('Je kan niet inloggen als je al ingelogd bent.');
}
/* Hash uit DB halen */
$sql = 'SELECT id, hash FROM tbl_gebruikers WHERE username = :username';
$stmt = $this->registry->db->prepare($sql);
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->execute();

if($stmt->rowCount() != 1)
{
throw new Exception('Combinatie gebruikersnaam/wachtwoord niet gevonden');
}

$result = $stmt->fetch(PDO::FETCH_ASSOC);
$dbHash = $result['hash'];
$userHash = User_Validator::generateHash($password, $dbHash);

if($dbHash != $userHash){
throw new Exception('Combinatie gebruikersnaam/wachtwoord niet gevonden');
}

$this->registry->session->setSession('loggedIn', true);
$this->loggedIn = true;
$this->registry->session->setSession('loginId', $result['id']);
$this->id = $result['id'];
return true;

}

public function logOut(){

$this->registry->session->unsetAll();
$this->registry->session->destroySessionCookie();
$this->registry->session->destroySession();
$this->loggedIn = false;
$this->id = NULL;


}

public function getProfileInfo($userId = NULL){

if(is_null($userId)){
$userId = $this->id;
}

$sql = '
SELECT
username,
voornaam,
tussenvoegsel,
achternaam,
email,
rechten,
geslacht,
regip
regdatetime,
werknemer,
werkgever
FROM tbl_gebruikers
WHERE id = :id';

$stmt = $this->registry->db->prepare($sql);
$stmt->bindParam(':id', $userId, PDO::PARAM_INT);
$stmt->execute();

$result = $stmt->fetch(PDO::FETCH_ASSOC);

if($stmt->rowCount() == 0)
{
throw new Exception('Kon gebruikerinfo niet vinden');
}

return $result;

}

public function editProfileInfo($profileInfo){

if($this->loggedIn == false)
{
throw new Exception('Kan niet profileinfo aanpassen zonder ingelogd te zijn.');
}

/* USER INPUT CHECKEN*/
$errors = array();
(User_Validator::checkVoornaam($profileInfo[':voornaam'] = trim($profileInfo[':voornaam']))) ? NULL : $errors['voornaam'] = 'Een voornaam mag alleen uit letters bestaan en moet meer dan 1 letter en minder dan 20 letters bevatten';
(User_Validator::checkTussenvoegsel($profileInfo[':tussenvoegsel'] = trim($profileInfo[':tussenvoegsel']))) ? NULL : $errors['tussenvoegsel'] = 'Mag ook leeg zijn. Een tussenvoegsel mag alleen bestaan uit letters bestaan en moet minder dan 10 letters bevatten';
(User_Validator::checkAchternaam($profileInfo[':achternaam'] = trim($profileInfo[':achternaam']))) ? NULL : $errors['achternaam'] = 'Een achternaam mag alleen uit letters bestaan en moet meer dan 1 letter en minder dan 25 letters bevatten';
(User_Validator::checkEmail($profileInfo[':email'] = trim($profileInfo[':email']))) ? NULL : $errors['email'] = 'Het e-mailadres moet geldig zijn.';
if(User_Validator::checkGeslacht($profileInfo[':geslacht'] = intval($profileInfo[':geslacht']))){}else{throw new Exception('Geslacht moet een INT zijn en mag niet groter zijn dan het getal 2');}

/* USER INPUT ONTHOUDEN */
$this->registry->session->setSession('voornaam', $profileInfo[':voornaam']);
$this->registry->session->setSession('tussenvoegsel', $profileInfo[':tussenvoegsel']);
$this->registry->session->setSession('achternaam', $profileInfo[':achternaam']);
$this->registry->session->setSession('email', $profileInfo[':email']);
$this->registry->session->setSession('geslacht', $profileInfo[':geslacht']);

if(!empty($errors)){
throw new UserException('Een aantal velden voldoet niet aan de voorwaarden', $errors);
}

$sql = '
UPDATE tbl_gebruikers
SET
voornaam = :voornaam,
tussenvoegsel = :tussenvoegsel,
achternaam = :achternaam,
email = :email,
geslacht = :geslacht
WHERE
id = :id';

$stmt = $this->registry->db->prepare($sql);
$profileInfo = array_merge(array(':id' => $this->id), $profileInfo);
$succes = $stmt->execute($profileInfo);

if(!$succes)
{
throw new UserException('Update query mislukt');
}
$this->registry->session->unsetSession('voornaam');
$this->registry->session->unsetSession('tussenvoegsel');
$this->registry->session->unsetSession('achternaam');
$this->registry->session->unsetSession('email');
$this->registry->session->unsetSession('geslacht');

return true;

}


public function register($registerInfo){

if($this->loggedIn == true)
{
throw new Exception('Je kan niet registreren als je ingelogd bent.');
}

/* USER INPUT CHECKEN*/
$errors = array();
($registerInfo[':password'] == $registerInfo[':passwordrepeat']) ? NULL : $errors['passwordrepeat'] = 'Wachtwoorden moeten hetzelfde zijn';
(User_Validator::checkUsername($registerInfo[':username'] = trim($registerInfo[':username']))) ? NULL : $errors['username'] = 'Moet langer dan 3 en korter dan 16 tekens zijn. Mag alleen bestaan uit letters, cijfers, "_" en "-"';
(User_Validator::checkPassword($registerInfo[':password'])) ? NULL : $errors['password'] = 'Moet langer dan 6 en korter dan 18 tekens zijn. Mag alleen bestaan uit letters, cijfers, "_" en "-"';
(User_Validator::checkVoornaam($registerInfo[':voornaam'] = trim($registerInfo[':voornaam']))) ? NULL : $errors['voornaam'] = 'Een voornaam mag alleen uit letters bestaan en moet meer dan 1 letter en minder dan 20 letters bevatten';
(User_Validator::checkTussenvoegsel($registerInfo[':tussenvoegsel'] = trim($registerInfo[':tussenvoegsel']))) ? NULL : $errors['tussenvoegsel'] = 'Mag ook leeg zijn. Een tussenvoegsel mag alleen bestaan uit letters bestaan en moet minder dan 10 letters bevatten';
(User_Validator::checkAchternaam($registerInfo[':achternaam'] = trim($registerInfo[':achternaam']))) ? NULL : $errors['achternaam'] = 'Een achternaam mag alleen uit letters bestaan en moet meer dan 1 letter en minder dan 25 letters bevatten';
(User_Validator::checkEmail($registerInfo[':email'] = trim($registerInfo[':email']))) ? NULL : $errors['email'] = 'Het e-mailadres moet geldig zijn.';
if(User_Validator::checkGeslacht($registerInfo[':geslacht'] = intval($registerInfo[':geslacht']))){}else{throw new Exception('Geslacht moet een INT zijn en mag niet groter zijn dan het getal 2');}

/* USER INPUT ONTHOUDEN */
$this->registry->session->setSession('username', $registerInfo[':username']);
$this->registry->session->setSession('voornaam', $registerInfo[':voornaam']);
$this->registry->session->setSession('tussenvoegsel', $registerInfo[':tussenvoegsel']);
$this->registry->session->setSession('achternaam', $registerInfo[':achternaam']);
$this->registry->session->setSession('email', $registerInfo[':email']);
$this->registry->session->setSession('geslacht', $registerInfo[':geslacht']);

if(!empty($errors)){
throw new UserException('Een aantal velden voldoet niet aan de voorwaarden', $errors);
}

/* NOG WAT DINGETJES DOEN ^^ */
$registerInfo[':regip'] = User_Validator::getIp();
$registerInfo[':hash'] = User_Validator::generateHash($registerInfo[':password']);
unset($registerInfo[':passwordrepeat']);
unset($registerInfo[':password']);

$sql = '
INSERT INTO
tbl_gebruikers
(username, voornaam, tussenvoegsel, achternaam, hash, email, geslacht, regip, regdatetime)
VALUES
(:username, :voornaam, :tussenvoegsel, :achternaam, :hash, :email, :geslacht, :regip, NOW())';

$stmt = $this->registry->db->prepare($sql);

$succes = $stmt->execute($registerInfo);

if($stmt->rowCount() == 0)
{
throw new UserException('Registratie mislukt!!');
}
$this->registry->session->unsetSession('username');
$this->registry->session->unsetSession('voornaam');
$this->registry->session->unsetSession('tussenvoegsel');
$this->registry->session->unsetSession('achternaam');
$this->registry->session->unsetSession('email');
$this->registry->session->unsetSession('geslacht');

return true;

}

public function changePassword($oldpassword, $newpassword, $newpasswordrepeat){

if($this->loggedIn == false)
{
throw new Exception('Je kunt je wachtwoord niet veranderen als je niet ingelogd bent');
}
if($newpassword != $newpasswordrepeat) { throw new Exception('Wachtwoorden moeten hetzelfde zijn'); }
if(User_Validator::checkPassword($newpassword)) { throw new Exception('Wachtwoord moet langer dan 6 en korter dan 18 tekens zijn. Mag alleen bestaan uit letters, cijfers, "_" en "-"'); }

/* Hash uit de database halen */
$sql = 'SELECT hash FROM tbl_gebruikers WHERE id = :id';
$stmt = $this->registry->db->prepare($sql);
$stmt->bindParam(':id', $this->id, PDO::PARAM_INT);
$stmt->execute();

if($stmt->rowCount() != 1)
{
throw new Exception('Hash niet gevonden :|');
}
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$dbHash = $result['hash'];
$userHash = User_Validator::generateHash($oldpassword, $dbHash);

if($dbHash != $userHash){
throw new Exception('Je wachtwoord is niet juist.');
}

$newHash = User_Validator::generateHash($newpassword);

$sql = '
UPDATE tbl_gebruikers
SET
hash = :hash
WHERE
id = :id';
$stmt = $this->registry->db->prepare($sql);
$stmt->bindParam(':id', $this->id);
$stmt->bindParam(':hash', $newHash);
$succes = $stmt->execute();

if(!$succes)
{
throw new UserException('Update query mislukt');
}





}





}



?>

Ik weet niet zeker of ik hem zo goed heb, of dat ik nog meerdere objecten nodig heb, maar ik hoor het graag ;)

Reageren