diff --git a/app/Resources/views/maintenance.html.twig b/app/Resources/views/maintenance.html.twig
new file mode 100644
index 0000000..6655e80
--- /dev/null
+++ b/app/Resources/views/maintenance.html.twig
@@ -0,0 +1,39 @@
+{% extends 'base.html.twig' %}
+
+{% block body %}
+
+ We are sorry, but we are in maintenance mode.
+
+
+ We are busy upgrading the system and will be back shortly.
+ Thank you for your patience!
+
+
+
+
+
+
+
+
+{% endblock %}
+{% block javascripts %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/app/Resources/views/off_canvas.html.twig b/app/Resources/views/off_canvas.html.twig
index 189f180..ab623f8 100644
--- a/app/Resources/views/off_canvas.html.twig
+++ b/app/Resources/views/off_canvas.html.twig
@@ -8,6 +8,11 @@
Our Story
RSVP
Gallery
+ {% if is_granted('IS_AUTHENTICATED_FULLY') %}
+
+ Upload Photo
+
+ {% endif %}
Location
Get In Touch
diff --git a/app/config/config.yml b/app/config/config.yml
index c3df565..0b0799f 100644
--- a/app/config/config.yml
+++ b/app/config/config.yml
@@ -13,6 +13,7 @@ parameters:
google.application_name: 'doughnut-wedding'
katrina.email: katrina.a.johnson@gmail.com
eric.email: sikofitt@gmail.com
+ maintenance: false
framework:
cache:
app: cache.adapter.redis
diff --git a/app/config/services.yml b/app/config/services.yml
index 6b7946e..8aca29e 100644
--- a/app/config/services.yml
+++ b/app/config/services.yml
@@ -38,7 +38,11 @@ services:
class: \Google_Service_Storage
factory: ['Sikofitt\DoughnutWeddingBundle\Factory\GoogleCloudStorageServiceFactory', createGoogleCloudService]
arguments: ['%google.credentials_file%', '%google.client_id%', '%google.application_name%']
-
+ doughnutwedding.event.check_maintenance_mode:
+ class: Sikofitt\DoughnutWeddingBundle\EventListener\CheckForMaintenanceModeListenerEvent
+ arguments: ['@service_container', '@security.token_storage']
+ tags:
+ - { name: kernel.event_listener, event: kernel.request }
doughnutwedding.event.check_email_on_reset_event:
class: Sikofitt\DoughnutWeddingBundle\EventListener\CheckThatEmailAndUserNameExistOnResetRequest
arguments: ['@router', '@templating.engine.twig']
diff --git a/src/Sikofitt/DoughnutWeddingBundle/Controller/GalleryController.php b/src/Sikofitt/DoughnutWeddingBundle/Controller/GalleryController.php
index 4714354..62ce298 100644
--- a/src/Sikofitt/DoughnutWeddingBundle/Controller/GalleryController.php
+++ b/src/Sikofitt/DoughnutWeddingBundle/Controller/GalleryController.php
@@ -22,19 +22,28 @@ namespace Sikofitt\DoughnutWeddingBundle\Controller;
use Pagerfanta\Adapter\ArrayAdapter;
use Pagerfanta\Pagerfanta;
-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
-use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
-use Sikofitt\DoughnutWeddingBundle\Entity\Image;
-use Sikofitt\DoughnutWeddingBundle\Entity\ImageComment;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\{
+ Method,
+ Route
+};
+use Sikofitt\DoughnutWeddingBundle\Entity\{
+ Image,
+ ImageComment,
+ User
+};
use Sikofitt\DoughnutWeddingBundle\Form\GalleryUploadType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
-use Symfony\Component\HttpFoundation\JsonResponse;
-use Symfony\Component\HttpFoundation\RedirectResponse;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\{
+ JsonResponse,
+ RedirectResponse,
+ Request,
+ Response
+};
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
-use Symfony\Component\Security\Csrf\CsrfToken;
+use Symfony\Component\Security\{
+ Core\Authentication\Token\TokenInterface,
+ Csrf\CsrfToken
+};
/**
* Class ImageController.
@@ -47,9 +56,12 @@ class GalleryController extends Controller
* @Route("/")
* @Method({"GET"})
*/
- public function indexAction(Request $request) : Response
+ public function indexAction(Request $request): Response
{
- $images = $this->get('doctrine.orm.default_entity_manager')->getRepository('SikofittDoughnutWeddingBundle:Image')->findAll();
+ $images = $this
+ ->get('doctrine.orm.entity_manager')
+ ->getRepository('SikofittDoughnutWeddingBundle:Image')
+ ->findAllSortedByUpdatedAtDesc();
$chunks = array_chunk($images, 12);
$adapter = new ArrayAdapter($images);
@@ -72,7 +84,10 @@ class GalleryController extends Controller
*/
public function pageAction(Request $request, int $number)
{
- $images = $this->get('doctrine.orm.default_entity_manager')->getRepository('SikofittDoughnutWeddingBundle:Image')->findAll();
+ $images = $this
+ ->get('doctrine.orm.entity_manager')
+ ->getRepository('SikofittDoughnutWeddingBundle:Image')
+ ->findAllSortedByUpdatedAtDesc();
$adapter = new ArrayAdapter($images);
$pager = new Pagerfanta($adapter);
@@ -80,7 +95,10 @@ class GalleryController extends Controller
$pager->setMaxPerPage(12);
$pager->setCurrentPage($number);
- return $this->render('SikofittDoughnutWeddingBundle:Image:index.html.twig', ['images' => $chunks[$number - 1], 'pager' => $pager]);
+ return $this->render('SikofittDoughnutWeddingBundle:Image:index.html.twig', [
+ 'images' => $chunks[$number - 1] ?? $images,
+ 'pager' => $pager,
+ ]);
}
/**
@@ -105,9 +123,19 @@ class GalleryController extends Controller
$em->persist($image);
$em->flush();
- $baseName = $image->getImageFile()->getBasename('.'.$image->getImageFile()->getExtension());
+ $baseName = $image
+ ->getImageFile()
+ ->getBasename(
+ sprintf('.%s', $image->getImageFile()->getExtension())
+ );
- return new RedirectResponse($this->get('router')->generate('view_gallery_image_by_hash', ['imageHash' => $baseName]));
+ return new RedirectResponse(
+ $this
+ ->get('router')
+ ->generate('view_gallery_image_by_hash', [
+ 'imageHash' => $baseName,
+ ])
+ );
}
return $this->render('SikofittDoughnutWeddingBundle:Image:upload.html.twig', [
@@ -122,20 +150,34 @@ class GalleryController extends Controller
public function ajaxCommentAction(Request $request): JsonResponse
{
if (false === $request->getSession()->has('_security_secured_area')) {
- return new JsonResponse(['status' => 403, 'message' => 'You must be logged in to post a comment'], 403);
+ return new JsonResponse([
+ 'status' => 403,
+ 'message' => 'You must be logged in to post a comment',
+ ], 403);
}
+
/** @var \Symfony\Component\Security\Core\Authentication\Token\TokenInterface $data */
- $data = unserialize($request->getSession()->get('_security_secured_area'), [TokenInterface::class]);
+ $data = unserialize(
+ $request->getSession()->get('_security_secured_area'), [
+ TokenInterface::class,
+ ]);
$tokenManager = $this->get('security.csrf.token_manager');
$fileName = $request->request->get('file');
-
$token = $request->request->get('_token');
$csrfToken = new CsrfToken($fileName, $token);
if (false === $tokenManager->isTokenValid($csrfToken)) {
return new JsonResponse(['status' => Response::HTTP_EXPECTATION_FAILED, 'message' => 'Invalid Token'], Response::HTTP_EXPECTATION_FAILED);
}
+
+ if (false === $data->getUser() instanceof User) {
+ return new JsonResponse([
+ 'status' => 403,
+ 'message' => 'You must be logged in to post a comment',
+ ], 403);
+ }
+
$em = $this->get('doctrine.orm.entity_manager');
$user = $em
->getRepository('SikofittDoughnutWeddingBundle:User')
@@ -155,6 +197,7 @@ class GalleryController extends Controller
->setIsChild(false)
->setCreated(new \DateTime('now'))
->setChildComments(null);
+
$em->persist($newComment);
$em->flush();
@@ -187,13 +230,17 @@ class GalleryController extends Controller
->get('doctrine.orm.entity_manager')
->createQueryBuilder()
->select('i')
- ->from('Sikofitt\DoughnutWeddingBundle\Entity\Image', 'i')
+ ->from(Image::class, 'i')
->where('i.imageName LIKE :imageHash')
->setParameter('imageHash', $imageHash.'%')
- ->getQuery()->getOneOrNullResult();
+ ->getQuery()
+ ->getOneOrNullResult();
+
if (null !== $image) {
- return $this->render('@SikofittDoughnutWedding/Image/view_image.html.twig',
- ['image' => $image]);
+ return $this
+ ->render('@SikofittDoughnutWedding/Image/view_image.html.twig', [
+ 'image' => $image,
+ ]);
}
throw new NotFoundHttpException();
@@ -232,6 +279,8 @@ class GalleryController extends Controller
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @param string $category
+ * @param int $number
+ * The current page
*
* @return Response
*/
diff --git a/src/Sikofitt/DoughnutWeddingBundle/Entity/Image.php b/src/Sikofitt/DoughnutWeddingBundle/Entity/Image.php
index bb29904..11f5372 100644
--- a/src/Sikofitt/DoughnutWeddingBundle/Entity/Image.php
+++ b/src/Sikofitt/DoughnutWeddingBundle/Entity/Image.php
@@ -313,6 +313,11 @@ class Image
*/
public function setTags($tags): Image
{
+ foreach ($tags as $key => $value) {
+ if (null === $value || '' === $value) {
+ unset($tags[$key]);
+ }
+ }
$this->tags = $tags;
return $this;
@@ -321,10 +326,18 @@ class Image
/**
* Get tags.
*
- * @return array
+ * @return array|string
*/
public function getTags()
{
+ if (true === is_array($this->tags)) {
+ foreach ((array) $this->tags as $key => $value) {
+ if (null === $value || '' === $value) {
+ unset($this->tags[$key]);
+ }
+ }
+ }
+
return $this->tags;
}
@@ -335,7 +348,7 @@ class Image
*
* @return Image
*/
- public function setCategory($category)
+ public function setCategory($category): ?Image
{
$this->category = $category;
@@ -347,7 +360,7 @@ class Image
*
* @return string
*/
- public function getCategory()
+ public function getCategory(): ?string
{
return $this->category;
}
diff --git a/src/Sikofitt/DoughnutWeddingBundle/EventListener/CheckForMaintenanceModeListenerEvent.php b/src/Sikofitt/DoughnutWeddingBundle/EventListener/CheckForMaintenanceModeListenerEvent.php
new file mode 100644
index 0000000..ed94de7
--- /dev/null
+++ b/src/Sikofitt/DoughnutWeddingBundle/EventListener/CheckForMaintenanceModeListenerEvent.php
@@ -0,0 +1,67 @@
+.
+ */
+
+namespace Sikofitt\DoughnutWeddingBundle\EventListener;
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+
+
+class CheckForMaintenanceModeListenerEvent
+{
+ private $container;
+ private $token;
+
+ public function __construct(ContainerInterface $container, TokenStorageInterface $token)
+ {
+ $this->container = $container;
+ $this->token = $token;
+ }
+
+ public function onKernelRequest(GetResponseEvent $event)
+ {
+ $maintenance = (bool) $this->container->getParameter('maintenance');
+
+ if (null === $maintenance || false === $maintenance) {
+ return;
+ }
+
+ $authToken = $this->token->getToken();
+ if (
+ null !== $authToken &&
+ true === $this->container
+ ->get('security.authorization_checker')
+ ->isGranted('ROLE_ADMIN', $authToken)
+ ) {
+ $event
+ ->getRequest()
+ ->getSession()
+ ->getFlashBag()
+ ->set('warning', 'Maintenance mode is on.');
+
+ return;
+ }
+
+ $event->setResponse(new Response($this->container->get('twig')
+ ->render('maintenance.html.twig')));
+ }
+}
diff --git a/src/Sikofitt/DoughnutWeddingBundle/Form/GalleryUploadType.php b/src/Sikofitt/DoughnutWeddingBundle/Form/GalleryUploadType.php
index 5bc32db..3b21258 100644
--- a/src/Sikofitt/DoughnutWeddingBundle/Form/GalleryUploadType.php
+++ b/src/Sikofitt/DoughnutWeddingBundle/Form/GalleryUploadType.php
@@ -25,56 +25,69 @@ use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Form\Type\VichImageType;
class GalleryUploadType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
+ $image = new Assert\Image();
+
$builder->add('imageFile', VichImageType::class, [
'label_attr' => [
- 'class' => 'uk-form-label uk-hidden',
+ 'class' => 'uk-form-label uk-visible@m',
+ 'id' => 'file-field-label',
+ 'style' => 'margin-right:14px;',
],
+
'attr' => [
'class' => 'uk-padding-small',
+ 'accept' => '.jpg,.jpeg,.png,.gif,.tiff',
+ ],
+ 'constraints' => [
+ new Assert\Image(),
],
])
- ->add('description', TextareaType::class, [
- 'required' => false,
- 'label' => 'Description of image.',
- 'attr' => [
- 'rows' => 4,
- 'class' => 'uk-textarea uk-form-large uk-padding-small',
- ],
- 'label_attr' => [
- 'class' => 'uk-form-label',
- ],
- ])
- ->add('tags', CollectionType::class, [
- 'required' => false,
- 'entry_type' => TextType::class,
- 'entry_options' => [
+ ->add('description', TextareaType::class, [
+ 'required' => false,
+ 'label' => 'Description of image.',
'attr' => [
- 'class' => 'uk-input uk-form-large uk-width-medium',
+ 'rows' => 4,
+ 'class' => 'uk-textarea uk-form-large uk-padding-small uk-margin-small-bottom',
+ 'placeholder' => 'Description of image',
],
- ],
- 'allow_add' => true,
- 'allow_delete' => true,
- 'label_attr' => [
- 'class' => 'uk-form-label',
- ],
- 'attr' => [
- 'class' => 'uk-input uk-form-large uk-padding-small',
- ],
- ])
- ->add('category', TextType::class, [
- 'required' => false,
- 'label_attr' => [
- 'class' => 'uk-form-label',
- ],
- 'attr' => [
- 'class' => 'uk-input uk-form-large uk-padding-small',
- ],
- ]);
+ 'label_attr' => [
+ 'class' => 'uk-form-label uk-visible@m',
+ ],
+ ])
+ ->add('tags', CollectionType::class, [
+ 'required' => false,
+ 'entry_type' => TextType::class,
+ 'entry_options' => [
+ 'attr' => [
+ 'class' => 'uk-input uk-form-large uk-width-medium uk-margin-small-bottom',
+ 'placeholder' => 'Enter tag',
+ ],
+ ],
+ 'allow_add' => true,
+ 'allow_delete' => true,
+ 'label_attr' => [
+ 'class' => 'uk-form-label uk-visible@m',
+ ],
+ 'attr' => [
+ 'class' => 'uk-input uk-form-large uk-padding-small',
+ ],
+ ])
+ ->add('category', TextType::class, [
+ 'required' => false,
+ 'label_attr' => [
+ 'class' => 'uk-form-label uk-visible@m',
+ ],
+ 'attr' => [
+ 'class' => 'uk-input uk-form-large uk-padding-small uk-margin-small-bottom',
+ 'placeholder' => 'Add category',
+ ],
+ ]);
}
}
diff --git a/src/Sikofitt/DoughnutWeddingBundle/Repository/ImageRepository.php b/src/Sikofitt/DoughnutWeddingBundle/Repository/ImageRepository.php
index f135f55..ccfe9ee 100644
--- a/src/Sikofitt/DoughnutWeddingBundle/Repository/ImageRepository.php
+++ b/src/Sikofitt/DoughnutWeddingBundle/Repository/ImageRepository.php
@@ -32,41 +32,61 @@ use Sikofitt\DoughnutWeddingBundle\Entity\Image;
class ImageRepository extends EntityRepository
{
/**
- * @param string $tag
- *
- * @return array
- */
- public function findImageByTag(string $tag): array
- {
- $images = $this->getEntityManager()
- ->createQueryBuilder()
- ->select('i')
- ->from(Image::class, 'i')
- ->where('i.tags LIKE :tag')
- ->setParameter('tag', '%'.$tag.'%')
- ->getQuery()->getResult();
- /**
- * @var int $key
- * @var Image $image
- */
- foreach ($images as $key => $image) {
- if (false === in_array($tag, $image->getTags(), true)) {
- unset($images[$key]);
- }
- }
+ * @return array|null
+ */
+ public function findAllSortedByUpdatedAtDesc(): ?array
+ {
+ return $this
+ ->getEntityManager()
+ ->createQueryBuilder()
+ ->select('i')
+ ->from(Image::class, 'i')
+ ->orderBy('i.updatedAt', 'DESC')
+ ->getQuery()
+ ->getResult();
+ }
- return $images;
+ /**
+ * @param string $tag
+ *
+ * @return array
+ */
+ public function findImageByTag(string $tag): array
+ {
+ $images = $this->getEntityManager()
+ ->createQueryBuilder()
+ ->select('i')
+ ->from(Image::class, 'i')
+ ->orderBy('i.updatedAt', 'DESC')
+ ->where('i.tags LIKE :tag')
+ ->setParameter('tag', '%'.$tag.'%')
+ ->getQuery()
+ ->getResult();
+
+ /**
+ * @var int $key
+ * @var Image $image
+ */
+ foreach ($images as $key => $image) {
+ if (false === in_array($tag, $image->getTags(), true)) {
+ unset($images[$key]);
+ }
}
+ return $images;
+ }
+
public function findImageByCategory(string $category): array
{
return $this
- ->getEntityManager()
- ->createQueryBuilder()
- ->select('i')
- ->from(Image::class, 'i')
- ->where('i.category =:category')
- ->setParameter('category', $category)
- ->getQuery()->getResult();
+ ->getEntityManager()
+ ->createQueryBuilder()
+ ->select('i')
+ ->from(Image::class, 'i')
+ ->orderBy('i.updatedAt', 'DESC')
+ ->where('i.category =:category')
+ ->setParameter('category', $category)
+ ->getQuery()
+ ->getResult();
}
}
diff --git a/src/Sikofitt/DoughnutWeddingBundle/Resources/views/Image/index.html.twig b/src/Sikofitt/DoughnutWeddingBundle/Resources/views/Image/index.html.twig
index 268ae5c..4acb318 100644
--- a/src/Sikofitt/DoughnutWeddingBundle/Resources/views/Image/index.html.twig
+++ b/src/Sikofitt/DoughnutWeddingBundle/Resources/views/Image/index.html.twig
@@ -24,7 +24,11 @@
Upload an Image to the Gallery
+Upload an Image to the Gallery
{{ form_start(form, {'attr': { 'class': 'uk-form uk-form-horizontal'}}) }} - {{ form_label(form.imageFile) }} -