%PDF- %PDF-
Direktori : /home/vacivi36/intranet.vacivitta.com.br/protected/modules/calendar/docs/ |
Current File : /home/vacivi36/intranet.vacivitta.com.br/protected/modules/calendar/docs/interface0.6.md |
# Calendar interface v0.6 Since calendar module version 0.6 it is possible to injecting calendar items into the calendar and snippet. All interface files reside within the `interface` directory of the calendar module. ## Exporting calendar item types A calendar item type can be used to mark your exported calendar item. A meeting module for example can export a `meeting` item type. Exported item types provide a config with the following options: - `title`: A translatable title - `color`: A default color used for this item type, which can be overwritten in the calendar module config - `icon`: Icon related to this event type In order to export one or more item types, your Module has to implement a listener for the `humhub\modules\calendar\interfaces\CalendarService::getItemTypes` event as in the following example. **config.php**: ```php return [ 'id' => 'meeting', 'class' => 'humhub\modules\meeting\Module', 'namespace' => 'humhub\modules\meeting', 'events' => [ //... ['class' => 'humhub\modules\calendar\interfaces\CalendarService', 'event' => 'getItemTypes', 'callback' => ['humhub\modules\meeting\Events', 'onGetCalendarItemTypes']], ], ]; ``` **Event.php:** ```php public static function onGetCalendarItemTypes($event) { $contentContainer = $event->contentContainer; if(!$contentContainer || $contentContainer->isModuleEnabled('meeting')) { $event->addType('meeting', [ 'title' => Yii::t('MeetingModule.base', 'Meeting'), 'color' => static::DEFAULT_COLOR, 'icon' => 'fa-calendar-o' ]); } } ``` > Note: Don't forget to check if your module is enabled on the given `$event->contentContainer`. If no `contentContainer` is given it's meant to be a global search for all available calendar item types. ## Inject calendar items In order to inject calendar items into a calendar you have to implement a listener for `humhub\modules\calendar\interfaces\CalendarService::findItems` as in the following example. **config.php**: ```php return [ //... 'events' => [ //... ['class' => 'humhub\modules\calendar\interfaces\CalendarService', 'event' => 'findItems', 'callback' => ['humhub\modules\meeting\Events', 'onFindCalendarItems']], ], ]; ``` Items are appended by means of `$event->addItems($itemTypeKey, $itemsArray)`. The item array can contain the following values: - `start`: DateTime instance of the start time ideally with timezone (otherwise we assume app timezone). - `end`: DateTime instance of the end time ideally with timezone (otherwise we assume app timezone). - `allDay`: Boolean whether or not the events are all-day events. - `title`: The title of the given item, displayed in the calendar and snippet - `editable`: Whether or not this item is editable (resize/drag/drop) this will also require the updateUrl - `viewUrl`: This link will be loaded into a modal once the item is selected in the calendar - `openUrl`: A link to the actual content (e.g Permalink) used in the snippet - `icon`: An font awesome icon class as for example `fa-bell`, used to prepended an icon to the event dom element - `updateUrl`: A url used to directly update the start/end time in case `editable` is set to true > Note: If you want to add full-day events, you must add a day to the end date and set the time to 00:00:00. The following example demonstrates this: ```php // Example 1: We want to add an one-day all-day event: 01.01.2018 $start = new DateTime('2018-01-01 00:00:00') $end = new DateTime('2018-01-02 00:00:00') // one day longer, but time set to 00:00:00! ``` ```php // Example 2: We want to add a two-day all-day event: 01.01.2018 - 02.01.2018 $start = new DateTime('2018-01-01 00:00:00') $end = new DateTime('2018-01-03 00:00:00') // one day longer, but time set to 00:00:00! ``` **Event.php:** ```php public static function onFindCalendarItems($event) { $contentContainer = $event->contentContainer; if(!$contentContainer || $contentContainer->isModuleEnabled('meeting')) { /* @var $meetings Meeting[] */ $meetings = MeetingCalendarQuery::findForEvent($event); $items = []; foreach ($meetings as $meeting) { $items[] = [ 'start' => $meeting->getBeginDateTime(), 'end' => $meeting->getEndDateTime(), 'title' => $meeting->title, 'editable' => true, 'icon' => 'fa-calendar-o', 'viewUrl' => $meeting->content->container->createUrl('/meeting/index/modal', ['id' => $meeting->id, 'cal' => true]), 'openUrl' => $meeting->content->getUrl(), 'updateUrl' => $meeting->content->container->createUrl('/meeting/index/calendar-update', ['id' => $meeting->id]), ]; } $event->addItems(static::ITEM_TYPE_KEY, $items); } } ``` For filtering out Items which do not match our `$event->filters` we simply have to extend `humhub\modules\calendar\interfaces\AbstractCalendarQuery`. The subclass of this helper should overwrite the follwoing fields: - `recordClass`: a `ActiveRecord` class string used for initializing the query. - `startField`: the name of the database field for the start date - `endField`: the name of the database field for the end date, if there is no explicit end field use the start field - `dateFormat`: the database date format of your date fields In case your model extends `ContentActiveRecord` the query class provides a default implementation for the following filter: - `filterDashboard()`: this special filter function is used for the dashboard upcoming events snippets, by default this filter will make use of the `USER_RELATED_SCOPE_SPACE` and `USER_RELATED_SCOPE_OWN_PROFILE` - `filterGuests()`: used for guest users which are not able to use other filters - `filterUserRelated()`: used for user related queries e.g: 'Only content from following spaces' (see `ActiveQueryContent::userRelated`) - `filterContentContainer()`: used to filter content of a specific ContentContainer (Space/User) - `filterReadable()`: only include content readable by the current user - `filterMine()`: only include items created by me - `setupDateCriteria()`: responsible for the date interval filter, this will only include items where either the start and/or the end date is within a given time range. Some filter have to be implemented manually (in case they are supported): - `filterIsParticipant()`: in case the item type supports an own participation logic, this filter is used to only include items in which the current logged in user participates (optional) - `filterResponded()`: **legacy** filter for filtering out items with no response yet (optional) - `filterNotResponded()`: **legacy** filter for filtering out items with a response (optional) >Note: In case a given filter is not supported the whole event item query will be skipped and will return a empty result. >Note: Guest users are not able to use other filters than the `filterGuests` >Info: Modules can decide which events to include or exclude in the Dashboard snippet by using the `filterDashboard` filter **MeetingCalendarQuery example:** ```php class MeetingCalendarQuery extends AbstractCalendarQuery { protected static $recordClass = Meeting::class; public $startField = 'date'; public $endField = 'date'; public $dateFormat = 'Y-m-d'; /** * @inheritdoc */ public function filterIsParticipant() { $this->_query->leftJoin('meeting_participant', 'meeting.id=meeting_participant.meeting_id AND meeting_participant.user_id=:userId', [':userId' => $this->_user->id]); $this->_query->andWhere('meeting_participant.id IS NOT NULL'); } } ``` ### Allow Drag-Drop and Resize of calendar items If you provide an `updateUrl` and set the `editable` to true, you have to implement a update controller function as the following: **IndexController.php** ```php public function actionCalendarUpdate($id) { $this->forcePostRequest(); $meeting = Meeting::find()->contentContainer($this->contentContainer)->where(['meeting.id' => $id])->one(); if (!$meeting) { throw new HttpException('404'); } if (!($meeting->content->canEdit())) { throw new HttpException('403'); } $meetingForm = new MeetingForm(['meeting' => $meeting]); if ($meetingForm->updateTime(Yii::$app->request->post('start'), Yii::$app->request->post('end'))) { return $this->asJson(['success' => true]); } throw new HttpException(400, "Could not save! " . print_r($meetingForm->getErrors())); } ``` **MeetingForm.php** ```php public function updateTime($start = null, $end = null) { $startDate = new DateTime($start, new DateTimeZone($this->getUserTimeZone())); $endDate = new DateTime($end, new DateTimeZone($this->getUserTimeZone())); Yii::$app->formatter->timeZone = Yii::$app->timeZone; // Note we ignore the end date (just use the time) since a meeting can't span over several days $this->meeting->date = Yii::$app->formatter->asDatetime($startDate, 'php:Y-m-d H:i:s'); $this->meeting->begin = Yii::$app->formatter->asTime($startDate, 'php:H:i:s'); $this->meeting->end = Yii::$app->formatter->asTime($endDate, 'php:H:i:s'); return $this->meeting->save(); } ``` > Note: In the previous example we translate the given date from user timezone to app timezone and then save the item.