Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
11 changes: 9 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": [],
Expand All @@ -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"
}
}
9 changes: 9 additions & 0 deletions config/autoload/docker.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,18 @@
/**
* Docker Environment Configuration
*/
use Zend\ServiceManager\Factory;

return [
'view_manager' => [
'display_exceptions' => true,
],
'service_manager' => [
'factories' => [
'stdClass' => InvokableFactory::class
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an example? I'm not seeing this used anywhere in your code.

],
'aliases' => [
'entityManager' => 'stdClass',
]
],
];
24 changes: 24 additions & 0 deletions config/autoload/doctrine.docker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
return [
'doctrine' => [
'configuration' => [
'orm_default' => [
'proxy_dir' => __DIR__.'/../../data/DoctrineORMModule/Proxy',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not mandatory to set this (system temporary directories are used by default, which have the correct permissions) and in our Docker environment we want to keep things simple.

'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',
],
],
],
],
];
29 changes: 29 additions & 0 deletions config/autoload/doctrine.global.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php
/**
* Doctrine Global Config
*/

return [
'doctrine' => [
'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',
] ,
],
],
],
];
8 changes: 6 additions & 2 deletions config/modules.config.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
<?php

/**
* List of enabled modules for this application.
* List of enabled modules for this product.
*
* This should be an array of module namespaces used in the application.
* This should be an array of module namespaces used in the product.
*/
return [
'Zend\Router',
'Zend\Validator',
'DoctrineModule',
'DoctrineORMModule',
'Application',
'Category',
'Product',
];
1 change: 1 addition & 0 deletions deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
chmod -Rf 777 data/DoctrineORMModule/Proxy
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ services:
volumes:
- .db:/var/lib/mysql
ports:
- "3306:3306"
- "3307:3306"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than committing this change, you can stop your local mysql service running while you're using Docker for this project.

100 changes: 100 additions & 0 deletions module/Category/config/module.config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

namespace Category;

use Doctrine\ORM\EntityManager;
use DoctrineORMModule\Service\EntityManagerAliasCompatFactory;
use DoctrineORMModule\Service\EntityManagerFactory;
use Zend\Router\Http\Literal;
use Zend\Router\Http\Segment;
use Zend\ServiceManager\Factory\InvokableFactory;

return [
'service_manager' =>[
'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,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to duplicate keys here that we already have declared in the Application module. The keys from config of each module get merged together (they're not kept separately for each module). This applies to most of the keys in this view_manager config - you should remove them all, apart from the ones which are specific to the Category module, such as the 3 template_map files and the template_path_stack (which is specific to the Category module as it uses DIR to refer to the Category module directory).

'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => [
'layout/layout' => __DIR__ . '/../../../view/layout/layout.phtml',
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All templates should be in view directories inside a module directory.

The layout.phtml template (and other site-wide templates, like error templates) should be in the Application module, while module-specific templates should be in the view directory of that module.

'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',
],
],
];
75 changes: 75 additions & 0 deletions module/Category/src/Controller/CategoryController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace Category\Controller;

use Category\Model\Category;
use Doctrine\ORM\EntityManager;
use Product\model\Product as ProductModel;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Category\Model\Category as CategoryModel;
class CategoryController extends AbstractActionController
{
/**
* Entity manager.
* @var Doctrine\ORM\EntityManager
*/
private $entityManager;

public function __construct($serviceManager)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than injecting the $serviceManager, you should inject directly the services you need - in this case $entityManager, although really you should inject own service (CategoryModel) in this module and inject that (with $entityManager injected into that service, instead of into this controller).

Injecting the $serviceManager is considered to be an anti-pattern.

{
$this->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");
}
}
45 changes: 45 additions & 0 deletions module/Category/src/Controller/CategoryControllerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* Created by PhpStorm.
* User: camelcase
* Date: 7/4/18
* Time: 12:43 PM
*/

namespace Category\Controller;


use Interop\Container\ContainerInterface;
use Interop\Container\Exception\ContainerException;
use Zend\ServiceManager\Exception\ServiceNotCreatedException;
use Zend\ServiceManager\Exception\ServiceNotFoundException;
use Zend\ServiceManager\Factory\FactoryInterface;

class CategoryControllerFactory implements FactoryInterface
{

/**
* Create an object
*
* @param ContainerInterface $container
* @param string $requestedName
* @param null|array $options
* @return object
* @throws ServiceNotFoundException if unable to resolve the service.
* @throws ServiceNotCreatedException if an exception is raised when
* creating a service.
* @throws ContainerException if any other error occurs
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{


// $entityManager = $container->get('doctrine.entitymanager.orm_default');
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (commented) line shows the right idea. We should inject specific services (e.g. the ORM) rather than the $serviceManager.

// 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);

}
}
Loading