diff --git a/application/config/config.php b/application/config/config.php
index 65c3030..6eb3b37 100644
--- a/application/config/config.php
+++ b/application/config/config.php
@@ -14,6 +14,7 @@
\Page\ConfigProvider::class,
\Meetup\ConfigProvider::class,
\Web\ConfigProvider::class,
+ \ContactUs\ConfigProvider::class,
new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'),
]);
diff --git a/application/data/phinx/migrations/20170830093221_contact_us.php b/application/data/phinx/migrations/20170830093221_contact_us.php
new file mode 100644
index 0000000..de27625
--- /dev/null
+++ b/application/data/phinx/migrations/20170830093221_contact_us.php
@@ -0,0 +1,34 @@
+
+ */
+class ContactUs extends AbstractMigration
+{
+ public function up()
+ {
+ $this
+ ->table('contact_us', ['id' => false, 'primary_key' => 'contact_uuid'])
+ ->addColumn('contact_uuid', 'binary', ['limit' => 16])
+ ->addColumn('contact_id', 'text')
+ ->addColumn('name', 'text')
+ ->addColumn('email', 'text')
+ ->addColumn('phone', 'text')
+ ->addColumn('subject', 'text')
+ ->addColumn('body', 'text')
+ ->addColumn('created_at', 'timestamp', ['default' => 'CURRENT_TIMESTAMP'])
+ ->create()
+ ;
+ }
+
+
+ public function down()
+ {
+ $this->dropTable('contact_us');
+ }
+}
diff --git a/application/data/phinx/seeds/ContactUs.php b/application/data/phinx/seeds/ContactUs.php
new file mode 100644
index 0000000..8e02142
--- /dev/null
+++ b/application/data/phinx/seeds/ContactUs.php
@@ -0,0 +1,34 @@
+
+ */
+class ContactUs extends AbstractSeed
+{
+ public function run()
+ {
+ $faker = Faker\Factory::create();
+ $table = $this->table('contact_us');
+
+ for ($x = 0; $x <= 5; $x++) {
+ $id = $faker->uuid;
+ $mysqlUuid = (new MysqlUuid\Uuid($id))->toFormat(new MysqlUuid\Formats\Binary());
+ $table->insert(
+ [
+ 'contact_uuid' => $mysqlUuid,
+ 'contact_id' => $id,
+ 'name' => $faker->name,
+ 'email' => $faker->companyEmail,
+ 'phone' => $faker->phoneNumber,
+ 'subject' => 'We\'r contacting you because of...',
+ 'body' => $faker->text,
+ ]
+ )->save();
+ }
+ }
+}
\ No newline at end of file
diff --git a/application/packages/Admin/templates/layout/admin.phtml b/application/packages/Admin/templates/layout/admin.phtml
index d7ed53f..8228316 100644
--- a/application/packages/Admin/templates/layout/admin.phtml
+++ b/application/packages/Admin/templates/layout/admin.phtml
@@ -86,6 +86,9 @@
Admin Users
+
+ Contact Us
+
diff --git a/application/packages/ContactUs/src/ConfigProvider.php b/application/packages/ContactUs/src/ConfigProvider.php
new file mode 100644
index 0000000..aca2cd3
--- /dev/null
+++ b/application/packages/ContactUs/src/ConfigProvider.php
@@ -0,0 +1,61 @@
+
+ */
+class ConfigProvider
+{
+ public function __invoke()
+ {
+ return [
+ 'templates' => [
+ 'map' => [
+ 'contact-us/pagination' => __DIR__.'/../templates/partial/pagination.php',
+ 'contact-us/errors' => __DIR__.'/../templates/partial/errors.php'
+ ],
+ 'paths' => [
+ 'contact-us' => [__DIR__.'/../templates/contact-us'],
+ ]
+ ],
+
+ 'dependencies' => [
+ 'factories' => [
+ Controller\ContactUsController::class => Controller\ContactUsControllerFactory::class,
+ Service\ContactUsService::class => Service\ContactUsServiceFactory::class,
+ Mapper\ContactUsMapper::class => Mapper\ContactUsMapperFactory::class,
+ Filter\ContactUsFilter::class => InvokableFactory::class,
+ ]
+ ],
+
+ 'routes' => [
+ [
+ 'name' => 'admin.contact-us',
+ 'path' => '/admin/contact-us/',
+ 'middleware' => Controller\ContactUsController::class,
+ 'allowed_methods' => ['GET'],
+ ],
+ [
+ 'name' => 'admin.contact-us.action',
+ 'path' => '/admin/contact-us/{action}/{id}',
+ 'middleware' => Controller\ContactUsController::class,
+ 'allowed_methods' => ['GET', 'POST'],
+ ]
+ ],
+
+ 'view_helpers' => [
+ 'factories' => [
+
+ ]
+ ]
+ ];
+ }
+}
diff --git a/application/packages/ContactUs/src/Controller/ContactUsController.php b/application/packages/ContactUs/src/Controller/ContactUsController.php
new file mode 100644
index 0000000..5073a3d
--- /dev/null
+++ b/application/packages/ContactUs/src/Controller/ContactUsController.php
@@ -0,0 +1,152 @@
+
+ */
+class ContactUsController extends AbstractController
+{
+ /**
+ * @var \Zend\Expressive\Router\RouterInterface $router
+ */
+ protected $router;
+
+ /**
+ * @var \Zend\Expressive\Template\TemplateRendererInterface $template
+ */
+ protected $template;
+
+ /**
+ * @var \ContactUs\Service\ContactUsService $contactUsService
+ */
+ protected $contactUsService;
+
+ /**
+ * ContactUsController constructor.
+ *
+ * @param Template $template
+ * @param Router $router
+ * @param ContactUsService $contactUsService
+ */
+ public function __construct(Template $template, Router $router, ContactUsService $contactUsService)
+ {
+ $this->template = $template;
+ $this->router = $router;
+ $this->contactUsService = $contactUsService;
+ }
+
+ /**
+ * @return HtmlResponse
+ */
+ public function index(): HtmlResponse
+ {
+ $params = $this->request->getQueryParams();
+ $page = isset($params['page']) ? $params['page'] : 1;
+ $limit = isset($params['limit']) ? $params['limit'] : 15;
+ $pagination = $this->contactUsService->getPagination($page, $limit);
+
+ return new HtmlResponse(
+ $this->template->render(
+ 'contact-us::index', [
+ 'pagination' => $pagination,
+ 'layout' => 'layout/admin',
+ ]
+ )
+ );
+ }
+
+ /**
+ * @param array $errors
+ *
+ * @return HtmlResponse
+ */
+ public function edit($errors = []): HtmlResponse
+ {
+ $id = $this->request->getAttribute('id');
+ $contactUs = $this->contactUsService->getById($id);
+
+ if ($this->request->getParsedBody()) {
+ $contactUs = new ContactUs();
+ $contactUs->exchangeArray(
+ $this->request->getParsedBody() + (array) $contactUs
+ );
+ $contactUs->setContactId($id);
+ }
+
+ return new HtmlResponse(
+ $this->template->render(
+ 'contact-us::edit', [
+ 'contact' => $contactUs,
+ 'errors' => $errors,
+ 'layout' => 'layout/admin',
+ ]
+ )
+ );
+ }
+
+ /**
+ * @return ResponseInterface
+ *
+ * @throws \Exception
+ */
+ public function save(): ResponseInterface
+ {
+ try
+ {
+ $id = $this->request->getAttribute('id');
+ $data = $this->request->getParsedBody();
+
+ if ($id) {
+ $this->contactUsService->update($data, $id);
+ } else {
+ $this->contactUsService->create($data);
+ }
+
+ return $this->response
+ ->withStatus(302)
+ ->withHeader('Location', $this->router->generateUri('admin.contact-us'))
+ ;
+
+ } catch (FilterException $fe) {
+ return $this->edit($fe->getArrayMessages());
+ } catch (\Exception $e) {
+ throw $e;
+ }
+ }
+
+ /**
+ * @return ResponseInterface
+ */
+ public function delete(): ResponseInterface
+ {
+ try
+ {
+ $id = $this->request->getAttribute('id');
+ $this->contactUsService->delete($id);
+
+ return $this->response
+ ->withStatus(302)
+ ->withHeader('Location', $this->router->generateUri('admin.contact-us'))
+ ;
+
+ } catch (\Exception $e) {
+ return $this->response
+ ->withStatus(302)
+ ->withHeader('Location', $this->router->generateUri('admin.contact-us'))
+ ;
+ }
+ }
+}
\ No newline at end of file
diff --git a/application/packages/ContactUs/src/Controller/ContactUsControllerFactory.php b/application/packages/ContactUs/src/Controller/ContactUsControllerFactory.php
new file mode 100644
index 0000000..ef1c628
--- /dev/null
+++ b/application/packages/ContactUs/src/Controller/ContactUsControllerFactory.php
@@ -0,0 +1,33 @@
+
+ */
+class ContactUsControllerFactory
+{
+ /**
+ * @param ContainerInterface $container
+ *
+ * @return ContactUsController
+ */
+ public function __invoke(ContainerInterface $container): ContactUsController
+ {
+ return new ContactUsController(
+ $container->get(TemplateRendererInterface::class),
+ $container->get(RouterInterface::class),
+ $container->get(ContactUsService::class)
+ );
+ }
+}
diff --git a/application/packages/ContactUs/src/Entity/ContactUs.php b/application/packages/ContactUs/src/Entity/ContactUs.php
new file mode 100644
index 0000000..a6da175
--- /dev/null
+++ b/application/packages/ContactUs/src/Entity/ContactUs.php
@@ -0,0 +1,208 @@
+
+ */
+class ContactUs
+{
+ private $contact_uuid;
+ private $contact_id;
+ private $name;
+ private $email;
+ private $phone;
+ private $subject;
+ private $body;
+ private $created_at;
+
+ /**
+ * @return mixed
+ */
+ public function getContactUuid()
+ {
+ return $this->contact_id;
+ }
+
+ /**
+ * @param $uuid
+ *
+ * @return \ContactUs\Entity\ContactUs
+ */
+ public function setContactUuid($uuid)
+ {
+ $this->contact_id = $uuid;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getContactId()
+ {
+ return $this->contact_id;
+ }
+
+ /**
+ * @param $id
+ *
+ * @return \ContactUs\Entity\ContactUs
+ */
+ public function setContactId($id)
+ {
+ $this->contact_id = $id;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * @param $name
+ *
+ * @return \ContactUs\Entity\ContactUs
+ */
+ public function setName($name)
+ {
+ $this->name = $name;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getEmail()
+ {
+ return $this->email;
+ }
+
+ /**
+ * @param $email
+ *
+ * @return \ContactUs\Entity\ContactUs
+ */
+ public function setEmail($email)
+ {
+ $this->email = $email;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getPhone()
+ {
+ return $this->phone;
+ }
+
+ /**
+ * @param $phone
+ *
+ * @return \ContactUs\Entity\ContactUs
+ */
+ public function setPhone($phone)
+ {
+ $this->phone = $phone;
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getSubject()
+ {
+ return $this->subject;
+ }
+
+ /**
+ * @param $subject
+ *
+ * @return \ContactUs\Entity\ContactUs
+ */
+ public function setSubject($subject)
+ {
+ $this->subject = $subject;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBody()
+ {
+ return $this->body;
+ }
+
+ /**
+ * @param $body
+ *
+ * @return \ContactUs\Entity\ContactUs
+ */
+ public function setBody($body)
+ {
+ $this->body = $body;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getCreatedAt()
+ {
+ return $this->created_at;
+ }
+
+ /**
+ * @param string $createdAt
+ *
+ * @return \ContactUs\Entity\ContactUs
+ */
+ public function setCreatedAt($createdAt)
+ {
+ $this->created_at = $createdAt;
+ }
+
+ /**
+ * Hydration of object.
+ *
+ * @param array $data
+ */
+ public function exchangeArray($data = [])
+ {
+ // Fetch entity properties.
+ $properties = array_keys(
+ get_object_vars($this)
+ );
+
+ foreach ($properties as $property) {
+ $this->{$property} = isset($data[$property]) ? $data[$property] : null;
+ }
+ }
+
+ /**
+ * Dehydrate/Extract object to array.
+ *
+ * @return array
+ */
+ public function getArrayCopy()
+ {
+ return [
+ 'contact_uuid' => (binary) $this->contact_uuid,
+ 'contact_id' => (string) $this->contact_id,
+ 'name' => (string) $this->name,
+ 'email' => (string) $this->email,
+ 'phone' => $this->phone,
+ 'subject' => (string) $this->subject,
+ 'body' => (string) $this->body,
+ 'created_at' => (string) $this->created_at
+ ];
+ }
+}
\ No newline at end of file
diff --git a/application/packages/ContactUs/src/Filter/ContactUsFilter.php b/application/packages/ContactUs/src/Filter/ContactUsFilter.php
new file mode 100644
index 0000000..ad4f068
--- /dev/null
+++ b/application/packages/ContactUs/src/Filter/ContactUsFilter.php
@@ -0,0 +1,92 @@
+
+ */
+class ContactUsFilter implements InputFilterAwareInterface
+{
+ /**
+ * @var \Zend\InputFilter\InputFilter $inputFilter
+ */
+ protected $inputFilter;
+
+ /**
+ * @return InputFilter
+ */
+ public function getInputFilter()
+ {
+ $inputFilter = new InputFilter();
+
+ $inputFilter
+ ->add([
+ 'name' => 'name',
+ 'required' => true,
+ 'filters' => [['name' => 'StringTrim']],
+ 'validators' => [
+ ['name' => 'NotEmpty'],
+ ['name' => 'StringLength', 'options' => ['min' => 1, 'max' => 255]],
+ ],
+ ])
+ ->add([
+ 'name' => 'email',
+ 'required' => true,
+ 'filters' => [['name' => 'StringTrim']],
+ 'validators' => [
+ ['name' => 'NotEmpty'],
+ ['name' => 'EmailAddress'],
+ ['name' => 'StringLength', 'options' => ['min' => 2, 'max' => 100]],
+ ]
+ ])
+ ->add([
+ 'name' => 'phone',
+ 'required' => false,
+ 'filters' => [['name' => 'StringTrim']],
+ 'validators' => [
+ // TODO: PhoneNumber match cases.
+ ]
+ ])
+ ->add([
+ 'name' => 'subject',
+ 'required' => true,
+ 'filters' => [['name' => 'StringTrim']],
+ 'validators' => [
+ ['name' => 'NotEmpty'],
+ ['name' => 'StringLength', 'options' => ['min' => 5]]
+ ]
+ ])
+ ->add([
+ 'name' => 'body',
+ 'required' => true,
+ 'filters' => [['name' => 'StringTrim']],
+ 'validators' => [
+ ['name' => 'NotEmpty'],
+ ['name' => 'StringLength', 'options' => ['min' => 5]]
+ ]
+ ])
+ ;
+
+ return $inputFilter;
+ }
+
+ /**
+ * @param InputFilterInterface $inputFilter
+ *
+ * @return void
+ *
+ * @throws \Exception
+ */
+ public function setInputFilter(InputFilterInterface $inputFilter)
+ {
+ $ex = new \Exception('Not used');
+ throw $ex;
+ }
+}
\ No newline at end of file
diff --git a/application/packages/ContactUs/src/Mapper/ContactUsMapper.php b/application/packages/ContactUs/src/Mapper/ContactUsMapper.php
new file mode 100644
index 0000000..53efdcf
--- /dev/null
+++ b/application/packages/ContactUs/src/Mapper/ContactUsMapper.php
@@ -0,0 +1,60 @@
+
+ */
+class ContactUsMapper extends AbstractTableGateway implements AdapterAwareInterface
+{
+ /**
+ * Table name.
+ *
+ * @var string $table
+ */
+ protected $table = 'contact_us';
+
+ /**
+ * ContactUsMapper constructor.
+ *
+ * @param Adapter $adapter
+ * @param HydratingResultSet $resultSet
+ */
+ public function __construct(Adapter $adapter, HydratingResultSet $resultSet)
+ {
+ $this->resultSetPrototype = $resultSet;
+ $this->adapter = $adapter;
+ $this->initialize();
+ }
+
+ /**
+ * @param Adapter $adapter
+ *
+ * @return void
+ *
+ * @throws \Exception
+ */
+ public function setDbAdapter(Adapter $adapter)
+ {
+ $ex = new \Exception('Set DB adapter in constructor.', 400);
+ throw $ex;
+ }
+
+ /**
+ * @return \Zend\Db\Sql\Select
+ */
+ public function getPaginationSelect()
+ {
+ return $this->getSql()->select()->order([
+ 'created_at' => 'desc',
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/application/packages/ContactUs/src/Mapper/ContactUsMapperFactory.php b/application/packages/ContactUs/src/Mapper/ContactUsMapperFactory.php
new file mode 100644
index 0000000..348d2ca
--- /dev/null
+++ b/application/packages/ContactUs/src/Mapper/ContactUsMapperFactory.php
@@ -0,0 +1,33 @@
+
+ */
+class ContactUsMapperFactory
+{
+ /**
+ * @param ContainerInterface $container
+ *
+ * @return ContactUsMapper
+ */
+ public function __invoke(ContainerInterface $container): ContactUsMapper
+ {
+ $adapter = $container->get(Adapter::class);
+ $resultSet = new HydratingResultSet(
+ new ArraySerializable(), new ContactUs()
+ );
+
+ return new ContactUsMapper($adapter, $resultSet);
+ }
+}
\ No newline at end of file
diff --git a/application/packages/ContactUs/src/Service/ContactUsService.php b/application/packages/ContactUs/src/Service/ContactUsService.php
new file mode 100644
index 0000000..24c2266
--- /dev/null
+++ b/application/packages/ContactUs/src/Service/ContactUsService.php
@@ -0,0 +1,174 @@
+
+ */
+class ContactUsService
+{
+ /**
+ * @var ContactUsFilter $contactUsFilter
+ */
+ private $contactUsFilter;
+
+ /**
+ * @var ContactUsMapper $contactUsMapper
+ */
+ private $contactUsMapper;
+
+ /**
+ * @var Paginator $pagination
+ */
+ private $pagination;
+
+ /**
+ * ContactUsService constructor.
+ *
+ * @param ContactUsFilter $contactUsFilter
+ * @param ContactUsMapper $contactUsMapper
+ * @param Paginator $pagination
+ */
+ public function __construct(
+ ContactUsFilter $contactUsFilter,
+ ContactUsMapper $contactUsMapper,
+ Paginator $pagination)
+ {
+ $this->contactUsFilter = $contactUsFilter;
+ $this->contactUsMapper = $contactUsMapper;
+ $this->pagination = $pagination;
+ }
+
+ /**
+ * @param int $page
+ * @param int $limit
+ *
+ * @return Paginator
+ */
+ public function getPagination($page = 1, $limit = 10)
+ {
+ $this->pagination->setCurrentPageNumber($page);
+ $this->pagination->setItemCountPerPage($limit);
+
+ return $this->pagination;
+ }
+
+ /**
+ * Return all records from db.
+ *
+ * @return \Zend\Db\ResultSet\ResultSet
+ */
+ public function getAll()
+ {
+ return $this->contactUsMapper->select();
+ }
+
+ /**
+ * @param mixed $contactId
+ *
+ * @return array|\ArrayObject|null
+ */
+ public function getById($contactId)
+ {
+ return $this->contactUsMapper->select(['contact_id' => $contactId])->current();
+ }
+
+ /**
+ * @param string $email
+ *
+ * @return array|\ArrayObject|null
+ */
+ public function getByEmail($email)
+ {
+ return $this->contactUsMapper->select(['email' => (string) $email])->current();
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return int
+ */
+ public function create(array $data)
+ {
+ $data = $this->filterData($data);
+ $data['contact_id'] = Uuid::uuid1()->toString();
+ $data['contact_uuid'] = (new \MysqlUuid\Uuid($data['contact_id']))->toFormat(new Binary());
+
+ return $this->contactUsMapper->insert($data);
+ }
+
+ /**
+ * @param array $data
+ * @param mixed $contactId
+ *
+ * @return int
+ *
+ * @throws \Exception
+ */
+ public function update($data, $contactId)
+ {
+ if (empty($this->getById($contactId))) {
+ $ex = new \Exception('Contact message object not found. Contact Message ID: ' . $contactId);
+ throw $ex;
+ }
+
+ return $this->contactUsMapper->update(
+ $this->filterData($data), ['contact_id' => $contactId]
+ );
+ }
+
+ /**
+ * @param mixed $contactId
+ *
+ * @return bool
+ *
+ * @throws \Exception
+ */
+ public function delete($contactId)
+ {
+ if (empty($this->getById($contactId))) {
+ $ex = new \Exception('Contact Message with ID: ' .$contactId. ' not found');
+ throw $ex;
+ }
+
+ return (bool) $this->contactUsMapper->delete(['contact_id' => $contactId]);
+ }
+
+ /**
+ * @return \Zend\Db\ResultSet\ResultSet
+ */
+ public function getForSelect()
+ {
+ return $this->contactUsMapper->select();
+ }
+
+ /**
+ * @param array $data
+ *
+ * @return array
+ *
+ * @throws FilterException
+ */
+ private function filterData($data)
+ {
+ $filter = $this->contactUsFilter->getInputFilter();
+ $filter->setData($data);
+
+ if (!$filter->isValid()) {
+ $ex = new FilterException($filter->getMessages());
+ throw $ex;
+ }
+
+ return $filter->getValues();
+ }
+}
\ No newline at end of file
diff --git a/application/packages/ContactUs/src/Service/ContactUsServiceFactory.php b/application/packages/ContactUs/src/Service/ContactUsServiceFactory.php
new file mode 100644
index 0000000..e3c51d4
--- /dev/null
+++ b/application/packages/ContactUs/src/Service/ContactUsServiceFactory.php
@@ -0,0 +1,43 @@
+
+ */
+class ContactUsServiceFactory
+{
+ /**
+ * @param ContainerInterface $container
+ *
+ * @return ContactUsService
+ */
+ public function __invoke(ContainerInterface $container)
+ {
+ // Create pagination object
+ $contactUsMapper = $container->get(ContactUsMapper::class);
+ $select = $contactUsMapper->getPaginationSelect();
+ $pagination = new Paginator((
+ new DbSelect(
+ $select,
+ $contactUsMapper->getAdapter(),
+ $contactUsMapper->getResultSetPrototype()
+ )
+ ));
+
+ return new ContactUsService(
+ $container->get(ContactUsFilter::class),
+ $container->get(ContactUsMapper::class),
+ $pagination
+ );
+ }
+}
\ No newline at end of file
diff --git a/application/packages/ContactUs/templates/contact-us/edit.phtml b/application/packages/ContactUs/templates/contact-us/edit.phtml
new file mode 100644
index 0000000..2dbac55
--- /dev/null
+++ b/application/packages/ContactUs/templates/contact-us/edit.phtml
@@ -0,0 +1,103 @@
+
+
+ /* normalize errors */ ?>
+= $this->partial('contact-us/errors', ['errors' => $errors]) ?>
+
+
+
+
+
+
+ getContactId()): ?>
+ Subject: "= $contact->getSubject() ?>"
+
+ Message Edit
+
+
+
+ Back
+
+
+
+
+
+
+
diff --git a/application/packages/ContactUs/templates/contact-us/index.phtml b/application/packages/ContactUs/templates/contact-us/index.phtml
new file mode 100644
index 0000000..7332ead
--- /dev/null
+++ b/application/packages/ContactUs/templates/contact-us/index.phtml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
Contact Us
+ / List of contact messages.
+
+
+
+
+
+
+
+
+
+
+ getTotalItemCount() > 0): ?>
+
+
+
+ Name |
+ Email |
+ Phone |
+ Subject |
+ Created |
+ |
+
+
+
+
+
+ = $record->getName(); ?> |
+ = $record->getEmail(); ?> |
+ = $record->getPhone(); ?> |
+ = $record->getSubject(); ?> |
+ = $record->getCreatedAt('H:i d.m.Y') ?> |
+
+
+
+
+
+
+ |
+
+
+
+
+ = $this->paginationControl($pagination, 'Sliding', 'contact-us/pagination', ['route' => 'admin.contact-us']) ?>
+
+
+
+
There are no contact messages!
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/application/packages/ContactUs/templates/partial/errors.php b/application/packages/ContactUs/templates/partial/errors.php
new file mode 100644
index 0000000..fcc155a
--- /dev/null
+++ b/application/packages/ContactUs/templates/partial/errors.php
@@ -0,0 +1,11 @@
+
+ $messages): ?>
+
+ $field = '
+
+ - '.(implode("
", (array) $messages)).'
+
+ '; ?>
+
+
+
\ No newline at end of file
diff --git a/application/packages/ContactUs/templates/partial/pagination.php b/application/packages/ContactUs/templates/partial/pagination.php
new file mode 100644
index 0000000..dd2261e
--- /dev/null
+++ b/application/packages/ContactUs/templates/partial/pagination.php
@@ -0,0 +1,63 @@
+
+
+
+
+ Showing = $this->get('firstItemNumber') ?> to = $this->get('lastItemNumber') ?> out
+ of = $this->totalItemCount ?> results.
+
+
+
+ pageCount > 1) : ?>
+
+
+
+
+
+
+
+
diff --git a/application/packages/ContactUs/tests/ConfigProviderTest.php b/application/packages/ContactUs/tests/ConfigProviderTest.php
new file mode 100644
index 0000000..0718b04
--- /dev/null
+++ b/application/packages/ContactUs/tests/ConfigProviderTest.php
@@ -0,0 +1,20 @@
+
+ */
+class ConfigProviderTest extends \PHPUnit_Framework_TestCase
+{
+ public function testInvokeShouldReturnContactUsConfigProvider()
+ {
+ $configProvider = new \ContactUs\ConfigProvider();
+ static::assertInternalType('array', $configProvider());
+ }
+}
diff --git a/application/packages/ContactUs/tests/bootstrap.php b/application/packages/ContactUs/tests/bootstrap.php
new file mode 100644
index 0000000..667364c
--- /dev/null
+++ b/application/packages/ContactUs/tests/bootstrap.php
@@ -0,0 +1,5 @@
+
+
+
+ ./
+
+
+
+ ../src
+
+
+
diff --git a/application/packages/ContactUs/tests/phpunit.xml.dist b/application/packages/ContactUs/tests/phpunit.xml.dist
new file mode 100644
index 0000000..3e67bdd
--- /dev/null
+++ b/application/packages/ContactUs/tests/phpunit.xml.dist
@@ -0,0 +1,21 @@
+
+
+
+ ./
+
+
+
+ ../src
+
+
+
diff --git a/application/packages/Web/Action/ContactUsAction.php b/application/packages/Web/Action/ContactUsAction.php
new file mode 100644
index 0000000..f4de459
--- /dev/null
+++ b/application/packages/Web/Action/ContactUsAction.php
@@ -0,0 +1,104 @@
+
+ */
+class ContactUsAction
+{
+ /**
+ * @var Template $template
+ */
+ protected $template;
+
+ /**
+ * @var ContactUsService $contactUsService
+ */
+ protected $contactUsService;
+
+ /**
+ * @var RouterInterface $router
+ */
+ protected $router;
+
+ /**
+ * ContactUsAction constructor.
+ *
+ * @param Template $template
+ * @param ContactUsService $contactUsService
+ * @param RouterInterface $router
+ */
+ public function __construct(
+ Template $template,
+ ContactUsService $contactUsService,
+ RouterInterface $router)
+ {
+ $this->template = $template;
+ $this->contactUsService = $contactUsService;
+ }
+
+ /**
+ * Executed when action is invoked.
+ *
+ * @param Request $request
+ * @param Response $response
+ * @param callable $next
+ *
+ * @throws \Exception
+ *
+ * @return mixed
+ */
+ public function __invoke(Request $request, Response $response, callable $next = null)
+ {
+ return new HtmlResponse($this->template->render('web::contact', [
+ 'layout' => 'layout/web'
+ ]));
+ }
+
+ /**
+ * @param Request $request
+ * @param Response $response
+ *
+ * @return Response
+ *
+ * @throws FilterException
+ * @throws \Exception
+ */
+ public function post(Request $request, Response $response)
+ {
+ $data = $request->getAttributes();
+ if (!empty($data)) {
+ try
+ {
+ $this->contactUsService->create($data);
+ return $response
+ ->withStatus(200)
+ ->withHeader('Location', $this->router->generateUri('contact-us'))
+ ;
+
+ } catch (FilterException $fe) {
+
+ return $response
+ ->withStatus(302)
+ ->withHeader('Location', $this->router->generateUri('contact-us'))
+ ;
+
+ } catch (\Exception $e) {
+ throw $e;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/application/packages/Web/ConfigProvider.php b/application/packages/Web/ConfigProvider.php
index 3ff8f02..5a7b09f 100644
--- a/application/packages/Web/ConfigProvider.php
+++ b/application/packages/Web/ConfigProvider.php
@@ -20,14 +20,15 @@ public function __invoke()
'dependencies' => [
'factories' => [
- Action\HomeAction::class => Factory\Action\HomeActionFactory::class,
- Action\PageAction::class => Factory\Action\PageActionFactory::class,
- Action\PostsAction::class => Factory\Action\PostsActionFactory::class,
- Action\PostAction::class => Factory\Action\PostActionFactory::class,
- Action\VideosAction::class => Factory\Action\VideosActionFactory::class,
- Action\VideoAction::class => Factory\Action\VideoActionFactory::class,
- Action\EventsAction::class => Factory\Action\EventsActionFactory::class,
- Action\EventAction::class => Factory\Action\EventActionFactory::class,
+ Action\HomeAction::class => Factory\Action\HomeActionFactory::class,
+ Action\PageAction::class => Factory\Action\PageActionFactory::class,
+ Action\PostsAction::class => Factory\Action\PostsActionFactory::class,
+ Action\PostAction::class => Factory\Action\PostActionFactory::class,
+ Action\VideosAction::class => Factory\Action\VideosActionFactory::class,
+ Action\VideoAction::class => Factory\Action\VideoActionFactory::class,
+ Action\EventsAction::class => Factory\Action\EventsActionFactory::class,
+ Action\EventAction::class => Factory\Action\EventActionFactory::class,
+ Action\ContactUsAction::class => Factory\Action\ContactUsFactory::class
],
],
@@ -37,6 +38,18 @@ public function __invoke()
'path' => '/',
'middleware' => Action\HomeAction::class,
],
+ [
+ 'name' => 'contact-us',
+ 'path' => '/contact-us',
+ 'middleware' => Action\ContactUsAction::class,
+ 'allowed_methods' => ['POST', 'GET'],
+ ],
+ [
+ 'name' => 'contact-us-post',
+ 'path' => '/contact-us-post',
+ 'middleware' => Action\ContactUsAction::class,
+ 'allowed_methods' => ['POST'],
+ ],
[
'name' => 'page',
'path' => '/{url_slug}',
@@ -59,7 +72,7 @@ public function __invoke()
Action\VideoAction::class,
Action\EventAction::class,
],
- ],
+ ]
],
];
}
diff --git a/application/packages/Web/Factory/Action/ContactUsFactory.php b/application/packages/Web/Factory/Action/ContactUsFactory.php
new file mode 100644
index 0000000..d965cb8
--- /dev/null
+++ b/application/packages/Web/Factory/Action/ContactUsFactory.php
@@ -0,0 +1,32 @@
+
+ */
+class ContactUsFactory
+{
+ /**
+ * @param ContainerInterface $container
+ *
+ * @return ContactUsAction
+ */
+ public function __invoke(ContainerInterface $container): ContactUsAction
+ {
+ return new ContactUsAction(
+ $container->get(TemplateRendererInterface::class),
+ $container->get(ContactUsService::class),
+ $container->get(RouterInterface::class)
+ );
+ }
+}
\ No newline at end of file
diff --git a/application/templates/web/contact.phtml b/application/templates/web/contact.phtml
new file mode 100644
index 0000000..fefa4cc
--- /dev/null
+++ b/application/templates/web/contact.phtml
@@ -0,0 +1,89 @@
+headTitle('Kontakt');
+ $this->headMeta('kontakt stranica', 'description');
+ $this->headMeta('page', 'og:type');
+ $this->headMeta($this->serverUrl(), 'og:url');
+?>
+
+
+