Skip to content

Commit

Permalink
Attach ICS file to invitation email
Browse files Browse the repository at this point in the history
  • Loading branch information
yurabakhtin committed Jan 11, 2024
1 parent 2425ba8 commit de92c08
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 44 deletions.
4 changes: 3 additions & 1 deletion config.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use humhub\components\console\Application as ConsoleApplication;
use humhub\components\Application;
use humhub\modules\space\widgets\Menu;
use humhub\modules\user\models\User;
Expand All @@ -21,6 +22,7 @@
'events' => [
['class' => Menu::class, 'event' => Menu::EVENT_INIT, 'callback' => [Events::class, 'onSpaceMenuInit']],
['class' => Application::class, 'event' => Application::EVENT_BEFORE_REQUEST, 'callback' => [Events::class, 'onBeforeRequest']],
['class' => ConsoleApplication::class, 'event' => ConsoleApplication::EVENT_BEFORE_REQUEST, 'callback' => [Events::class, 'onBeforeRequest']],
['class' => ProfileMenu::class, 'event' => ProfileMenu::EVENT_INIT, 'callback' => [Events::class, 'onProfileMenuInit']],
['class' => SpaceSidebar::class, 'event' => SpaceSidebar::EVENT_INIT, 'callback' => [Events::class, 'onSpaceSidebarInit']],
['class' => ProfileSidebar::class, 'event' => ProfileSidebar::EVENT_INIT, 'callback' => [Events::class, 'onProfileSidebarInit']],
Expand All @@ -37,4 +39,4 @@
['class' => User::class, 'event' => User::EVENT_BEFORE_DELETE, 'callback' => [Events::class, 'onUserDelete']],
['class' => 'humhub\modules\rest\Module', 'event' => 'restApiAddRules', 'callback' => [Events::class, 'onRestApiAddRules']],
],
];
];
54 changes: 18 additions & 36 deletions controllers/IcalController.php
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
<?php


namespace humhub\modules\calendar\controllers;

use humhub\components\access\ControllerAccess;
use humhub\components\Controller;
use humhub\modules\calendar\interfaces\CalendarService;
use humhub\modules\calendar\models\CalendarEntry;
use humhub\modules\content\models\Content;
use Yii;
use yii\base\Exception;
use yii\web\HttpException;
use yii\web\NotFoundHttpException;
use humhub\components\Controller;
use humhub\modules\calendar\helpers\CalendarUtils;
use humhub\modules\calendar\helpers\RecurrenceHelper;
use humhub\modules\calendar\interfaces\CalendarService;
use humhub\modules\calendar\interfaces\event\CalendarEventIF;
use humhub\modules\calendar\interfaces\recurrence\RecurrentEventIF;
use humhub\modules\calendar\interfaces\VCalendar;
use humhub\modules\content\models\Content;


class IcalController extends Controller
Expand Down Expand Up @@ -53,57 +48,44 @@ public function init()
*/
public function actionExport($id)
{
$event = $this->getEvent($id);

if(RecurrenceHelper::isRecurrent($event) && !RecurrenceHelper::isRecurrentRoot($event)) {
/* @var $event RecurrentEventIF */
$event = $event->getRecurrenceQuery()->getRecurrenceRoot();
}
$model = $this->getModel($id);

$uid = $event->getUid() ?: $this->uniqueId;
$ics = $model->generateIcs();

return Yii::$app->response->sendContentAsFile(VCalendar::withEvents($event, CalendarUtils::getSystemTimeZone(true))->serialize(), $uid.'.ics', ['mimeType' => static::EXPORT_MIME]);
if (empty($ics)) {
throw new HttpException(400, 'Selected content does not implement calendar interface');
}

}
$uid = $model->getUid() ?: $this->uniqueId;

public function actionGenerateics()
{
$calendarEntry = $this->getCalendarEntry(Yii::$app->request->get('id'));
$ics = $calendarEntry->generateIcs();
return Yii::$app->response->sendContentAsFile($ics, uniqid() . '.ics', ['mimeType' => static::EXPORT_MIME]);
return Yii::$app->response->sendContentAsFile($ics, $uid.'.ics', ['mimeType' => static::EXPORT_MIME]);
}

/**
* @param $id
* @return CalendarEventIF
* @return CalendarEntry
* @throws HttpException
* @throws \Throwable
* @throws Exception
*/
public function getEvent($id)
public function getModel($id)
{
$content = Content::findOne(['id' => $id]);

if(!$content) {
if (!$content) {
throw new NotFoundHttpException();
}

if(!$content->canView()) {
if (!$content->canView()) {
throw new HttpException(403);
}

$model = $content->getModel();

if(!$model) {
if (!$model) {
throw new NotFoundHttpException();
}

$event = CalendarUtils::getCalendarEvent($model);

if(!$event) {
throw new HttpException(400, 'Selected content does not implement calendar interface');
}

return $event;
return $model;
}
}
}
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Changelog
1.5.7 (Unreleased)
--------------------------
- Fix #433: Fix memory usage on integrity check
- Enh #435: Attach ICS file to invitation email

1.5.6 (October 26, 2023)
--------------------------
Expand Down
4 changes: 2 additions & 2 deletions interfaces/VCalendar.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class VCalendar extends Model


/**
* @param CalendarEventIF[] $items
* @param CalendarEventIF|CalendarEventIF[] $items
* @return VCalendar
*/
public static function withEvents($items, $tz = null)
Expand Down Expand Up @@ -364,4 +364,4 @@ public function add($items, bool $initRecurrenceChildren = true)

return $this;
}
}
}
18 changes: 14 additions & 4 deletions models/CalendarEntry.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use humhub\modules\calendar\interfaces\recurrence\AbstractRecurrenceQuery;
use humhub\modules\calendar\interfaces\recurrence\RecurrentEventIF;
use humhub\modules\calendar\interfaces\reminder\CalendarEventReminderIF;
use humhub\modules\calendar\interfaces\VCalendar;
use humhub\modules\calendar\models\participation\CalendarEntryParticipation;
use humhub\modules\calendar\models\recurrence\CalendarEntryRecurrenceQuery;
use humhub\modules\calendar\models\reminder\CalendarReminder;
Expand Down Expand Up @@ -634,11 +635,20 @@ public function getBadge()
return null;
}

public function generateIcs()
public function generateIcs(): ?string
{
$timezone = Yii::$app->settings->get('defaultTimeZone');
$ics = new ICS($this->title, $this->description, $this->start_datetime, $this->end_datetime, null, null, $timezone, $this->all_day);
return $ics;
$event = CalendarUtils::getCalendarEvent($this);

if (!$event) {
return null;
}

if (RecurrenceHelper::isRecurrent($event) && !RecurrenceHelper::isRecurrentRoot($event)) {
/* @var $event RecurrentEventIF */
$event = $event->getRecurrenceQuery()->getRecurrenceRoot();
}

return VCalendar::withEvents($event, CalendarUtils::getSystemTimeZone(true))->serialize();
}

public function afterMove(ContentContainerActiveRecord $container = null)
Expand Down
20 changes: 19 additions & 1 deletion notifications/Invited.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use humhub\modules\calendar\models\CalendarEntry;
use humhub\modules\notification\components\BaseNotification;
use Yii;
use yii\mail\MessageInterface;

/**
* Notification for an invited participant
Expand Down Expand Up @@ -64,4 +65,21 @@ public function getMailSubject()
'contentTitle' => $this->getContentInfo($this->source, false)
]);
}
}

/**
* @inheritdoc
*/
public function beforeMailSend(MessageInterface $message)
{
$ics = $this->source->generateIcs();

if (!empty($ics)) {
$message->attachContent($ics, [
'fileName' => $this->source->getUid() . '.ics',
'contentType' => 'text/calendar'
]);
}

return true;
}
}

0 comments on commit de92c08

Please sign in to comment.