Skip to content

Commit 54e1dfa

Browse files
author
Codeliner
committed
Add booking function
1 parent ca88ade commit 54e1dfa

File tree

32 files changed

+831
-60
lines changed

32 files changed

+831
-60
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!.gitignore

module/Application/config/module.config.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,14 @@
7777
),
7878
),
7979
'service_manager' => array(
80+
'invokables' => array(
81+
'overbooking_policy' => 'Application\Service\Policy\TenPercentOverbookingPolicy',
82+
),
8083
'factories' => array(
8184
'main_navigation' => 'Zend\Navigation\Service\DefaultNavigationFactory',
8285
'cargo_form' => 'Application\Form\Service\CargoFormFactory',
8386
'voyage_form' => 'Application\Form\Service\VoyageFormFactory',
87+
'booking_service' => 'Application\Service\Factory\BookingServiceFactory',
8488
'cargo_repository' => function($sl) {
8589
$em = $sl->get('doctrine.entitymanager.orm_default');
8690
return $em->getRepository('Application\Domain\Model\Cargo\Cargo');
@@ -120,6 +124,7 @@
120124

121125
$cargoController = new Application\Controller\CargoController();
122126
$cargoController->setCargoRepository($cargoRepository);
127+
$cargoController->setVoyageRepository($serviceManager->get('voyage_repository'));
123128
$cargoController->setCargoForm($serviceManager->get('cargo_form'));
124129
return $cargoController;
125130
},
@@ -130,6 +135,15 @@
130135
$voyageController->setVoyageForm($serviceManager->get('voyage_form'));
131136
$voyageController->setVoyageRepository($serviceManager->get('voyage_repository'));
132137
return $voyageController;
138+
},
139+
'Application\Controller\Booking' => function($controllerLoader) {
140+
$serviceManager = $controllerLoader->getServiceLocator();
141+
142+
$bookingController = new Application\Controller\BookingController();
143+
$bookingController->setCargoRepository($serviceManager->get('cargo_repository'));
144+
$bookingController->setVoyageRepository($serviceManager->get('voyage_repository'));
145+
$bookingController->setBookingService($serviceManager->get('booking_service'));
146+
return $bookingController;
133147
}
134148
)
135149
),
@@ -154,7 +168,6 @@
154168
'orm_default' => array(
155169
//Define custom doctrine types to map the ddd value objects
156170
'types' => array(
157-
'uid' => 'Application\Infrastructure\Persistence\Doctrine\Type\UID',
158171
'trackingid' => 'Application\Infrastructure\Persistence\Doctrine\Type\TrackingId',
159172
'voyagenumber' => 'Application\Infrastructure\Persistence\Doctrine\Type\VoyageNumber',
160173
),
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
<?php
2+
/*
3+
* This file is part of the codeliner/php-ddd-cargo-sample package.
4+
* (c) Alexander Miertsch <[email protected]>
5+
*
6+
* For the full copyright and license information, please view the LICENSE
7+
* file that was distributed with this source code.
8+
*/
9+
namespace Application\Controller;
10+
11+
use Zend\Mvc\Controller\AbstractActionController;
12+
use Zend\View\Model\ViewModel;
13+
use Zend\Validator\StringLength;
14+
use Zend\Validator\Regex;
15+
use Application\Domain\Model\Cargo;
16+
use Application\Domain\Model\Voyage;
17+
use Application\Service\BookingService;
18+
use Application\Service\Exception\ServiceException;
19+
use Application\Service\Exception\RuntimeException;
20+
/**
21+
* MVC Controller that manages the booking process of Voyage.
22+
*
23+
* @author Alexander Miertsch <[email protected]>
24+
*/
25+
class BookingController extends AbstractActionController
26+
{
27+
/**
28+
* The CargoRepository
29+
*
30+
* @var Cargo\CargoRepositoryInterface
31+
*/
32+
protected $cargoRepository;
33+
34+
/**
35+
*
36+
* @var Voyage\VoyageRepositoryInterface
37+
*/
38+
protected $voyageRepository;
39+
40+
/**
41+
*
42+
* @var BookingService
43+
*/
44+
protected $bookingService;
45+
46+
/**
47+
* Book a Cargo on a Voyage
48+
*/
49+
public function bookingAction()
50+
{
51+
//we use the post redirect get pattern and redirect to same location
52+
$prg = $this->prg();
53+
54+
if ($prg instanceof \Zend\Http\PhpEnvironment\Response) {
55+
// returned a response to redirect us
56+
return $prg;
57+
} elseif ($prg === false) {
58+
throw new RuntimeException('Request is out of date.');
59+
}
60+
61+
try {
62+
$trackingId = $prg['tracking_id'];
63+
64+
if (empty($trackingId)) {
65+
throw new RuntimeException('TrackingId must not be empty');
66+
}
67+
68+
$strLengthVal = new StringLength(1, 13);
69+
$regexVal = new Regex('/^[a-zA-Z0-9_-]+$/');
70+
71+
if (!$strLengthVal->isValid($trackingId) || !$regexVal->isValid($trackingId)) {
72+
throw new RuntimeException('TrackingId is invalid');
73+
}
74+
75+
$voyageNumber = $prg['voyage_number'];
76+
77+
if (empty($voyageNumber)) {
78+
throw new RuntimeException('VoyageNumber must not be empty');
79+
}
80+
81+
$strLengthVal = new StringLength(3, 30);
82+
$regexVal = new Regex('/^[a-zA-Z0-9_-]+$/');
83+
84+
if (!$strLengthVal->isValid($voyageNumber) || !$regexVal->isValid($voyageNumber)) {
85+
throw new RuntimeException('VoyageNumber is invalid');
86+
}
87+
88+
$cargo = $this->cargoRepository->findCargo(new Cargo\TrackingId($trackingId));
89+
90+
if (is_null($cargo)) {
91+
throw new RuntimeException('Cargo can not be found');
92+
}
93+
94+
$voyage = $this->voyageRepository->findVoyage(new Voyage\VoyageNumber($voyageNumber));
95+
96+
if (is_null($voyage)) {
97+
throw new RuntimeException('Voyage can not be found');
98+
}
99+
100+
$this->bookingService->bookNewCargo($cargo, $voyage);
101+
102+
return array('msg' => 'Cargo was successfully booked', 'success' => true);
103+
104+
} catch (ServiceException $ex) {
105+
return array('msg' => $ex->getMessage(), 'success' => false);
106+
}
107+
}
108+
109+
/**
110+
* Set the CargoRepository
111+
*
112+
* @param Cargo\CargoRepositoryInterface $cargoRepository
113+
* @return void
114+
*/
115+
public function setCargoRepository(Cargo\CargoRepositoryInterface $cargoRepository)
116+
{
117+
$this->cargoRepository = $cargoRepository;
118+
}
119+
120+
/**
121+
* Set the voyage repository
122+
*
123+
* @param Voyage\VoyageRepositoryInterface $voyageRepository
124+
* @return void
125+
*/
126+
public function setVoyageRepository(Voyage\VoyageRepositoryInterface $voyageRepository)
127+
{
128+
$this->voyageRepository = $voyageRepository;
129+
}
130+
131+
/**
132+
* Set BookingService
133+
*
134+
* @param BookingService $bookingService
135+
* @return void
136+
*/
137+
public function setBookingService(BookingService $bookingService)
138+
{
139+
$this->bookingService = $bookingService;
140+
}
141+
}

module/Application/src/Application/Controller/CargoController.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Zend\Mvc\Controller\AbstractActionController;
1212
use Zend\View\Model\ViewModel;
1313
use Application\Domain\Model\Cargo;
14+
use Application\Domain\Model\Voyage\VoyageRepositoryInterface;
1415
use Application\Form\CargoForm;
1516
/**
1617
* MVC Controller for Cargo Management
@@ -26,6 +27,13 @@ class CargoController extends AbstractActionController
2627
*/
2728
protected $cargoRepository;
2829

30+
/**
31+
*
32+
* @var VoyageRepositoryInterface
33+
*/
34+
protected $voyageRepository;
35+
36+
2937
/**
3038
*
3139
* @var CargoForm
@@ -56,7 +64,13 @@ public function showAction()
5664
throw new \RuntimeException('Cargo can not be found. Please check the trackingId!');
5765
}
5866

59-
return array('cargo' => $cargo);
67+
if ($cargo->isBooked()) {
68+
$voyages = array();
69+
} else {
70+
$voyages = $this->voyageRepository->findAll();
71+
}
72+
73+
return array('cargo' => $cargo, 'voyages' => $voyages);
6074
}
6175

6276
public function addAction()
@@ -103,6 +117,17 @@ public function setCargoRepository(Cargo\CargoRepositoryInterface $cargoReposito
103117
$this->cargoRepository = $cargoRepository;
104118
}
105119

120+
/**
121+
* Set the voyage repository
122+
*
123+
* @param VoyageRepositoryInterface $voyageRepository
124+
* @return void
125+
*/
126+
public function setVoyageRepository(VoyageRepositoryInterface $voyageRepository)
127+
{
128+
$this->voyageRepository = $voyageRepository;
129+
}
130+
106131
/**
107132
* Set a cargo form.
108133
*

module/Application/src/Application/Controller/VoyageController.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,19 @@ public function addAction()
7373
}
7474
}
7575

76+
public function showAction()
77+
{
78+
$voyageNumber = $this->getEvent()->getRouteMatch()->getParam('voyagenumber', '');
79+
80+
$voyage = $this->voyageRepository->findVoyage(new Voyage\VoyageNumber($voyageNumber));
81+
82+
if(is_null($voyage)) {
83+
throw new \Exception('Voyage could not be found');
84+
}
85+
86+
return array('voyage' => $voyage);
87+
}
88+
7689
public function setVoyageRepository(Voyage\VoyageRepositoryInterface $voyageRepository)
7790
{
7891
$this->voyageRepository = $voyageRepository;

module/Application/src/Application/Domain/Model/Cargo/Cargo.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
namespace Application\Domain\Model\Cargo;
1010

1111
use Application\Domain\Shared\EntityInterface;
12+
use Application\Domain\Model\Voyage\Voyage;
1213
use Doctrine\ORM\Mapping\Entity;
1314
use Doctrine\ORM\Mapping\Table;
1415
use Doctrine\ORM\Mapping\Column;
1516
use Doctrine\ORM\Mapping\Id;
17+
use Doctrine\ORM\Mapping\ManyToOne;
18+
use Doctrine\ORM\Mapping\JoinColumn;
1619
/**
1720
* A Cargo. This is the central class in the domain model.
1821
*
@@ -49,6 +52,18 @@ class Cargo implements EntityInterface
4952
* @var integer
5053
*/
5154
protected $size;
55+
56+
/**
57+
* The booked Voyage
58+
*
59+
* --Annotations required by Doctrine----
60+
* @ManyToOne(targetEntity="Application\Domain\Model\Voyage\Voyage", inversedBy="bookedCargos", fetch="LAZY")
61+
* @JoinColumn(name="voyage_number", referencedColumnName="voyage_number")
62+
* --------------------------------------
63+
*
64+
* @var Voyage
65+
*/
66+
protected $voyage;
5267

5368
/**
5469
* Construct
@@ -90,7 +105,36 @@ public function setSize($size)
90105
$this->size = $size;
91106
}
92107

108+
/**
109+
*
110+
* @return Voyage
111+
*/
112+
public function getVoyage()
113+
{
114+
return $this->voyage;
115+
}
116+
117+
/**
118+
*
119+
* @param Voyage $voyage
120+
* @return void
121+
*/
122+
public function setVoyage(Voyage $voyage)
123+
{
124+
$this->voyage = $voyage;
125+
}
93126

127+
/**
128+
* Check if Cargo is already booked
129+
*
130+
* @return boolean
131+
*/
132+
public function isBooked()
133+
{
134+
return !is_null($this->getVoyage());
135+
}
136+
137+
94138
/**
95139
* {@inheritDoc}
96140
*/

0 commit comments

Comments
 (0)