mirror of
https://github.com/kevinveenbirkenbach/coding-challenge-online-shop.git
synced 2024-11-01 00:53:10 +01:00
Implemented Navigation
This commit is contained in:
parent
401fa64733
commit
d480467615
@ -27,7 +27,14 @@ abstract class AbstractController
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function render(string $template,array $variables=[]):void{
|
protected function render(string $template,array $variables=[]):void{
|
||||||
echo $this->core->getTwig()->render($template,$variables);
|
echo $this->core->getTwig()->render($template,$this->addUser($variables));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addUser(array $variables):array{
|
||||||
|
if(array_key_exists('user', $variables)){
|
||||||
|
throw new \Exception('Key user isn\'t allowed!');
|
||||||
|
}
|
||||||
|
$variables['user'] = $this->core->getUser();
|
||||||
|
return $variables;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
67
src/controller/AbstractDefaultController.php
Normal file
67
src/controller/AbstractDefaultController.php
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
namespace controller;
|
||||||
|
|
||||||
|
use router\link\Link;
|
||||||
|
use router\Router;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This controllers render the frames/default.html.twig
|
||||||
|
*
|
||||||
|
* @author kevinfrantz
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class AbstractDefaultController extends AbstractController
|
||||||
|
{
|
||||||
|
|
||||||
|
protected function render(string $template, array $variables = []): void
|
||||||
|
{
|
||||||
|
parent::render($template, $this->addMenuItems($variables));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addMenuItems(array $variables): array
|
||||||
|
{
|
||||||
|
if (array_key_exists('menu_items', $variables)) {
|
||||||
|
throw new \Exception('You aren\'t allowed to define this key!');
|
||||||
|
}
|
||||||
|
$variables['menu_items'] = $this->getMenuItems();
|
||||||
|
return $variables;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getMenuItems(): array
|
||||||
|
{
|
||||||
|
return array_merge([
|
||||||
|
new Link([], 'home'),
|
||||||
|
new Link([
|
||||||
|
Router::CONTROLLER => 'product',
|
||||||
|
Router::ACTION => 'list'
|
||||||
|
], 'product list'),
|
||||||
|
new Link([
|
||||||
|
Router::CONTROLLER => 'order',
|
||||||
|
Router::ACTION => 'basket'
|
||||||
|
], 'basket')
|
||||||
|
], $this->getUserMenuItems());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getUserMenuItems(): array
|
||||||
|
{
|
||||||
|
if ($this->core->getUser()) {
|
||||||
|
return [
|
||||||
|
new Link([
|
||||||
|
Router::CONTROLLER => 'user',
|
||||||
|
Router::ACTION => 'logout'
|
||||||
|
], 'logout')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
new Link([
|
||||||
|
Router::CONTROLLER => 'user',
|
||||||
|
Router::ACTION => 'login'
|
||||||
|
], 'login'),
|
||||||
|
new Link([
|
||||||
|
Router::CONTROLLER => 'user',
|
||||||
|
Router::ACTION => 'register'
|
||||||
|
], 'register')
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,17 +1,17 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace controller\product;
|
namespace controller\product;
|
||||||
|
|
||||||
use controller\AbstractController;
|
|
||||||
use repository\product\Product as ProductRepository;
|
use repository\product\Product as ProductRepository;
|
||||||
use core\Core;
|
use core\Core;
|
||||||
use router\Link;
|
use router\link\Link;
|
||||||
|
use controller\AbstractDefaultController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author kevinfrantz
|
* @author kevinfrantz
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
final class Product extends AbstractController implements ProductInterface
|
final class Product extends AbstractDefaultController implements ProductInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,7 +23,7 @@ final class Product extends AbstractController implements ProductInterface
|
|||||||
public function __construct(Core $core)
|
public function __construct(Core $core)
|
||||||
{
|
{
|
||||||
parent::__construct($core);
|
parent::__construct($core);
|
||||||
$this->productRepository = new ProductRepository($this->core->getDatabase());
|
$this->productRepository = new ProductRepository($this->core);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function list(?string $color = null): void
|
public function list(?string $color = null): void
|
||||||
|
@ -1,43 +1,17 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace controller\standart;
|
namespace controller\standart;
|
||||||
|
|
||||||
use controller\AbstractController;
|
use controller\AbstractDefaultController;
|
||||||
use router\Link;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author kevinfrantz
|
* @author kevinfrantz
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
final class Standart extends AbstractController implements StandartInterface
|
final class Standart extends AbstractDefaultController implements StandartInterface
|
||||||
{
|
{
|
||||||
public function homepage():void{
|
public function homepage():void{
|
||||||
$this->render('standart/homepage.html.twig',['options'=>$this->getAllOptions()]);
|
$this->render('standart/homepage.html.twig');
|
||||||
}
|
|
||||||
|
|
||||||
private function getAllOptions(){
|
|
||||||
return [
|
|
||||||
new Link([
|
|
||||||
'controller'=>'user',
|
|
||||||
'action'=>'login'
|
|
||||||
],'login'),
|
|
||||||
new Link([
|
|
||||||
'controller'=>'user',
|
|
||||||
'action'=>'logout'
|
|
||||||
],'logout'),
|
|
||||||
new Link([
|
|
||||||
'controller'=>'user',
|
|
||||||
'action'=>'register'
|
|
||||||
],'register'),
|
|
||||||
new Link([
|
|
||||||
'controller'=>'product',
|
|
||||||
'action'=>'list'
|
|
||||||
],'product list'),
|
|
||||||
new Link([
|
|
||||||
'controller'=>'order',
|
|
||||||
'action'=>'basket'
|
|
||||||
],'basket'),
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace repository;
|
namespace repository;
|
||||||
|
|
||||||
|
use core\CoreInterface;
|
||||||
|
use entity\user\UserInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author kevinfrantz
|
* @author kevinfrantz
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -13,8 +16,14 @@ abstract class AbstractRepository
|
|||||||
*/
|
*/
|
||||||
protected $database;
|
protected $database;
|
||||||
|
|
||||||
public function __construct(\PDO $database){
|
/**
|
||||||
$this->database = $database;
|
* @var UserInterface
|
||||||
|
*/
|
||||||
|
protected $user;
|
||||||
|
|
||||||
|
public function __construct(CoreInterface $core){
|
||||||
|
$this->database = $core->getDatabase();
|
||||||
|
$this->user = $core->getUser();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
<?php
|
|
||||||
namespace router;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A link containes out of get parameters
|
|
||||||
* @author kevinfrantz
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
final class Link
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* ArrayCollection would be nicer but I have to save time ;)
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $parameters;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $name;
|
|
||||||
|
|
||||||
public function __construct(array $parameters=[],string $name = ''){
|
|
||||||
$this->setParameters($parameters);
|
|
||||||
$this->setName($name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setParameters(array $parameters):void{
|
|
||||||
$this->parameters = $parameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setName(string $name):void{
|
|
||||||
$this->name = $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getName():string{
|
|
||||||
return $this->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUrl():string{
|
|
||||||
return "index.php".$this->getParameters();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getParameters():string{
|
|
||||||
$parameters = '?';
|
|
||||||
foreach ($this->parameters as $key=>$value){
|
|
||||||
$parameters .= $key.'='.$value.'&';
|
|
||||||
}
|
|
||||||
return $parameters;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -14,7 +14,10 @@ use controller\order\Order;
|
|||||||
*/
|
*/
|
||||||
final class Router implements RouterInterface
|
final class Router implements RouterInterface
|
||||||
{
|
{
|
||||||
|
const CONTROLLER='controller';
|
||||||
|
|
||||||
|
const ACTION = 'action';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @var CoreInterface
|
* @var CoreInterface
|
||||||
@ -38,10 +41,10 @@ final class Router implements RouterInterface
|
|||||||
public function route()
|
public function route()
|
||||||
{
|
{
|
||||||
if ($this->get) {
|
if ($this->get) {
|
||||||
switch ($this->get['controller']) {
|
switch ($this->get[self::CONTROLLER]) {
|
||||||
case 'user':
|
case 'user':
|
||||||
$userController = new User();
|
$userController = new User();
|
||||||
switch ($this->get['action']) {
|
switch ($this->get[self::ACTION]) {
|
||||||
case 'login':
|
case 'login':
|
||||||
return $userController->login();
|
return $userController->login();
|
||||||
case 'logout':
|
case 'logout':
|
||||||
@ -51,13 +54,13 @@ final class Router implements RouterInterface
|
|||||||
}
|
}
|
||||||
case 'product':
|
case 'product':
|
||||||
$productController = new Product($this->core);
|
$productController = new Product($this->core);
|
||||||
switch ($this->get['action']) {
|
switch ($this->get[self::ACTION]) {
|
||||||
case 'list':
|
case 'list':
|
||||||
return $productController->list(($this->get['color'])?$this->get['color']:null);
|
return $productController->list(($this->get['color'])?$this->get['color']:null);
|
||||||
}
|
}
|
||||||
case 'order':
|
case 'order':
|
||||||
$orderController = new Order($this->core);
|
$orderController = new Order($this->core);
|
||||||
switch ($this->get['action']){
|
switch ($this->get[self::ACTION]){
|
||||||
case 'store':
|
case 'store':
|
||||||
return $orderController->store();
|
return $orderController->store();
|
||||||
case 'basket':
|
case 'basket':
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace router;
|
namespace router\link;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A button containes out of a link and post parameters
|
* A button containes out of a link and post parameters
|
71
src/router/link/Link.php
Normal file
71
src/router/link/Link.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
namespace router\link;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A link containes out of get parameters
|
||||||
|
*
|
||||||
|
* @author kevinfrantz
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
final class Link implements LinkInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ArrayCollection would be nicer but I have to save time ;)
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $parameters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
public function __construct(array $parameters = [], string $name = '')
|
||||||
|
{
|
||||||
|
$this->setParameters($parameters);
|
||||||
|
$this->setName($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setParameters(array $parameters): void
|
||||||
|
{
|
||||||
|
$this->parameters = $parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setName(string $name): void
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUrl(): string
|
||||||
|
{
|
||||||
|
return "index.php" . $this->getParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getParameters(): string
|
||||||
|
{
|
||||||
|
$parameters = '?';
|
||||||
|
foreach ($this->parameters as $key => $value) {
|
||||||
|
$parameters .= $key . '=' . $value . '&';
|
||||||
|
}
|
||||||
|
return $parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isActive(): bool
|
||||||
|
{
|
||||||
|
foreach ($this->parameters as $key => $parameter) {
|
||||||
|
if (! array_key_exists($key, $_GET) || (array_key_exists($key, $_GET) && $_GET[$key]!==$parameter)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
17
src/router/link/LinkInterface.php
Normal file
17
src/router/link/LinkInterface.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
namespace router\link;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author kevinfrantz
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
interface LinkInterface
|
||||||
|
{
|
||||||
|
public function getName():string;
|
||||||
|
|
||||||
|
public function getUrl():string;
|
||||||
|
|
||||||
|
public function isActive():bool;
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,7 @@
|
|||||||
{% extends "base.html.twig" %}
|
{% extends "base.html.twig" %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
|
{% include 'frames/structure/navbar.html.twig' with menu_items %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="page-header">
|
|
||||||
<h1>Online Shop</h1>
|
|
||||||
<hr />
|
|
||||||
</div>
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
32
src/template/frames/structure/navbar.html.twig
Normal file
32
src/template/frames/structure/navbar.html.twig
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||||
|
<a class="navbar-brand" href="/">Online Shop</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
|
<ul class="navbar-nav mr-auto">
|
||||||
|
{% for item in menu_items %}
|
||||||
|
<!--<li class="nav-item active">
|
||||||
|
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
|
||||||
|
</li>
|
||||||
|
-->
|
||||||
|
<li class="nav-item {% if item.active %}active{% endif %}">
|
||||||
|
<a class="nav-link" href="{{ item.url }}">{{ item.name }}</a>
|
||||||
|
</li>
|
||||||
|
<!--
|
||||||
|
<li class="nav-item dropdown">
|
||||||
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
Dropdown
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||||
|
<a class="dropdown-item" href="#">Action</a>
|
||||||
|
<a class="dropdown-item" href="#">Another action</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item" href="#">Something else here</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
-->
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
@ -24,7 +24,7 @@
|
|||||||
<b>price:</b>
|
<b>price:</b>
|
||||||
<ul>
|
<ul>
|
||||||
<li>{{ product.getPrice.getNetto.getFloat }} {{ product.getPrice.getNetto.getSymbol }} <i>(net)</i></li>
|
<li>{{ product.getPrice.getNetto.getFloat }} {{ product.getPrice.getNetto.getSymbol }} <i>(net)</i></li>
|
||||||
<li>{{ product.getPrice.getGross.getFloat }} {{ product.getPrice.getGross.getSymbol }} <i>(gross)</i></li>
|
<li>{{ product.getPrice.getGross.getFloat }} {{ product.getPrice.getGross.getSymbol }} <i>(gross)</i>, Tax: {{ product.getPrice.getTax }} %</li>
|
||||||
</ul>
|
</ul>
|
||||||
</span>
|
</span>
|
||||||
<a href="#" class="btn btn-primary">Add to basket</a>
|
<a href="#" class="btn btn-primary">Add to basket</a>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<h2>Welcome to the online shop!</h2>
|
<h2>Welcome to the online shop!</h2>
|
||||||
You have the following options:
|
You have the following options:
|
||||||
<ul>
|
<ul>
|
||||||
{% for option in options %}
|
{% for option in menu_items %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{option.getUrl}}">{{option.getName}}</a>
|
<a href="{{option.getUrl}}">{{option.getName}}</a>
|
||||||
</li>
|
</li>
|
||||||
|
Loading…
Reference in New Issue
Block a user