mirror of
				https://github.com/kevinveenbirkenbach/coding-challenge-online-shop.git
				synced 2025-11-04 11:07:58 +00:00 
			
		
		
		
	Implemented Navigation
This commit is contained in:
		@@ -27,7 +27,14 @@ abstract class AbstractController
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    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
 | 
			
		||||
namespace controller\product;
 | 
			
		||||
 | 
			
		||||
use controller\AbstractController;
 | 
			
		||||
use repository\product\Product as ProductRepository;
 | 
			
		||||
use core\Core;
 | 
			
		||||
use router\Link;
 | 
			
		||||
use router\link\Link;
 | 
			
		||||
use controller\AbstractDefaultController;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @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)
 | 
			
		||||
    {
 | 
			
		||||
        parent::__construct($core);
 | 
			
		||||
        $this->productRepository = new ProductRepository($this->core->getDatabase());
 | 
			
		||||
        $this->productRepository = new ProductRepository($this->core);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function list(?string $color = null): void
 | 
			
		||||
 
 | 
			
		||||
@@ -1,43 +1,17 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace controller\standart;
 | 
			
		||||
 | 
			
		||||
use controller\AbstractController;
 | 
			
		||||
use router\Link;
 | 
			
		||||
use controller\AbstractDefaultController;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 *
 | 
			
		||||
 * @author kevinfrantz
 | 
			
		||||
 *        
 | 
			
		||||
 */
 | 
			
		||||
final class Standart extends AbstractController implements StandartInterface
 | 
			
		||||
final class Standart extends AbstractDefaultController implements StandartInterface
 | 
			
		||||
{
 | 
			
		||||
    public function homepage():void{
 | 
			
		||||
        $this->render('standart/homepage.html.twig',['options'=>$this->getAllOptions()]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    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'),
 | 
			
		||||
        ];
 | 
			
		||||
        $this->render('standart/homepage.html.twig');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,9 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace repository;
 | 
			
		||||
 | 
			
		||||
use core\CoreInterface;
 | 
			
		||||
use entity\user\UserInterface;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 
 | 
			
		||||
 * @author kevinfrantz
 | 
			
		||||
@@ -13,8 +16,14 @@ abstract class AbstractRepository
 | 
			
		||||
     */
 | 
			
		||||
    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,6 +14,9 @@ use controller\order\Order;
 | 
			
		||||
 */
 | 
			
		||||
final class Router implements RouterInterface
 | 
			
		||||
{
 | 
			
		||||
    const CONTROLLER='controller';
 | 
			
		||||
    
 | 
			
		||||
    const ACTION = 'action';
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
@@ -38,10 +41,10 @@ final class Router implements RouterInterface
 | 
			
		||||
    public function route()
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->get) {
 | 
			
		||||
            switch ($this->get['controller']) {
 | 
			
		||||
            switch ($this->get[self::CONTROLLER]) {
 | 
			
		||||
                case 'user':
 | 
			
		||||
                    $userController = new User();
 | 
			
		||||
                    switch ($this->get['action']) {
 | 
			
		||||
                    switch ($this->get[self::ACTION]) {
 | 
			
		||||
                        case 'login':
 | 
			
		||||
                            return $userController->login();
 | 
			
		||||
                        case 'logout':
 | 
			
		||||
@@ -51,13 +54,13 @@ final class Router implements RouterInterface
 | 
			
		||||
                    }
 | 
			
		||||
                case 'product':
 | 
			
		||||
                    $productController = new Product($this->core);
 | 
			
		||||
                    switch ($this->get['action']) {
 | 
			
		||||
                    switch ($this->get[self::ACTION]) {
 | 
			
		||||
                        case 'list':
 | 
			
		||||
                            return $productController->list(($this->get['color'])?$this->get['color']:null);
 | 
			
		||||
                    }
 | 
			
		||||
                case 'order':
 | 
			
		||||
                    $orderController = new Order($this->core);
 | 
			
		||||
                    switch ($this->get['action']){
 | 
			
		||||
                    switch ($this->get[self::ACTION]){
 | 
			
		||||
                        case 'store':
 | 
			
		||||
                            return $orderController->store();
 | 
			
		||||
                        case 'basket':
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<?php
 | 
			
		||||
namespace router;
 | 
			
		||||
namespace router\link;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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" %}
 | 
			
		||||
{% block body %}
 | 
			
		||||
{% include 'frames/structure/navbar.html.twig' with menu_items %}
 | 
			
		||||
<div class="container">
 | 
			
		||||
	<div class="page-header">
 | 
			
		||||
		<h1>Online Shop</h1>
 | 
			
		||||
		<hr />
 | 
			
		||||
	</div>
 | 
			
		||||
	{% block content %}
 | 
			
		||||
	{% endblock %}
 | 
			
		||||
</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>
 | 
			
		||||
			<ul>
 | 
			
		||||
				<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>
 | 
			
		||||
			</span>
 | 
			
		||||
			<a href="#" class="btn btn-primary">Add to basket</a>
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
<h2>Welcome to the online shop!</h2>
 | 
			
		||||
You have the following options:
 | 
			
		||||
<ul>
 | 
			
		||||
{% for option in options %}
 | 
			
		||||
{% for option in menu_items %}
 | 
			
		||||
  <li>
 | 
			
		||||
    <a href="{{option.getUrl}}">{{option.getName}}</a>
 | 
			
		||||
  </li>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user