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 @@ + + + +partial('contact-us/errors', ['errors' => $errors]) ?> + +
    +
    +
    +
    +

    + getContactId()): ?> +

    Subject: "getSubject() ?>"

    + +

    Message Edit

    + + + + Back + +
    +
    +

    +
    + +
    +
    + + + + name) ? $errors->name : ''); ?> + +
    +
    + +
    +
    + + + + email) ? $errors->email : ''); ?> + +
    +
    + +
    +
    + + + + phone ) ? $errors->phone : ''); ?> + +
    +
    + +
    +
    + + + + subject ) ? $errors->subject : ''); ?> + +
    +
    + +
    +
    + + + + body ) ? $errors->body : ''); ?> + +
    +
    + +
    + +
    +
    + + + Cancel + + getContactId()): ?> + Delete + + +
    +
    + +
    +
    +
    +
    +
    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): ?> + + + + + + + + + + + + + + + + + + + + + + + +
    NameEmailPhoneSubjectCreated
    getName(); ?>getEmail(); ?>getPhone(); ?>getSubject(); ?>getCreatedAt('H:i d.m.Y') ?> + + + +   + +
    + 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 = ' + + '; ?> + + + \ 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 get('firstItemNumber') ?> to get('lastItemNumber') ?> out + of totalItemCount ?> results. +
    +
    +
    + pageCount > 1) : ?> +
    +
      + + previous)) : ?> +
    • + + + +
    • + +
    • + + + +
    • + + + + pagesInRange as $page): ?> + current) : ?> +
    • + + + +
    • + +
    • + +
    • + + + + + next)) : ?> +
    • + + + +
    • + +
    • + + + +
    • + +
    +
    + +
    +
    + + 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'); +?> + +
    +
    +
    Kontakt
    +
    + + + +
    + +
    +
    +
    +
    +

    + Kontakt Forma +

    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    + +
    +

    Ne propustite

    + + event()->getLatest(2) as $event): ?> + + + + + + post()->forWeb() as $post): ?> + + + +
    +
    +
    +