diff --git a/Dockerfile b/Dockerfile index fae3669..82860ec 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,6 +3,7 @@ FROM php:7.0-apache RUN apt-get update \ && apt-get install -y git zlib1g-dev \ && docker-php-ext-install zip \ + && docker-php-ext-install pdo_mysql \ && a2enmod rewrite \ && sed -i 's!/var/www/html!/var/www/public!g' /etc/apache2/sites-available/000-default.conf \ && mv /var/www/html /var/www/public \ diff --git a/README.md b/README.md index fceb16f..c265cc0 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,5 @@ images it requires. For subsequent runs, the start up time should be much faster 3. View the test page: http://localhost:8080/ + +4. Dummy Chnage diff --git a/composer.json b/composer.json index a65fe86..f4b01f7 100644 --- a/composer.json +++ b/composer.json @@ -10,12 +10,16 @@ }, "autoload": { "psr-4": { - "Application\\": "module/Application/src/" + "Application\\": "module/Application/src/", + "Category\\": "module/Category/src/", + "Product\\": "module/Product/src/" } }, "autoload-dev": { "psr-4": { - "ApplicationTest\\": "module/Application/test/" + "ApplicationTest\\": "module/Application/test/", + "CategoryTest\\":"module/Category/test/", + "ProductTest\\":"module/Product/test/" } }, "extra": [], @@ -28,5 +32,8 @@ "phpunit/phpunit": "^6.5", "zendframework/zend-test": "^3.2", "squizlabs/php_codesniffer": "^3.3" + }, + "require": { + "doctrine/doctrine-orm-module": "^1.1" } } diff --git a/config/autoload/docker.php b/config/autoload/docker.php index 2909593..c52c3be 100644 --- a/config/autoload/docker.php +++ b/config/autoload/docker.php @@ -2,9 +2,18 @@ /** * Docker Environment Configuration */ +use Zend\ServiceManager\Factory; return [ 'view_manager' => [ 'display_exceptions' => true, ], + 'service_manager' => [ + 'factories' => [ + 'stdClass' => InvokableFactory::class + ], + 'aliases' => [ + 'entityManager' => 'stdClass', + ] + ], ]; diff --git a/config/autoload/doctrine.docker.php b/config/autoload/doctrine.docker.php new file mode 100644 index 0000000..1fd9dcb --- /dev/null +++ b/config/autoload/doctrine.docker.php @@ -0,0 +1,24 @@ + [ + 'configuration' => [ + 'orm_default' => [ + 'proxy_dir' => __DIR__.'/../../data/DoctrineORMModule/Proxy', + 'proxy_namespace' => 'DoctrineORMModule\Proxy', + ] + ], + 'connection' => [ + // default connection name + 'orm_default' => [ + 'driverClass' => \Doctrine\DBAL\Driver\PDOMySql\Driver::class, + 'params' => [ + 'host' => 'db', + 'port' => '3306', + 'user' => 'app', + 'password' => 'app', + 'dbname' => 'app', + ], + ], + ], +], +]; \ No newline at end of file diff --git a/config/autoload/doctrine.global.php b/config/autoload/doctrine.global.php new file mode 100644 index 0000000..331cb28 --- /dev/null +++ b/config/autoload/doctrine.global.php @@ -0,0 +1,29 @@ + [ + 'driver' => [ + // defines an annotation driver, named `annotation_driver` + 'annotation_driver' => [ + 'class' => \Doctrine\ORM\Mapping\Driver\AnnotationDriver::class, + 'cache' => 'array', + 'paths' => [ + realpath(__DIR__ . '/../../module/Category/src/Entity'), + realpath(__DIR__ . '/../../module/Product/src/Entity'), + ], + ], + // default metadata driver, aggregates all other drivers into a single one. + // Override `orm_default` only if you know what you're doing + 'orm_default' => [ + 'drivers' => [ + // register `annotation_driver` for any entity under namespace `\Entity` + 'Category\Entity' => 'annotation_driver', + 'Product\Entity' => 'annotation_driver', + ] , + ], + ], +], +]; \ No newline at end of file diff --git a/config/modules.config.php b/config/modules.config.php index 81b5749..e6eed7b 100644 --- a/config/modules.config.php +++ b/config/modules.config.php @@ -1,12 +1,16 @@ [ + 'aliases' => array( + 'category' => 'Category\Controller\CategoryController', + ), + 'factories' => array( + + ), + ], + 'router' => [ + 'routes' => [ + 'categories' => [ + 'type' => Segment::class, + 'options' => [ + 'route' => '/categories', + 'defaults' => [ + 'controller' => Controller\CategoryController::class, + 'action' => 'index', + ], + ], + ], + 'createCategories' => [ + 'type' => Segment::class, + 'options' => [ + 'route' => '/categories/new', + 'defaults' => [ + 'controller' => Controller\CategoryController::class, + 'action' => 'new', + ], + ], + ], + 'editCategories' => [ + 'type' => Segment::class, + 'options' => [ + 'route' => '/categories/edit/[:id]', + 'defaults' => [ + 'controller' => Controller\CategoryController::class, + 'action' => 'edit', + ], + ], + ], + 'showCategory' => [ + 'type' => Segment::class, + 'options' => [ + 'route' => '/categories/show/[:id]', + 'defaults' => [ + 'controller' => Controller\CategoryController::class, + 'action' => 'show', + ], + ], + ], + 'deleteCategory' => [ + 'type' => Segment::class, + 'options' => [ + 'route' => '/categories/delete/[:id]', + 'defaults' => [ + 'controller' => Controller\CategoryController::class, + 'action' => 'delete', + ], + ], + ], + ], + ], + 'controllers' => [ + 'factories' => [ + Controller\CategoryController::class => Controller\CategoryControllerFactory::class, + ], + ], + 'view_manager' => [ + 'display_not_found_reason' => true, + 'display_exceptions' => true, + 'doctype' => 'HTML5', + 'not_found_template' => 'error/404', + 'exception_template' => 'error/index', + 'template_map' => [ + 'layout/layout' => __DIR__ . '/../../../view/layout/layout.phtml', + 'category/category/index' => __DIR__ . '/../../../view/category/index/index.phtml', + 'category/category/new' => __DIR__ . '/../../../view/category/index/new.phtml', + 'category/category/edit' => __DIR__ . '/../../../view/category/index/edit.phtml', + 'category/category/show' => __DIR__ . '/../../../view/category/index/show.phtml', + 'category/category/delete' => __DIR__ . '/../../../view/category/index/delete.phtml', + 'error/404' => __DIR__ . '/../../../view/error/404.phtml', + 'error/index' => __DIR__ . '/../../../view/error/index.phtml', + ], + 'template_path_stack' => [ + __DIR__ . '/../view', + ], + ], +]; diff --git a/module/Category/src/Controller/CategoryController.php b/module/Category/src/Controller/CategoryController.php new file mode 100644 index 0000000..3393859 --- /dev/null +++ b/module/Category/src/Controller/CategoryController.php @@ -0,0 +1,75 @@ +entityManager = $serviceManager->get(EntityManager::class); + } + + public function indexAction() + { + $categoryModel = new CategoryModel($this->entityManager); + $categories = $categoryModel->getCategories(); + return new ViewModel(["categories"=>$categories]); + } + + public function newAction() + { + if ($this->getRequest()->isPost()){ + $data = $this->params()->fromPost(); + $categoryModel = new CategoryModel($this->entityManager); + $categoryModel->createCategory($data["name"], $data["description"]); + $this->redirect()->toUrl("/categories"); + } + + return new ViewModel(); + } + public function editAction() + { + $id = $this->params("id"); + $categoryModel = new CategoryModel($this->entityManager); + $categoryEntity = $categoryModel->getCategory($id); + if ($this->getRequest()->isPost()) { + $data = $this->params()->fromPost(); + $categoryModel->editCategory($id, $data["name"], $data["description"]); + $this->redirect()->toUrl("/categories"); + } + return new ViewModel(["category"=>$categoryEntity]); + } + public function showAction() + { + $id = $this->params("id"); + + $categoryModel = new CategoryModel($this->entityManager); + $productModel = new ProductModel($this->entityManager); + + $categoryEntity = $categoryModel->getCategory($id); + $productEntities = $productModel->getProductsByCategory($id); + + return new ViewModel(["category"=>$categoryEntity, "products"=>$productEntities]); + } + public function deleteAction() + { + $id = $this->params("id"); + + $categoryModel = new CategoryModel($this->entityManager); + $categoryEntity = $categoryModel->deleteCategory($id); + + $this->redirect()->toUrl("/categories"); + } +} diff --git a/module/Category/src/Controller/CategoryControllerFactory.php b/module/Category/src/Controller/CategoryControllerFactory.php new file mode 100644 index 0000000..1236cb3 --- /dev/null +++ b/module/Category/src/Controller/CategoryControllerFactory.php @@ -0,0 +1,45 @@ +get('doctrine.entitymanager.orm_default'); +// var_dump(get_class($entityManager));exit; + // Instantiate the controller and inject dependencies + return new CategoryController($container); +// $service = (null === $options) ? new $requestedName : new $requestedName($options); +// return $service->setServiceManager($container); + + } +} \ No newline at end of file diff --git a/module/Category/src/Entity/Category.php b/module/Category/src/Entity/Category.php new file mode 100644 index 0000000..698172e --- /dev/null +++ b/module/Category/src/Entity/Category.php @@ -0,0 +1,100 @@ +name = $name; + } + + /** + * @param string $description + */ + public function setDescription(string $description) + { + $this->description = $description; + } + + /** + * @param int $id + */ + public function setId(int $id) + { + $this->id = $id; + } + + /** + * @param mixed $products + */ + public function setProducts($products) + { + $this->products = $products; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @return string + */ + public function getDescription(): string + { + return $this->description; + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return mixed + */ + public function getProducts() + { + return $this->products; + } +} \ No newline at end of file diff --git a/module/Category/src/Model/Category.php b/module/Category/src/Model/Category.php new file mode 100644 index 0000000..eeecf70 --- /dev/null +++ b/module/Category/src/Model/Category.php @@ -0,0 +1,58 @@ +entityManager = $entityManager; + } + + public function createCategory($name, $description) + { + $categoryEntity = new CategoryEntity(); + $categoryEntity->setName($name); + $categoryEntity->setDescription($description); + + $this->entityManager->persist($categoryEntity); + $this->entityManager->flush($categoryEntity); + } + + public function editCategory($id, $name, $description) + { + $categoryEntity = new CategoryEntity(); + $categoryEntity->setId($id); + $categoryEntity->setName($name); + $categoryEntity->setDescription($description); + $this->entityManager->merge($categoryEntity); + $this->entityManager->flush(); + } + + public function getCategories() + { + return $this->entityManager->getRepository(CategoryEntity::class)->findAll(); + } + + public function getCategory($id) + { + return $this->entityManager->find(CategoryEntity::class, $id); + } + + public function deleteCategory($id) + { + $categoryEntity = $this->entityManager->find(CategoryEntity::class, $id); + $this->entityManager->remove($categoryEntity); + $this->entityManager->flush(); + } +} \ No newline at end of file diff --git a/module/Category/src/Module.php b/module/Category/src/Module.php new file mode 100644 index 0000000..a57301f --- /dev/null +++ b/module/Category/src/Module.php @@ -0,0 +1,11 @@ +setApplicationConfig(ArrayUtils::merge( + include __DIR__ . '/../../../../config/application.config.php', + $configOverrides + )); + + parent::setUp(); + } + + public function testIndexActionCanBeAccessed() + { + $this->dispatch('/', 'GET'); + $this->assertResponseStatusCode(200); + $this->assertModuleName('product'); + $this->assertControllerName(ProductController::class); // as specified in router's controller name alias + $this->assertControllerClass('ProductController'); + $this->assertMatchedRouteName('home'); + } + + public function testIndexActionViewModelTemplateRenderedWithinLayout() + { + $this->dispatch('/', 'GET'); + $this->assertQuery('.container .jumbotron'); + } + + public function testInvalidRouteDoesNotCrash() + { + $this->dispatch('/invalid/route', 'GET'); + $this->assertResponseStatusCode(404); + } +} diff --git a/module/Product/config/module.config.php b/module/Product/config/module.config.php new file mode 100644 index 0000000..6e059fb --- /dev/null +++ b/module/Product/config/module.config.php @@ -0,0 +1,90 @@ + [ + 'routes' => [ + 'products' => [ + 'type' => Segment::class, + 'options' => [ + 'route' => '/products', + 'defaults' => [ + 'controller' => Controller\ProductController::class, + 'action' => 'index', + ], + ], + ], + 'createProducts' => [ + 'type' => Segment::class, + 'options' => [ + 'route' => '/products/new', + 'defaults' => [ + 'controller' => Controller\ProductController::class, + 'action' => 'new', + ], + ], + ], + 'editProducts' => [ + 'type' => Segment::class, + 'options' => [ + 'route' => '/products/edit/[:id]', + 'defaults' => [ + 'controller' => Controller\ProductController::class, + 'action' => 'edit', + ], + ], + ], + 'showProduct' => [ + 'type' => Segment::class, + 'options' => [ + 'route' => '/products/show/[:id]', + 'defaults' => [ + 'controller' => Controller\ProductController::class, + 'action' => 'show', + ], + ], + ], + 'deleteProduct' => [ + 'type' => Segment::class, + 'options' => [ + 'route' => '/products/delete/[:id]', + 'defaults' => [ + 'controller' => Controller\ProductController::class, + 'action' => 'delete', + ], + ], + ], + ], + ], + 'controllers' => [ + 'factories' => [ + Controller\ProductController::class => Controller\ProductControllerFactory::class, + ], + ], + 'view_manager' => [ + 'display_not_found_reason' => true, + 'display_exceptions' => true, + 'doctype' => 'HTML5', + 'not_found_template' => 'error/404', + 'exception_template' => 'error/index', + 'template_map' => [ + 'layout/layout' => __DIR__ . '/../../../view/layout/layout.phtml', + 'product/product/index' => __DIR__ . '/../../../view/product/index/index.phtml', + 'product/product/new' => __DIR__ . '/../../../view/product/index/new.phtml', + 'product/product/edit' => __DIR__ . '/../../../view/product/index/edit.phtml', + 'product/product/show' => __DIR__ . '/../../../view/product/index/show.phtml', + 'product/product/delete' => __DIR__ . '/../../../view/product/index/delete.phtml', + 'error/404' => __DIR__ . '/../../../view/error/404.phtml', + 'error/index' => __DIR__ . '/../../../view/error/index.phtml', + ], + 'template_path_stack' => [ + __DIR__ . '/../view', + ], + ], +]; diff --git a/module/Product/src/Controller/ProductController.php b/module/Product/src/Controller/ProductController.php new file mode 100644 index 0000000..82c9a07 --- /dev/null +++ b/module/Product/src/Controller/ProductController.php @@ -0,0 +1,73 @@ +entityManager = $serviceManager->get(EntityManager::class); + } + public function indexAction() + { + $productModel = new ProductModel($this->entityManager); + $products = $productModel->getProducts(); + return new ViewModel(["products"=>$products]); + } + + public function newAction() + { + if ($this->getRequest()->isPost()){ + $data = $this->params()->fromPost(); + $productModel = new ProductModel($this->entityManager); + $productModel->createProduct($data["name"], $data["description"], $data["price"], $data["category"]); + $this->redirect()->toUrl("/products"); + } + $categoryModel = new CategoryModel($this->entityManager); + return new ViewModel(["categories" => $categoryModel->getCategories()]); + } + public function editAction() + { + $id = $this->params("id"); + $productModel = new ProductModel($this->entityManager); + $productEntity = $productModel->getProduct($id); + if ($this->getRequest()->isPost()) { + $data = $this->params()->fromPost(); + $productModel->editProduct($id, $data["name"], $data["description"], $data["price"], $data["category"]); + $this->redirect()->toUrl("/products"); + } + $categoryModel = new CategoryModel($this->entityManager); + return new ViewModel([ + "product"=>$productEntity, + "categories" => $categoryModel->getCategories()]); + } + public function showAction() + { + $id = $this->params("id"); + + $productModel = new ProductModel($this->entityManager); + $productEntity = $productModel->getProduct($id); + + return new ViewModel(["product"=>$productEntity]); + } + public function deleteAction() + { + $id = $this->params("id"); + + $productModel = new ProductModel($this->entityManager); + $productEntity = $productModel->deleteProduct($id); + + $this->redirect()->toUrl("/products"); + } +} diff --git a/module/Product/src/Controller/ProductControllerFactory.php b/module/Product/src/Controller/ProductControllerFactory.php new file mode 100644 index 0000000..3e5b6b9 --- /dev/null +++ b/module/Product/src/Controller/ProductControllerFactory.php @@ -0,0 +1,40 @@ +get('doctrine.entitymanager.orm_default'); +// var_dump(get_class($entityManager));exit; + // Instantiate the controller and inject dependencies + return new ProductController($container); +// $service = (null === $options) ? new $requestedName : new $requestedName($options); +// return $service->setServiceManager($container); + + } +} \ No newline at end of file diff --git a/module/Product/src/Entity/Product.php b/module/Product/src/Entity/Product.php new file mode 100644 index 0000000..065149f --- /dev/null +++ b/module/Product/src/Entity/Product.php @@ -0,0 +1,122 @@ +name = $name; + } + + /** + * @param string $description + */ + public function setDescription(string $description) + { + $this->description = $description; + } + + /** + * @param float $price + */ + public function setPrice(float $price) + { + $this->price = $price; + } + + /** + * @param int $id + */ + public function setId(int $id) + { + $this->id = $id; + } + + /** + * @param mixed $category + */ + public function setCategory($category) + { + $this->category = $category; + } + + /** + * @return string + */ + public function getName(): string + { + return $this->name; + } + + /** + * @return string + */ + public function getDescription(): string + { + return $this->description; + } + + /** + * @return float + */ + public function getPrice(): float + { + return $this->price; + } + + /** + * @return int + */ + public function getId(): int + { + return $this->id; + } + + /** + * @return mixed + */ + public function getCategory() + { + return $this->category; + } +} \ No newline at end of file diff --git a/module/Product/src/Module.php b/module/Product/src/Module.php new file mode 100644 index 0000000..e9bbc43 --- /dev/null +++ b/module/Product/src/Module.php @@ -0,0 +1,11 @@ +entityManager = $entityManager; + } + + public function createProduct($name, $description, $price, $categoryId) + { + $category = $this->entityManager->find(CategoryEntity::class, $categoryId); + $productEntity = new ProductEntity(); + $productEntity->setName($name); + $productEntity->setPrice($price); + $productEntity->setDescription($description); + $productEntity->setCategory($category); + $this->entityManager->persist($productEntity); + $this->entityManager->flush($productEntity); + } + + public function editProduct($id, $name, $description, $price, $categoryId) + { + $category = $this->entityManager->find(CategoryEntity::class, $categoryId); + $productEntity = new ProductEntity(); + $productEntity->setId($id); + $productEntity->setName($name); + $productEntity->setPrice($price); + $productEntity->setDescription($description); + $productEntity->setCategory($category); + $this->entityManager->merge($productEntity); + $this->entityManager->flush(); + } + + public function getProducts() + { + $categories = $this->entityManager->getRepository(ProductEntity::class)->findAll(); + return $categories; + } + + public function getProduct($id) + { + return $this->entityManager->find(ProductEntity::class, $id); + } + + public function getProductsByCategory($id) + { + return $this->entityManager->getRepository(ProductEntity::class)->findBy(["category" => $id]); + } + + public function deleteProduct($id) + { + $productEntity = $this->entityManager->find(ProductEntity::class, $id); + $this->entityManager->remove($productEntity); + $this->entityManager->flush(); + } +} \ No newline at end of file diff --git a/module/Product/test/Controller/ProductControllerTest.php b/module/Product/test/Controller/ProductControllerTest.php new file mode 100644 index 0000000..a811574 --- /dev/null +++ b/module/Product/test/Controller/ProductControllerTest.php @@ -0,0 +1,48 @@ +setApplicationConfig(ArrayUtils::merge( + include __DIR__ . '/../../../../config/application.config.php', + $configOverrides + )); + + parent::setUp(); + } + + public function testIndexActionCanBeAccessed() + { + $this->dispatch('/', 'GET'); + $this->assertResponseStatusCode(200); + $this->assertModuleName('product'); + $this->assertControllerName(ProductController::class); // as specified in router's controller name alias + $this->assertControllerClass('ProductController'); + $this->assertMatchedRouteName('home'); + } + + public function testIndexActionViewModelTemplateRenderedWithinLayout() + { + $this->dispatch('/', 'GET'); + $this->assertQuery('.container .jumbotron'); + } + + public function testInvalidRouteDoesNotCrash() + { + $this->dispatch('/invalid/route', 'GET'); + $this->assertResponseStatusCode(404); + } +} diff --git a/view/category/index/edit.phtml b/view/category/index/edit.phtml new file mode 100644 index 0000000..2d6f35c --- /dev/null +++ b/view/category/index/edit.phtml @@ -0,0 +1,20 @@ +
+

Edit Category

+
+
+
+
+ + +
+ +
+ + +
+ +
+ +
+
+
diff --git a/view/category/index/index.phtml b/view/category/index/index.phtml new file mode 100644 index 0000000..e641646 --- /dev/null +++ b/view/category/index/index.phtml @@ -0,0 +1,35 @@ +
+

Categories

+
+
+ Create New Category +
+
+ + + + + + + + + + "; + echo ""; + echo ""; + echo ""; + echo ""; + } + ?> + +
NameDescriptionAction
".$category->getName()."".$category->getDescription()." show "; + echo " edit "; + echo " delete ". + "
+
\ No newline at end of file diff --git a/view/category/index/new.phtml b/view/category/index/new.phtml new file mode 100644 index 0000000..bd7a1b1 --- /dev/null +++ b/view/category/index/new.phtml @@ -0,0 +1,20 @@ +
+

Create New Category

+
+
+
+
+ + +
+ +
+ + +
+ +
+ +
+
+
diff --git a/view/category/index/show.phtml b/view/category/index/show.phtml new file mode 100644 index 0000000..9a6f001 --- /dev/null +++ b/view/category/index/show.phtml @@ -0,0 +1,39 @@ +
+

getName(); ?> Category

+
+
+
getDescription(); ?>
+ Edit this Category +

Our Products

+ + + + + + + + + + + + "; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + ?> + +
NamePriceDescriptionCategoryAction
".$product->getName()."".$product->getPrice()."".$product->getDescription()."".$product->getCategory()->getName()." show "; + echo " edit "; + echo " Remove from Category ". + "
+
diff --git a/view/error/404.phtml b/view/error/404.phtml new file mode 100644 index 0000000..1b4ebca --- /dev/null +++ b/view/error/404.phtml @@ -0,0 +1,105 @@ + +

A 404 error occurred

+

message ?>

+ +reason)) : + switch ($this->reason) { + case Application::ERROR_CONTROLLER_CANNOT_DISPATCH: + $reasonMessage = 'The requested controller was unable to dispatch the request.'; + break; + case Application::ERROR_MIDDLEWARE_CANNOT_DISPATCH: + $reasonMessage = 'The requested middleware was unable to dispatch the request.'; + break; + case Application::ERROR_CONTROLLER_NOT_FOUND: + $reasonMessage = 'The requested controller could not be mapped to an existing controller class.'; + break; + case Application::ERROR_CONTROLLER_INVALID: + $reasonMessage = 'The requested controller was not dispatchable.'; + break; + case Application::ERROR_ROUTER_NO_MATCH: + $reasonMessage = 'The requested URL could not be matched by routing.'; + break; + default: + $reasonMessage = 'We cannot determine at this time why a 404 was generated.'; + break; + } + ?> +

+ + +controller)) : ?> +
+
Controller:
+
+ escapeHtml($this->controller) ?> + controller_class) && $this->controller_class != $this->controller) { + printf('(resolves to %s)', $this->escapeHtml($this->controller_class)); + } + ?> +
+
+ + +display_exceptions)) : ?> + exception) + && ($this->exception instanceof \Exception || $this->exception instanceof \Error)) : ?> +
+ +

Additional information:

+

exception) ?>

+
+
File:
+
+
exception->getFile() ?>:exception->getLine() ?>
+
+
Message:
+
+
escapeHtml($this->exception->getMessage()) ?>
+
+
Stack trace:
+
+
escapeHtml($this->exception->getTraceAsString()) ?>
+
+
+ + exception->getPrevious()) : ?> +
+ +

Previous exceptions:

+ + + +

No Exception available

+ + diff --git a/view/error/index.phtml b/view/error/index.phtml new file mode 100644 index 0000000..1b28a21 --- /dev/null +++ b/view/error/index.phtml @@ -0,0 +1,63 @@ +

An error occurred

+

message ?>

+ +display_exceptions)) : ?> + exception) + && ($this->exception instanceof \Exception || $this->exception instanceof \Error)) : ?> +
+ +

Additional information:

+

exception) ?>

+
+
File:
+
+
exception->getFile() ?>:exception->getLine() ?>
+
+
Message:
+
+
escapeHtml($this->exception->getMessage()) ?>
+
+
Stack trace:
+
+
escapeHtml($this->exception->getTraceAsString()) ?>
+
+
+ + exception->getPrevious()) : ?> +
+ +

Previous exceptions:

+ + + +

No Exception available

+ + diff --git a/view/layout/layout.phtml b/view/layout/layout.phtml new file mode 100644 index 0000000..db661c8 --- /dev/null +++ b/view/layout/layout.phtml @@ -0,0 +1,54 @@ +doctype() ?> + + + + headTitle('Category')->setSeparator(' - ')->setAutoEscape(false) ?> + + headMeta() + ->appendName('viewport', 'width=device-width, initial-scale=1.0') + ->appendHttpEquiv('X-UA-Compatible', 'IE=edge') + ?> + + + headLink(['rel' => 'shortcut icon', 'type' => 'image/vnd.microsoft.icon', 'href' => $this->basePath() . '/img/favicon.ico']) + ->prependStylesheet($this->basePath('css/style.css')) + ->prependStylesheet($this->basePath('css/bootstrap-theme.min.css')) + ->prependStylesheet($this->basePath('css/bootstrap.min.css')) + ?> + + + headScript() + ->prependFile($this->basePath('js/bootstrap.min.js')) + ->prependFile($this->basePath('js/jquery-3.1.0.min.js')) + ?> + + + +
+ content ?> +
+ inlineScript() ?> + + diff --git a/view/product/index/edit.phtml b/view/product/index/edit.phtml new file mode 100644 index 0000000..313f193 --- /dev/null +++ b/view/product/index/edit.phtml @@ -0,0 +1,40 @@ +
+

Edit Product

+
+
+
+
+ + +
+ +
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
diff --git a/view/product/index/index.phtml b/view/product/index/index.phtml new file mode 100644 index 0000000..15c4aae --- /dev/null +++ b/view/product/index/index.phtml @@ -0,0 +1,39 @@ +
+

Products

+
+
+ Create New Product +
+
+ + + + + + + + + + + + "; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + } + ?> + +
NamePriceDescriptionCategoryAction
".$product->getName()."".$product->getPrice()."".$product->getDescription()."".$product->getCategory()->getName()." show "; + echo " edit "; + echo " delete ". + "
+
\ No newline at end of file diff --git a/view/product/index/new.phtml b/view/product/index/new.phtml new file mode 100644 index 0000000..93da7e2 --- /dev/null +++ b/view/product/index/new.phtml @@ -0,0 +1,33 @@ +
+

Create New Product

+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
diff --git a/view/product/index/show.phtml b/view/product/index/show.phtml new file mode 100644 index 0000000..69a553e --- /dev/null +++ b/view/product/index/show.phtml @@ -0,0 +1,9 @@ +
+

getName(); ?>

+
+
+
Price: getPrice(); ?>
+
Category: getCategory()->getName();?>
+
Description: getDescription(); ?>
+ Edit this Product +