mirror of
https://github.com/espocrm/espocrm.git
synced 2026-07-01 08:26:04 +00:00
ics fixes
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
72
application/Espo/Core/Mail/Event/EventFactory.php
Normal file
72
application/Espo/Core/Mail/Event/EventFactory.php
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -349,7 +349,7 @@
|
||||
"index": true
|
||||
},
|
||||
"icsEventDateStart": {
|
||||
"type": "datetime",
|
||||
"type": "datetimeOptional",
|
||||
"readOnly": true,
|
||||
"notStorable": true
|
||||
},
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user