1 Dynamische Websites Week 102 INFO Feedback vraag het in de labo s als je feedback wilt op je code Lessen op 5/12 en 12/12 om op 19/12 om 11.003 KLEU...
INFO • Feedback • vraag het in de labo’s als je feedback wilt op je code
• Lessen • op 5/12 en 12/12 om 17.15 • op 19/12 om 11.00
KLEURENCODE • GROEN = zelf kunnen schrijven • PAARS = code moet je niet zelf kunnen
schrijven, maar moet je wel begrijpen, kunnen uitleggen en gebruiken op de juiste plaatsen en hier moet je eventueel een methode moeten kunnen toevoegen indien nodig
AGENDA • Loader • Input
PROBLEEM • PHP code is nu vervuild met require_once op verschillende plaatsen wanneer we bepaalde php files en/of klassen nodig hebben
CATEGORYCONTROLLER.PHP _categoryMapper = new CategoryMapper(); }
CATEGORYMAPPER.PHP
OPLOSSING • Loader klasse •
require_once code wordt hierdoor weg gewerkt
•
kan meerdere klassen die elkaar nodig hebben ineens laden
private function parseUri() { // strip the controllerfile out of the scriptname $scriptPrefix = str_replace(self::CONTROLLER_FILE, '', $_SERVER['SCRIPT_NAME']); $uri = str_replace(self::CONTROLLER_FILE, '', $_SERVER['REQUEST_URI']); // get the part of the uri, starting from the position after the scriptprefix $path = substr($uri, strlen($scriptPrefix)); // strip non-alphanumeric characters out of the path $path = preg_replace('/[^a-zA-Z0-9]\//', "", $path); // trim the path for / $path = trim($path, '/'); // explode the $path into three parts to get the controller, action and parameters // the @-sign is used to supress errors when the function after it fails @list($controller, $action, $params) = explode("/", $path, 3); if (isset($controller)) { $this->setController($controller); } if (isset($action)) { $this->setAction($action); } if (isset($params)) { $this->setParams(explode("/", $params)); } }
FRONTCONTROLLER.PHP private function setController($controller) { $controller = ($controller) ? $controller : self::DEFAULT_CONTROLLER; $this->controller = ucfirst(strtolower($controller)) . 'Controller'; // create an instance of the controller as an object $this->_controllerObject = $this->_loader->getController($this->controller, self::DEFAULT_CONTROLLER); return $this; } private function setAction($action) { ...} private function setParams(array $params) { ...}
FRONTCONTROLLER.PHP public function run() { // checking the parameter count, using Reflection (http://www.php.net/reflection) $reflector = new ReflectionClass($this->controller); $method = $reflector->getMethod($this->action); $parameters = $method->getNumberOfRequiredParameters(); if (($parameters) > count($this->params)) { die("Action '$this->action' in class '$this->controller' expects $parameters mandatory parameter(s), you only provided " . } // call the method based on $this->action and the params call_user_func_array(array($this->_controllerObject, $this->action), $this->params); } }
public function __construct() { $this->_loader = Loader::getInstance(); $this->_input = new Input(); $this->_template = new Template(); $this->_validator = new Validator(); $menuMapper = $this->_loader->getModelMapper('menu'); $this->_template->menuItems = $menuMapper->getMenuItems(); $this->_template->setPartial('navbar'); $this->_template->setPartial('headermeta'); $this->_template->setPartial('statusMessage'); $this->_template->setPartial('footer');
}
// haal de statusberichten uit een sessie, dus van een vorige pagina voor de redirect $this->_getStatusMessage();
CATEGORYCONTROLLLER.PHP $this->_input->post(‘categoryname’) public function add() is de ingegeven string in categorienaam veld gesanitized dus { ‘amerika’ $category = new Category(); $this->_template->_category = $category; if ($_POST) { $category->setCategoryname($this->_input->post('categoryname')); $this->_validator->isRequired('categoryname', $category->getCategoryname()); if ($this->_validator->isValidForm()) { $this->_categoryMapper->add($this->_template->_category); $this->_navigateToOverview('Nieuwe categorie toegevoegd.'); } else { $this->_setErrorMessages('Er zijn fouten in het toevoegen van de categorie.'); } } $this->_template->setPagetitle('voeg categorie toe'); $this->_template->render('category/form'); }
INPUT.PHP
public function post($key, $default = false) { if (isset($_POST[$key])) { return $this->_sanitize($_POST[$key]); } else { return $default; } } private function _sanitize($input) { if (is_array($input)) { for ($i = 0; $i < count($input); $i++) { $this->_sanitize($input[$i]); } } else { $input = trim($input); $input = htmlentities($input, ENT_QUOTES, "UTF-8"); }
}
} ...
return $input;
CATEGORYCONTROLLLER.PHP deze methode zet in de fieldmessages een key ‘categoryname’ en public function add() zet hier een new message met een lege message en status true { $category = new Category(); $this->_template->_category = $category; if ($_POST) { $category->setCategoryname($this->_input->post('categoryname')); $this->_validator->isRequired('categoryname', $category->getCategoryname()); if ($this->_validator->isValidForm()) { $this->_categoryMapper->add($this->_template->_category); $this->_navigateToOverview('Nieuwe categorie toegevoegd.'); } else { $this->_setErrorMessages('Er zijn fouten in het toevoegen van de categorie.'); } } $this->_template->setPagetitle('voeg categorie toe'); $this->_template->render('category/form'); }
VALIDATOR.PHP
class Validator { private $_fieldMessages = array(); public function isRequired($key, $value) { return $this->isValidLength($key, $value); } public function isValidLength($key, $value, $min = 1, $max=100) { if (strlen($value) < $min || strlen($value) > $max) { $this->_fieldMessages[$key] = new Message($key . " moet minstens $min lang zijn en mag niet meer dan $max zijn", false); $valid = false; } else { $this->_fieldMessages[$key] = new Message('', true); $valid = true; } return $valid; } ...
CATEGORYCONTROLLLER.PHP public function add() { $category = new Category(); $this->_template->_category = $category; if ($_POST) { $category->setCategoryname($this->_input->post('categoryname')); $this->_validator->isRequired('categoryname', $category->getCategoryname()); if ($this->_validator->isValidForm()) { $this->_categoryMapper->add($this->_template->_category); $this->_navigateToOverview('Nieuwe categorie toegevoegd.'); } else { $this->_setErrorMessages('Er zijn fouten in het toevoegen van de categorie.'); } } $this->_template->setPagetitle('voeg categorie toe'); $this->_template->render('category/form'); }
VALIDATOR.PHP
deze methode kijkt in de array van fieldmessages als er een message inzit waarvan de status op false staat (dat betekent dat er nog fouten in het form zitten) en geeft dan false terug, anders betekent het dat er geen fouten in het form meer zitten en dan geeft deze methode true terug
class Validator { private $_fieldMessages = array();
public function isValidForm () { foreach ($this->_fieldMessages as $field) { if (!$field->getStatus()) { return false; } } return true; } ...
CATEGORYCONTROLLLER.PHP public function add() { $category = new Category(); $this->_template->_category = $category; if ($_POST) { $category->setCategoryname($this->_input->post('categoryname')); $this->_validator->isRequired('categoryname', $category->getCategoryname()); if ($this->_validator->isValidForm()) { $this->_categoryMapper->add($this->_template->_category); $this->_navigateToOverview('Nieuwe categorie toegevoegd.'); } else { $this->_setErrorMessages('Er zijn fouten in het toevoegen van de categorie.'); } } $this->_template->setPagetitle('voeg categorie toe'); $this->_template->render('category/form'); }
CATEGORYMAPPER.PHP
MAPPER.PHP
$object = object(Category)#14 (2) { ["_categoryname":"Category":private]=> string(7) "Amerika" ["_id":"Identifiable":private]=> NULL } public function __construct($table, $type) {
public function execute($sql, $arguments = array()) { if (!is_array($arguments)) { $arguments = array($arguments); }
gaat SQL injections tegen
try { $stmt = $this->_db->prepare($sql); $stmt->execute($arguments); $stmt->setFetchMode(PDO::FETCH_ASSOC); } catch(PDOException $e) { error_log($e->getMessage()); } nu pas worden de argumenten in de query gezet en wordt de query uitgevoerd return $stmt; } ...
INSERT INTO category (categoryname) VALUES (‘amerika’)
CATEGORYCONTROLLLER.PHP public function add() { $category = new Category(); $this->_template->_category = $category; if ($_POST) { $category->setCategoryname($this->_input->post('categoryname')); $this->_validator->isRequired('categoryname', $category->getCategoryname()); if ($this->_validator->isValidForm()) { $this->_categoryMapper->add($this->_template->_category); $this->_navigateToOverview('Nieuwe categorie toegevoegd.'); } else { $this->_setErrorMessages('Er zijn fouten in het toevoegen van de categorie.'); } } $this->_template->setPagetitle('voeg categorie toe'); $this->_template->render('category/form'); }
CATEGORYCONTROLLLER.PHP
private function _navigateToOverview($message) { $statusMessage = new Message($message, true); $this->_setStatusMessage($statusMessage); redirect('category/index'); } }
$statusMessage is een new Message object met als message 'Nieuwe categorie toegevoegd.' en als status true (want het is gelukt het adden)
MESSAGE.PHP
function __construct($message = '', $status = true) { $this->_setMessage($message); $this->_setStatus($status); } private function _setMessage($message) { $this->_message = $message; } public function getMessage() { return $this->_message; } private function _setStatus($status) { $this->_status = $status; } public function getStatus() { return $this->_status; } }
CATEGORYCONTROLLLER.PHP
private function _navigateToOverview($message) { $statusMessage = new Message($message, true); $this->_setStatusMessage($statusMessage); redirect('category/index'); } }
$statusMessage wordt toegevoegd aan de SESSION (want we gaan redirecten naar een andere pagina en dan moet het in de SESSION gestopt worden de statusmessage) (om te kunnen tonen wanneer we gaan redirecten naar de volgende pagina)
CONTROLLLER.PHP protected function _setStatusMessage($statusMessage, $resetStatusMessage = false) { // als reset: dan direct zetten en niet via sessie gaan if ($resetStatusMessage) { $this->_template->setStatusMessage($statusMessage); } else { $_SESSION['statusMessage'] = $statusMessage; } }
CATEGORYCONTROLLLER.PHP
private function _navigateToOverview($message) { $statusMessage = new Message($message, true); $this->_setStatusMessage($statusMessage); redirect('category/index'); } }
ROUTEHELPERS.PHP
CATEGORYCONTROLLLER.PHP
private function _navigateToOverview($message) { $statusMessage = new Message($message, true); $this->_setStatusMessage($statusMessage); redirect('category/index'); } redirect naar category/index }
dus hier begint het spel opnieuw, we gaan terug naar index.php en dus een FrontController object maken en CategoryController object en naar index methode hier gaat nu ook $statusMessage uit de SESSION gehaald worden om te tonen op de index pagina dat het toevoegen van de category gelukt is
CONTROLLER.PHP
$this->_getStatusMessage() heeft message object met als message 'Nieuwe categorie toegevoegd.' en als status true in de SESSION zitten
public function __construct() { $this->_loader = Loader::getInstance(); $this->_input = new Input(); $this->_template = new Template(); $this->_validator = new Validator(); $menuMapper = $this->_loader->getModelMapper('menu'); $this->_template->menuItems = $menuMapper->getMenuItems(); $this->_template->setPartial('navbar'); $this->_template->setPartial('headermeta'); $this->_template->setPartial('statusMessage'); $this->_template->setPartial('footer');
}
// haal de statusberichten uit een sessie, dus van een vorige pagina voor de redirect $this->_getStatusMessage();
CONTROLLLER.PHP private function _getStatusMessage() { if (isset($_SESSION['statusMessage'])) { $this->_template->setStatusMessage($_SESSION['statusMessage']); unset($_SESSION['statusMessage']); } }
private function parseUri() { // strip the controllerfile out of the scriptname $scriptPrefix = str_replace(self::CONTROLLER_FILE, '', $_SERVER['SCRIPT_NAME']); $uri = str_replace(self::CONTROLLER_FILE, '', $_SERVER['REQUEST_URI']); // get the part of the uri, starting from the position after the scriptprefix $path = substr($uri, strlen($scriptPrefix)); // strip non-alphanumeric characters out of the path $path = preg_replace('/[^a-zA-Z0-9]\//', "", $path); // trim the path for / $path = trim($path, '/'); // explode the $path into three parts to get the controller, action and parameters // the @-sign is used to supress errors when the function after it fails @list($controller, $action, $params) = explode("/", $path, 3); if (isset($controller)) { $this->setController($controller); } if (isset($action)) { $this->setAction($action); } if (isset($params)) { $this->setParams(explode("/", $params)); } }
FRONTCONTROLLER.PHP public function run() { // checking the parameter count, using Reflection (http://www.php.net/reflection) $reflector = new ReflectionClass($this->controller); $method = $reflector->getMethod($this->action); $parameters = $method->getNumberOfRequiredParameters(); if (($parameters) > count($this->params)) { die("Action '$this->action' in class '$this->controller' expects $parameters mandatory parameter(s), you only provided " . } // call the method based on $this->action and the params call_user_func_array(array($this->_controllerObject, $this->action), $this->params); } }
public function __construct() { $this->_loader = Loader::getInstance(); $this->_input = new Input(); $this->_template = new Template(); $this->_validator = new Validator(); $menuMapper = $this->_loader->getModelMapper('menu'); $this->_template->menuItems = $menuMapper->getMenuItems(); $this->_template->setPartial('navbar'); $this->_template->setPartial('headermeta'); $this->_template->setPartial('statusMessage'); $this->_template->setPartial('footer');
}
// haal de statusberichten uit een sessie, dus van een vorige pagina voor de redirect $this->_getStatusMessage();
CATEGORYCONTROLLLER.PHP $this->_input->post(‘categoryname’) public function add() is de ingegeven string in categorienaam veld gesanitized dus ‘’ { $category = new Category(); $this->_template->_category = $category; if ($_POST) { $category->setCategoryname($this->_input->post('categoryname')); $this->_validator->isRequired('categoryname', $category->getCategoryname()); if ($this->_validator->isValidForm()) { $this->_categoryMapper->add($this->_template->_category); $this->_navigateToOverview('Nieuwe categorie toegevoegd.'); } else { $this->_setErrorMessages('Er zijn fouten in het toevoegen van de categorie.'); } } $this->_template->setPagetitle('voeg categorie toe'); $this->_template->render('category/form'); }
INPUT.PHP
public function post($key, $default = false) { if (isset($_POST[$key])) { return $this->_sanitize($_POST[$key]); } else { return $default; } } private function _sanitize($input) { if (is_array($input)) { for ($i = 0; $i < count($input); $i++) { $this->_sanitize($input[$i]); } } else { $input = trim($input); $input = htmlentities($input, ENT_QUOTES, "UTF-8"); }
}
} ...
return $input;
CATEGORYCONTROLLLER.PHP
deze methode zet in de fieldmessages een key ‘categoryname’ en zet hier een new message in met een message “categoryname public function add() moet minstens 1 lang zijn en mag niet meer dan $100 zijn” en { $category = new Category(); status false $this->_template->_category = $category; if ($_POST) { $category->setCategoryname($this->_input->post('categoryname')); $this->_validator->isRequired('categoryname', $category->getCategoryname()); if ($this->_validator->isValidForm()) { $this->_categoryMapper->add($this->_template->_category); $this->_navigateToOverview('Nieuwe categorie toegevoegd.'); } else { $this->_setErrorMessages('Er zijn fouten in het toevoegen van de categorie.'); } } $this->_template->setPagetitle('voeg categorie toe'); $this->_template->render('category/form'); }
VALIDATOR.PHP
class Validator { private $_fieldMessages = array(); public function isRequired($key, $value) { return $this->isValidLength($key, $value); } public function isValidLength($key, $value, $min = 1, $max=100) { if (strlen($value) < $min || strlen($value) > $max) { $this->_fieldMessages[$key] = new Message($key . " moet minstens $min lang zijn en mag niet meer dan $max zijn", false); $valid = false; } else { $this->_fieldMessages[$key] = new Message('', true); $valid = true; } return $valid; } ...
CATEGORYCONTROLLLER.PHP public function add() { $category = new Category(); $this->_template->_category = $category; if ($_POST) { $category->setCategoryname($this->_input->post('categoryname')); $this->_validator->isRequired('categoryname', $category->getCategoryname()); if ($this->_validator->isValidForm()) { $this->_categoryMapper->add($this->_template->_category); $this->_navigateToOverview('Nieuwe categorie toegevoegd.'); } else { $this->_setErrorMessages('Er zijn fouten in het toevoegen van de categorie.'); } } $this->_template->setPagetitle('voeg categorie toe'); $this->_template->render('category/form'); }
VALIDATOR.PHP
deze methode kijkt in de array van fieldmessages als er een message inzit waarvan de status op false staat (dat betekent dat er nog fouten in het form zitten) en geeft dan false terug, anders betekent het dat er geen fouten in het form meer zitten en dan geeft deze methode true terug
class Validator { private $_fieldMessages = array();
public function isValidForm () { foreach ($this->_fieldMessages as $field) { if (!$field->getStatus()) { return false; } } return true; } ...
CATEGORYCONTROLLLER.PHP public function add() { $category = new Category(); $this->_template->_category = $category; if ($_POST) { $category->setCategoryname($this->_input->post('categoryname')); $this->_validator->isRequired('categoryname', $category->getCategoryname()); if ($this->_validator->isValidForm()) { $this->_categoryMapper->add($this->_template->_category); $this->_navigateToOverview('Nieuwe categorie toegevoegd.'); } else { $this->_setErrorMessages('Er zijn fouten in het toevoegen van de categorie.'); } } $this->_template->setPagetitle('voeg categorie toe'); $this->_template->render('category/form'); }
CONTROLLER.PHP protected function _setErrorMessages ($message) { $statusMessage = new Message($message, false); $this->_setStatusMessage($statusMessage, true); $fieldMessages = $this->_validator->getFieldMessages(); $this->_template->setFieldMessages($fieldMessages); } $message = 'Er zijn fouten in het toevoegen van de categorie.' $statusMessage = new Message object met als message 'Er zijn fouten in het toevoegen van de categorie.' en als status false $statusMessage wordt gezet en tweede parameter is true omdat we niet redirecten, maar op dezelfde pagina de fouten willen tonen, dus statusmessage moet nu ook niet in de SESSION gestopt worden
CONTROLLLER.PHP protected function _setStatusMessage($statusMessage, $resetStatusMessage = false) { // als reset: dan direct zetten en niet via sessie gaan if ($resetStatusMessage) { $this->_template->setStatusMessage($statusMessage); } else { $_SESSION['statusMessage'] = $statusMessage; } }
CONTROLLER.PHP protected function _setErrorMessages ($message) { $statusMessage = new Message($message, false); $this->_setStatusMessage($statusMessage, true); $fieldMessages = $this->_validator->getFieldMessages(); $this->_template->setFieldMessages($fieldMessages); }
$fieldMessages = array(1) { ["categoryname"]=> object(Message)#15 (2) { ["_status":"Message":private]=> bool(false) ["_message":"Message":private]=> string(68) "categoryname moet minstens 1 lang zijn en mag niet meer dan 100 zijn" } }
CATEGORYCONTROLLLER.PHP public function add() { $category = new Category(); $this->_template->_category = $category; if ($_POST) { $category->setCategoryname($this->_input->post('categoryname')); $this->_validator->isRequired('categoryname', $category->getCategoryname()); if ($this->_validator->isValidForm()) { $this->_categoryMapper->add($this->_template->_category); $this->_navigateToOverview('Nieuwe categorie toegevoegd.'); } else { $this->_setErrorMessages('Er zijn fouten in het toevoegen van de categorie.'); } } $this->_template->setPagetitle('voeg categorie toe'); $this->_template->render('category/form'); }