diff --git a/.editorconfig b/.editorconfig
index b9f9286..05c83fe 100755
--- a/.editorconfig
+++ b/.editorconfig
@@ -15,10 +15,6 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
-[*.feature]
-indent_style = space
-indent_size = 2
-
[*.json]
indent_style = space
indent_size = 2
@@ -34,14 +30,15 @@ indent_size = 4
indent_style = space
indent_size = 4
-[*.yml]
+[*.yaml]
indent_style = space
indent_size = 4
trim_trailing_whitespace = false
-[.circleci/config.yml]
+[*.yml]
indent_style = space
-indent_size = 2
+indent_size = 4
+trim_trailing_whitespace = false
[.gitmodules]
indent_style = tab
@@ -50,7 +47,7 @@ indent_style = tab
indent_style = space
indent_size = 4
-[.styleci.yml]
+[.php_cs.xml.dist]
indent_style = space
indent_size = 2
@@ -58,14 +55,6 @@ indent_size = 2
indent_style = space
indent_size = 2
-[appveyor.yml]
-indent_style = space
-indent_size = 2
-
-[behat.yml]
-indent_style = space
-indent_size = 2
-
[composer.json]
indent_style = space
indent_size = 4
diff --git a/README.md b/README.md
index 8774071..b162075 100755
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@ The source of the documentation is stored in the `src/Resources/doc/` folder in
### Installation
1. [Download CalendarBundle using composer](#1-download-calendarbundle-using-composer)
-2. [Create the listener](#2-create-the-listener)
+2. [Create the subscriber](#2-create-the-subscriber)
3. [Add styles and scripts in your template](#3-add-styles-and-scripts-in-your-template)
#### 1. Download CalendarBundle using composer
@@ -45,42 +45,49 @@ calendar:
resource: "@CalendarBundle/Resources/config/routing.yaml"
```
-#### 2. Create the listener
-You need to create a listener class to load your data into the calendar and register it as a service.
+#### 2. Create the subscriber
+You need to create a subscriber class to load your data into the calendar.
-This listener must be called when the event `calendar.set_data` is launched.
+This subscriber must be registered only if autoconfigure is false.
```yaml
# config/services.yaml
services:
# ...
- App\EventListener\CalendarListener:
- tags:
- - { name: 'kernel.event_listener', event: 'calendar.set_data', method: load }
+ App\EventSubscriber\CalendarSubscriber:
```
-Then, create the listener class to fill the calendar
+Then, create the subscriber class to fill the calendar
-See the [doctrine listener example](src/Resources/doc/doctrine-crud.md#full-listener)
+See the [doctrine subscriber example](src/Resources/doc/doctrine-crud.md#full-subscriber)
```php
-// src/EventListener/CalendarListener.php
+// src/EventSubscriber/CalendarSubscriber.php
'onCalendarSetData',
+ ];
+ }
+
+ public function onCalendarSetData(CalendarEvent $calendar)
{
$start = $calendar->getStart();
$end = $calendar->getEnd();
$filters = $calendar->getFilters();
- // You may want to make a custom query to fill the calendar
+ // You may want to make a custom query from your database to fill the calendar
$calendar->addEvent(new Event(
'Event 1',
diff --git a/composer.json b/composer.json
index bb40708..c96622a 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,12 @@
"name": "tattali/calendar-bundle",
"type": "symfony-bundle",
"description": "Provides event calendar for your Symfony 4 project. Compatible with Doctrine ORM & ODM, and API like Google Calendar.",
- "keywords": ["fullcalendar", "calendar", "symfony", "symfony calendar"],
+ "keywords": [
+ "fullcalendar",
+ "calendar",
+ "symfony",
+ "symfony calendar"
+ ],
"homepage": "https://github.com/tattali/CalendarBundle",
"license": "MIT",
"authors": [
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
old mode 100644
new mode 100755
index 28757da..7167a3b
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -3,7 +3,6 @@
-
@@ -13,7 +12,6 @@
-
@@ -21,4 +19,7 @@
+
+ src/
+ tests/
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index f53d464..39d3796 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -9,7 +9,7 @@
-
+
diff --git a/src/Controller/CalendarController.php b/src/Controller/CalendarController.php
index 01ac9af..6997d95 100755
--- a/src/Controller/CalendarController.php
+++ b/src/Controller/CalendarController.php
@@ -11,6 +11,7 @@
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as ContractsEventDispatcherInterface;
class CalendarController extends AbstractController
{
@@ -39,9 +40,9 @@ public function loadAction(Request $request): Response
$filters = $request->get('filters', '{}');
$filters = \is_array($filters) ? $filters : json_decode($filters, true);
- $event = $this->eventDispatcher->dispatch(
- CalendarEvents::SET_DATA,
- new CalendarEvent($start, $end, $filters)
+ $event = $this->dispatchWithBC(
+ new CalendarEvent($start, $end, $filters),
+ CalendarEvents::SET_DATA
);
$content = $this->serializer->serialize($event->getEvents());
@@ -52,4 +53,13 @@ public function loadAction(Request $request): Response
return $response;
}
+
+ public function dispatchWithBC($event, string $eventName)
+ {
+ if ($this->eventDispatcher instanceof ContractsEventDispatcherInterface) {
+ return $this->eventDispatcher->dispatch($event, $eventName);
+ }
+
+ return $this->eventDispatcher->dispatch($eventName, $event);
+ }
}
diff --git a/src/Event/CalendarEvent.php b/src/Event/CalendarEvent.php
index 2e6fee9..905955c 100644
--- a/src/Event/CalendarEvent.php
+++ b/src/Event/CalendarEvent.php
@@ -5,9 +5,14 @@
namespace CalendarBundle\Event;
use CalendarBundle\Entity\Event;
+use CalendarBundle\Event\Event as BaseEvent;
use DateTimeInterface;
-use Symfony\Component\EventDispatcher\Event as BaseEvent;
+/**
+ * This event is triggered before the serialization of the events.
+ *
+ * This event allows you to fill the calendar with your data.
+ */
class CalendarEvent extends BaseEvent
{
/**
diff --git a/src/Event/Event.php b/src/Event/Event.php
new file mode 100644
index 0000000..8b148e0
--- /dev/null
+++ b/src/Event/Event.php
@@ -0,0 +1,22 @@
+addOption(
);
```
-#### Full listener
+#### Full subscriber
-Full listener with `Booking` entity. Modify it to fit your needs.
+Full subscriber with `Booking` entity. Modify it to fit your needs.
```php
-// src/EventListener/CalendarListener.php
+// src/EventSubscriber/CalendarSubscriber.php
router = $router;
}
- public function load(CalendarEvent $calendar): void
+ public static function getSubscribedEvents()
+ {
+ return [
+ CalendarEvents::SET_DATA => 'onCalendarSetData',
+ ];
+ }
+
+ public function onCalendarSetData(CalendarEvent $calendar)
{
$start = $calendar->getStart();
$end = $calendar->getEnd();
@@ -280,7 +287,7 @@ class CalendarListener
// Change booking.beginAt by your start date property
$bookings = $this->bookingRepository
->createQueryBuilder('booking')
- ->where('booking.beginAt BETWEEN :start and :end')
+ ->where('booking.beginAt BETWEEN :start and :end OR booking.endAt BETWEEN :start and :end')
->setParameter('start', $start->format('Y-m-d H:i:s'))
->setParameter('end', $end->format('Y-m-d H:i:s'))
->getQuery()
@@ -325,16 +332,19 @@ class CalendarListener
Then create the calendar template
add a link to the `booking_new` form
+
```twig
Create new booking
```
and include the `calendar-holder`
+
```twig
{% include '@Calendar/calendar.html' %}
```
Full template:
+
```twig
{# templates/booking/calendar.html.twig #}
{% extends 'base.html.twig' %}
@@ -389,13 +399,14 @@ Full template:
{% endblock %}
```
-* Now visit: http://localhost:8000/booking/calendar
+
+* Now visit:
* In the calendar when you click on an event it call the `show()` action that should contains an edit and delete link
* And when you create a new `Booking` (or your custom entity name) it appear on the calendar
-* If you have created a custom entity don't forget to modify the listener:
+* If you have created a custom entity don't forget to modify the subscriber:
- Replace all `Booking` or `booking` by your custom entity name
- In the query near the `where` modify `beginAt` to your custom start date property
- Also when you create each `Event` in the `foreach` modify the getters to fit with your entity
diff --git a/tests/Controller/CalendarControllerTest.php b/tests/Controller/CalendarControllerTest.php
index 302d2e5..86a741a 100755
--- a/tests/Controller/CalendarControllerTest.php
+++ b/tests/Controller/CalendarControllerTest.php
@@ -14,6 +14,7 @@
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
+use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as ContractsEventDispatcherInterface;
class CalendarControllerTest extends TestCase
{
@@ -46,10 +47,18 @@ public function testItProvidesAnEventsFeedForACalendar()
$this->calendarEvent->getEvents()->willReturn([$this->event]);
- $this->eventDispatcher
- ->dispatch(CalendarEvents::SET_DATA, Argument::type(CalendarEvent::class))
- ->willReturn($this->calendarEvent)
- ;
+ $dispatcher = $this->getEventDispatcherMock();
+ if ($dispatcher instanceof ContractsEventDispatcherInterface) {
+ $this->eventDispatcher
+ ->dispatch(Argument::type(CalendarEvent::class), CalendarEvents::SET_DATA)
+ ->willReturn($this->calendarEvent)
+ ;
+ } else {
+ $this->eventDispatcher
+ ->dispatch(CalendarEvents::SET_DATA, Argument::type(CalendarEvent::class))
+ ->willReturn($this->calendarEvent)
+ ;
+ }
$data = json_encode([
[
@@ -85,11 +94,18 @@ public function testItNotFindAnyEvents()
$this->request->get('filters', '{}')->willReturn('{}');
$this->calendarEvent->getEvents()->willReturn([$this->event]);
-
- $this->eventDispatcher
- ->dispatch(CalendarEvents::SET_DATA, Argument::type(CalendarEvent::class))
- ->willReturn($this->calendarEvent)
- ;
+ $dispatcher = $this->getEventDispatcherMock();
+ if ($dispatcher instanceof ContractsEventDispatcherInterface) {
+ $this->eventDispatcher
+ ->dispatch(Argument::type(CalendarEvent::class), CalendarEvents::SET_DATA)
+ ->willReturn($this->calendarEvent)
+ ;
+ } else {
+ $this->eventDispatcher
+ ->dispatch(CalendarEvents::SET_DATA, Argument::type(CalendarEvent::class))
+ ->willReturn($this->calendarEvent)
+ ;
+ }
$data = '';
@@ -105,4 +121,11 @@ public function testItNotFindAnyEvents()
$this->assertEquals($data, $response->getContent());
$this->assertEquals(Response::HTTP_NO_CONTENT, $response->getStatusCode());
}
+
+ private function getEventDispatcherMock()
+ {
+ return $this->getMockBuilder(EventDispatcherInterface::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
}