Если вы публикуете на сайте анонсы мероприятий и всяких встреч, то не лишним будет добавить кнопку "Добавить в календарь ics". Многие iphone-о-владельцы будут рады парой кликов добавить в свой iCalendar событие, которое хотят посетить или не пропустить.

В работе можно посмотреть на naukapobedit.ru, кнопка "Добавить в календарь".
Итак, в представление добавляем кнопку и ссылку на метод в контроллере, который сгенерирует и выдаст в браузер файл с расширением .ics на скачивание. Я использую виджет GridView, который работает в режиме Pjax. Добавляю кнопку в колонку.
<?= GridView::widget([ ... 'columns' => [ ... [ 'attribute'=>'addtocalendar', 'label' => '', 'headerOptions' => ['width' => '220'], 'format'=>'raw', 'value'=>function ($model, $index, $widget){ if(($model->when_end) == NULL){ return '<div class="dropdown"> <button class=" btn btn-default dropdown-toggle btn-block" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <span class="glyphicon glyphicon-calendar" aria-hidden="true"></span> Добавить в календарь </button> <ul class="dropdown-menu dropdown-menu-right"><li>'. Html::a( 'Добавить в календарь (.ics)', ['event/output', 'id'=>$model->id], [ 'title'=>'Подробнее', 'target'=>'_blank', 'data-pjax'=>0 ] ).' </li></ul> </div>'; } else {return "";} } ], ...
Здесь я добавил кнопку с выпадающим списком, чтобы потом добавить ещё вариант Добавить в Google Calendar. Сейчас говорим только про ical. При нажатии на ссылку из выпадающего списка вызывается метод 'output' в контроллере 'event'. Очень важный параметр 'data-pjax'=>0 - он отменяет режим pjax, иначе браузер отображает содержимое файла .ics, а должен отдавать файл для сохранения пользователем.
Переходим к контроллеру. Там метод output вызывает метод input, и ещё некоторые "махинации" с форматом даты есть. Кто хочет, сделайте код по изящнее.
const DATETIME_FORMAT = 'Ymd\THis';//'Ymd\THis\Z'; public function actionOutput($id) { $model = $this->findModel($id); $ch = curl_init(); //инициализируем сессию и возвращаем ее дескриптор $_csrf = http_build_query(['_csrf'=>$_COOKIE['_csrf']]); $token = http_build_query([ 'when_date'=>$model->when_date, 'when_time'=>$model->when_time, 'who'=>$model->who, 'what'=>$model->what, 'clubname'=>$model->clubName, 'where'=>$model->where, 'link'=>$model->link, '_csrf'=>Yii::$app->request->getCsrfToken()]); curl_setopt($ch, CURLOPT_URL, 'http://naukapobedit.ru/event/input'); //Указываем на какой урл будем передавать данные curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_COOKIE, $_csrf); //Указываем способ передачи данных curl_setopt($ch, CURLOPT_POSTFIELDS, $token ); //Указываем данные, которые будем передавать на сервер curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //Сохранять полученный ответ от сервера будем в переменную //curl_setopt($ch, CURLOPT_HEADER, 1); $output = curl_exec($ch); curl_close($ch); $headers = Yii::$app->response->headers; $headers->set('Content-Disposition', 'attachment;filename="«'.\yii\helpers\Html::encode($model->who.'__'.$model->what).'».ics"'); $headers->set('Content-Type', 'text/calendar;charset=utf-8'); $headers->set('Content-Description: File Transfer'); $headers->set('Cache-Control: public'); header('HTTP/1.0 200 OK', true, 200); Yii::$app->response->sendContentAsFile($output, "«".$model->who."__".$model->what."»".'.ics'); Yii::$app->response->send(); } public function actionInput() { $when_date = $_POST['when_date']; $when_time = $_POST['when_time']; $who = $_POST['who']; $what = $_POST['what']; $clubname = $_POST['clubname']; $location = $_POST['where']; $url = $_POST['link']; $dt = new \DateTime($when_date." ".$when_time, new \DateTimeZone("UTC")); $dt2 = new \DateTime($when_date." ".$when_time, new \DateTimeZone("UTC")); $dtend = $dt2->add(new \DateInterval('PT2H'))->format(self::DATETIME_FORMAT); $dt->createFromFormat('Y-m-d H:i:s', $when_date." ".$when_time); $dtstart = $dt->format(self::DATETIME_FORMAT); $now = new \DateTime(); $dtstamp = $now->format(self::DATETIME_FORMAT); return $ical = "BEGIN:VCALENDAR PRODID:-//Naukapobedit//NONSGML Naukapobedit //RU VERSION:2.0 METHOD:PUBLISH BEGIN:VEVENT UID:" . md5(uniqid(mt_rand(), true)). " DTSTART:".$dtstart." DTEND:".$dtend." DTSTAMP:".$dtstamp." SUMMARY:".$who.": ".$what." DESCRIPTION:".$clubname." LOCATION:".$location." URL:".$url." END:VEVENT END:VCALENDAR "; }
12 сентября 2018, Программирование, веб-кодинг / Метки: календарь

