Skip to content

Instantly share code, notes, and snippets.

@elmarputz
Created December 16, 2016 08:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elmarputz/3d0ff461cc25db0e53d1a7cd55c5565c to your computer and use it in GitHub Desktop.
Save elmarputz/3d0ff461cc25db0e53d1a7cd55c5565c to your computer and use it in GitHub Desktop.
Controller.php
<?php
/**
* Controller
*
* class handles POST requests and redirects
* the client after processing
* - demo of singleton pattern
*/
class Controller extends BaseObject {
// static strings used in views
const ACTION = 'action';
const METHOD_POST = 'POST';
const PAGE = 'page';
const CC_NAME = 'nameOnCard';
const CC_NUMBER = 'cardNumber';
const ACTION_ADD = 'addToCart';
const ACTION_REMOVE = 'removeFromCart';
const ACTION_ORDER = 'placeOrder';
const ACTION_LOGIN = 'login';
const USR_NAME = 'userName';
const USR_PASSWORD = 'password';
const ACTION_LOGOUT = 'logout';
private static $instance = false;
/**
*
* @return Controller
*/
public static function getInstance() {
if (!self::$instance) {
self::$instance = new Controller();
}
return self::$instance;
}
private function __construct() {
}
/**
*
* processes POST requests and redirects client depending on selected
* action
*
* @return bool
* @throws Exception
*/
public function invokePostAction() {
if ($_SERVER['REQUEST_METHOD'] != self::METHOD_POST) {
throw new Exception('Controller can only handle POST requests.');
return null;
} elseif (!isset($_REQUEST[self::ACTION])) {
throw new Exception('Action not specified.');
return null;
}
// now process the assigned action
$action = $_REQUEST[self::ACTION];
switch ($action) {
case self::ACTION_ADD :
ShoppingCart::add((int) $_REQUEST['bookId']);
Util::redirect();
break;
case self::ACTION_REMOVE :
ShoppingCart::remove((int) $_REQUEST['bookId']);
Util::redirect();
break;
case self::ACTION_ORDER :
$user = AuthenticationManager::getAuthenticatedUser();
// abort
if ($user == null) {
$this->forwardRequest(array('Not logged in.'));
break;
}
// else
if ($this->processCheckout($_POST[self::CC_NAME], $_POST[self::CC_NUMBER]))
break;
else
return null;
case self::ACTION_LOGIN :
//try to authenticate the given user
if (!AuthenticationManager::authenticate($_REQUEST[self::USR_NAME], $_REQUEST[self::USR_PASSWORD])) {
$this->forwardRequest(array('Invalid user name or password.'));
}
Util::redirect();
break;
case self::ACTION_LOGOUT :
//sign out current user
AuthenticationManager::signOut();
Util::redirect();
break;
default : throw new Exception('Unknown controller action: ' . $action);
}
}
/**
*
* @param string $nameOnCard
* @param integer $cardNumber
* @return bool
*/
protected function processCheckout($nameOnCard = null, $cardNumber = null) {
$errors = array();
$nameOnCard = trim($nameOnCard);
if ($nameOnCard == null || strlen($nameOnCard) == 0) {
$errors[] = 'Invalid name on card.';
}
if ($cardNumber == null || strlen($cardNumber) != 16 || !ctype_digit($cardNumber)) {
$errors[] = 'Invalid card number. Card number must be sixteen digits.';
}
if (count($errors) > 0) {
$this->forwardRequest($errors);
return false;
}
//check cart
if (ShoppingCart::size() == 0) {
$this->forwardRequest(array('No items in cart.'));
return false;
}
//try to place a new order
$user = AuthenticationManager::getAuthenticatedUser();
$orderId = DataManager::createOrder($user->getId(), ShoppingCart::getAll(), $nameOnCard, $cardNumber);
if (!$orderId) {
$this->forwardRequest(array('Could not create order.'));
return false;
}
//clear shopping card and redirect to success page
ShoppingCart::clear();
Util::redirect('index.php?view=success&orderId=' . rawurlencode($orderId));
return true;
}
/**
*
* @param array $errors : optional assign it to
* @param string $target : url for redirect of the request
*/
protected function forwardRequest(array $errors = null, $target = null) {
//check for given target and try to fall back to previous page if needed
if ($target == null) {
if (!isset($_REQUEST[self::PAGE])) {
throw new Exception('Missing target for forward.');
}
$target = $_REQUEST[self::PAGE];
}
//forward request to target
// optional - add errors to redirect and process them in view
if (count($errors) > 0)
$target .= '&errors=' . urlencode(serialize($errors));
header('location: ' . $target);
exit();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment