ics fixes

This commit is contained in:
Yuri Kuznetsov
2021-08-10 12:52:42 +03:00
parent 973910b837
commit c1936cf46b
5 changed files with 163 additions and 23 deletions

View File

@@ -39,6 +39,7 @@ use Espo\Core\{
FieldProcessing\Loader,
FieldProcessing\LoaderParams,
Mail\Event\Event as EspoEvent,
Mail\Event\EventFactory,
Utils\Log,
};
@@ -84,18 +85,13 @@ class IcsDataLoader implements Loader
return;
}
$valueMap = (object) [];
if ($event->status === 'CANCELLED') {
return;
}
$espoEvent = EspoEvent::create()
->withUid($event->uid ?? null)
->withDateStart($event->dtstart_tz ?? null)
->withDateEnd($event->dtend_tz ?? null)
->withName($event->summary ?? null)
->withLocation($event->location ?? null)
->withDescription($event->description ?? null)
->withTimezone($ical->calendarTimeZone() ?? null)
->withOrganizer($event->organizer ?? null)
->withAttendees($event->attendee ?? null);
$espoEvent = EventFactory::createFromU01jmg3Ical($ical);
$valueMap = (object) [];
try {
$valueMap->name = $espoEvent->getName();
@@ -103,6 +99,12 @@ class IcsDataLoader implements Loader
$valueMap->dateStart = $espoEvent->getDateStart();
$valueMap->dateEnd = $espoEvent->getDateEnd();
$valueMap->location = $espoEvent->getLocation();
$valueMap->isAllDay = $espoEvent->isAllDay();
if ($espoEvent->isAllDay()) {
$valueMap->dateStartDate = $espoEvent->getDateStart();
$valueMap->dateEndDate = $espoEvent->getDateEnd();
}
}
catch (Throwable $e) {
$this->log->warning("Error while converting ICS event '" . $entity->getId() . "': " . $e->getMessage());
@@ -158,6 +160,10 @@ class IcsDataLoader implements Loader
$entity->set('icsEventData', $eventData);
$entity->set('icsEventDateStart', $espoEvent->getDateStart());
if ($espoEvent->isAllDay()) {
$entity->set('icsEventDateStartDate', $espoEvent->getDateStart());
}
}
private function loadCreatedEvent(Entity $entity, EspoEvent $espoEvent, object $eventData): void

View File

@@ -55,10 +55,11 @@ class Event
private $uid = null;
private $isAllDay = false;
public function withAttendees(?string $attendees): self
{
$obj = clone $this;
$obj->attendees = $attendees;
return $obj;
@@ -67,7 +68,6 @@ class Event
public function withOrganizer(?string $organizer): self
{
$obj = clone $this;
$obj->organizer = $organizer;
return $obj;
@@ -76,7 +76,6 @@ class Event
public function withDateStart(?string $dateStart): self
{
$obj = clone $this;
$obj->dateStart = $dateStart;
return $obj;
@@ -85,7 +84,6 @@ class Event
public function withDateEnd(?string $dateEnd): self
{
$obj = clone $this;
$obj->dateEnd = $dateEnd;
return $obj;
@@ -94,7 +92,6 @@ class Event
public function withLocation(?string $location): self
{
$obj = clone $this;
$obj->location = $location;
return $obj;
@@ -103,7 +100,6 @@ class Event
public function withName(?string $name): self
{
$obj = clone $this;
$obj->name = $name;
return $obj;
@@ -112,7 +108,6 @@ class Event
public function withDescription(?string $description): self
{
$obj = clone $this;
$obj->description = $description;
return $obj;
@@ -121,7 +116,6 @@ class Event
public function withTimezone(?string $timezone): self
{
$obj = clone $this;
$obj->timezone = $timezone;
return $obj;
@@ -130,17 +124,29 @@ class Event
public function withUid(?string $uid): self
{
$obj = clone $this;
$obj->uid = $uid;
return $obj;
}
public function withIsAllDay(bool $isAllDay): self
{
$obj = clone $this;
$obj->isAllDay = $isAllDay;
return $obj;
}
public function getUid(): ?string
{
return $this->uid;
}
public function isAllDay(): bool
{
return $this->isAllDay;
}
public function getName(): ?string
{
return $this->name;
@@ -153,7 +159,7 @@ class Event
public function getDateEnd(): ?string
{
return $this->convertDate($this->dateEnd);
return $this->convertDate($this->dateEnd, true);
}
public function getLocation(): ?string
@@ -171,12 +177,26 @@ class Event
return new self();
}
private function convertDate(?string $value): ?string
private function convertDate(?string $value, bool $isEnd = false): ?string
{
if ($value === null) {
return null;
}
if ($this->isAllDay) {
$dt = DateTime::createFromFormat('Ymd', $value);
if ($dt === false) {
throw new RuntimeException("Could not parse '{$value}'.");
}
if ($isEnd) {
$dt->modify('-1 day');
}
return $dt->format(DateTimeUtil::SYSTEM_DATE_FORMAT);
}
$timezone = $this->timezone ?? 'UTC';
$dt = DateTime::createFromFormat('Ymd\THis', $value, new DateTimeZone($timezone));

View File

@@ -0,0 +1,72 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Core\Mail\Event;
use ICal\Event as U01jmg3Event;
use ICal\ICal as U01jmg3ICal;
use RuntimeException;
class EventFactory
{
public static function createFromU01jmg3Ical(U01jmg3ICal $ical): Event
{
/* @var $event U01jmg3Event */
$event = $ical->events()[0] ?? null;
if (!$event) {
throw new RuntimeException();
}
$dateStart = $event->dtstart_tz ?? null;
$dateEnd = $event->dtend_tz ?? null;
$isAllDay = strlen($event->dtstart) === 8;
if ($isAllDay) {
$dateStart = $event->dtstart ?? null;
$dateEnd = $event->dtend ?? null;
}
$espoEvent = Event::create()
->withUid($event->uid ?? null)
->withIsAllDay($isAllDay)
->withDateStart($dateStart)
->withDateEnd($dateEnd)
->withName($event->summary ?? null)
->withLocation($event->location ?? null)
->withDescription($event->description ?? null)
->withTimezone($ical->calendarTimeZone() ?? null)
->withOrganizer($event->organizer ?? null)
->withAttendees($event->attendee ?? null);
return $espoEvent;
}
}

View File

@@ -349,7 +349,7 @@
"index": true
},
"icsEventDateStart": {
"type": "datetime",
"type": "datetimeOptional",
"readOnly": true,
"notStorable": true
},

View File

@@ -32,6 +32,7 @@ namespace tests\unit\Espo\Core\Mail\Event;
use ICal\ICal;
use ICal\Event;
use Espo\Core\Mail\Event\EventFactory;
use Espo\Core\Mail\Event\Event as MailEvent;
class EventTest extends \PHPUnit\Framework\TestCase
@@ -113,6 +114,32 @@ END:VEVENT
END:VCALENDAR
";
private $icsContents3 =
"BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:REQUEST
BEGIN:VEVENT
DTSTART;VALUE=DATE:20210810
DTEND;VALUE=DATE:20210811
DTSTAMP:20210810T091857Z
ORGANIZER;CN=test:mailto:test@group.calendar.google.c
om
UID:4r15namb5v2h4dou58gkfajjbe@google.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;RSVP=
TRUE;CN=test.com;X-NUM-GUESTS=0:mailto:test@test.com
X-MICROSOFT-CDO-OWNERAPPTID:1443094082
CREATED:20210810T091748Z
LAST-MODIFIED:20210810T091856Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:test ics 4
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR";
public function testEvent1(): void
{
$ical = new ICal();
@@ -181,5 +208,20 @@ END:VCALENDAR
"1 Broadway Ave., Brooklyn",
$espoEvent->getLocation()
);
$this->assertFalse($espoEvent->isAllDay());
}
public function testEvent3(): void
{
$ical = new ICal();
$ical->initString($this->icsContents3);
$event = EventFactory::createFromU01jmg3Ical($ical);
$this->assertTrue($event->isAllDay());
$this->assertEquals('2021-08-10', $event->getDateStart());
$this->assertEquals('2021-08-10', $event->getDateEnd());
}
}