LoginSignup
4
5

More than 1 year has passed since last update.

PHPで各種カレンダーへの予定追加機能を実装する

Last updated at Posted at 2022-03-03

はじめに

イベント予約時にカレンダーへの予定追加を可能とする機能を実装する機会があり学習したのでまとめる。
カレンダーへの予定追加の方法としては以下2通り。

①icsファイルのダウンロード
②パラメーターを含んだリンクの設置(Googleカレンダー、Yahoo!カレンダー、Outlook)

※Outlookのみパラメーターを利用すると一部不備があるため、実際にはicsファイルのダウンロードとした。

尚、icsファイルの書き方自体は他にもたくさん記事があるため詳細については割愛し、PHPでの実装時の流れや詰まった点、パラメーターの種類について主に記載していく。

icsファイルとは

カレンダーにインポートすると記載された内容でカレンダーに登録される。
Googleカレンダー、Outlookなどにインポート可能。(Yahoo!カレンダーは不可)
iCalendarはicsファイルを開くと自動的にカレンダーへの追加画面となる。
特徴は以下。

  • MIMEタイプは「text/calendar」
  • 拡張子は「.ics」
  • 中身はプレーンテキストで、文字コードはutf-8が標準で用いられる。

ファイルの中身は以下のように特殊な形式となっている。

BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//A company//X product//NONSGML v1.0//JP
BEGIN:VEVENT
DTSTART;TZID=Asia/Tokyo:20220302T173000
DTEND;TZID=Asia/Tokyo:20220302T201000
SUMMARY:タイトル
DESCRIPTION:詳細
END:VEVENT
END:VCALENDAR

上から簡単に見ていく。

BEGIN

これはicsファイルを作成する上でのお作法のようなものだ。
4行目のBEGIN:VEVENTも同じで、ここからカレンダーですよ〜、ここからイベントですよ〜と示すためのもので、下のENDとそれぞれ対になっている。

VERSION

現状では特に気にせず2.0を指定すれば良い。

PRODID

作成者の情報を記載する。
決まったフォーマットはなく、「-//会社名//個人名(プロダクト名)//国名」がよく用いられる形式のようだ。

DTSTART;TZID / DTEND;TZID

予定の開始・終了日時。
yyyymmddThhmmss形式となる。
ISO8601で定められたフォーマットで、間の"T"はセパレータというものらしくとにかく必須。

SUMMARY

予定のタイトル。

DESCRIPTION

予定の詳細。
改行も可能。※後述

上に挙げたのはあくまで設定項目の一例で、他にもアラームの設定など可能となる。
ここでは他の項目について言及しないので、気になる場合は別の記事を探していただくことをオススメする。

PHPでicsファイルのダウンロード機能を実装する

まずはicsファイルをダウンロードするためのリンクを設置する。

views/calendar.blade.php
<a href="/addCalendar/{{ $id }}">

続いて、Controller側でicsファイルを生成していく。
ざっと中身を見ていただくと以下のようになる。

Controller/Calendar.php
public function addCalendar(Request $request)
{
	$headers = array(
		'Content-Type' => 'text/calendar',
        'Content-Disposition' => 'attachment; filename=calendar.ics',
    );

                             ## 中略 ##

    $description = "カレンダーへの予定追加機能について".¥¥r¥¥n."icsファイルとパラメーター形式"//後述

    $fp = fopen('php://temp', 'w+b');
	$text = 
	   	"BEGIN:VCALENDAR\r\n".
	    "VERSION:2.0\r\n".
    	"PRODID:-//".config('custom.paramater.company_name')."/".config('custom.paramater.site_name')."//NONSGML v1.0//JP\r\n".
		"BEGIN:VEVENT\r\n".
	   	"DTSTART;TZID=Asia/Tokyo:".$seminarStart->format('Ymd').'T'.$seminarStart->format('His')."\r\n".
    	"DTEND;TZID=Asia/Tokyo:".$seminaEnd->format('Ymd').'T'.$seminarEnd->format('His')."\r\n".
		"SUMMARY:".$title."\r\n".
	   	"DESCRIPTION:".$description."\r\n".
	    "END:VEVENT\r\n".
	    "END:VCALENDAR\r\n";
	fwrite($fp, $text);
	rewind($fp);
	$ics = stream_get_contents($fp);
	fclose($fp);
	return Response::make($ics, 200, $headers);

なんとなく概要を掴んでいただいた上で、手順を分けて記載していく。(ざっくり分けると2つの手順のみ)

①headerを指定する

初めにダウンロードするファイルのheaderを指定する。
前述の通り、Content-Typetext/calendarとする。

Content-TypeContent-Disposition、またこれから記載するファイルそのものの生成方法(icsファイルに限らず)についてはこちらに記載しているので、そちらを確認していただけると幸いです。

②icsファイルの中身を作成する

変数$textにicsファイルの中身をテキストとして格納し、それをtempファイルに書き込んでいく。
そしてそれをダウンロードできる形式にしてブラウザに返してやる、というのが本当にざっくりした流れだ。
タイトルや日時指定をし、予定概要にただ一行の文を記載すれば良いのであればこれで完了になる。

ただし予定概要の部分(DESCRIPTION)を改行したいのであれば、少し注意が必要だ。
実際この部分で手間取り時間を食ってしまった。

やり方としては、変数の中で改行されるような形にしてそれを当て込むというやり方が良い。
仮に以下のようにして改行をしようとするとうまくいかない。

$text = 
	         ## 中略 ##
	   	"DESCRIPTION:カレンダーへの予定追加機能について"."\r\n"."icsファイルとパラメーター形式"."\r\n".
	    "END:VEVENT\r\n".
	         ## 中略 ##

おそらくこの場合、「カレンダーへの予定追加機能について」で改行され次の行の頭が「icsファイルとパラメーター形式」となるが、icsファイル内のキー(DESCRIPTIONなど)として認識されてしまいエラーとなるのだと思う。
そのため、$descriptionという変数の中で改行をしている。

そしてもう一つ気をつけるのが、変数内の改行部分を同じように¥r¥nとすると、結局変数を当て込んだときに改行処理が走ってしまい、上記と同じことになってしまう。

$description = "カレンダーへの予定追加機能について".¥r¥n."icsファイルとパラメーター形式" //変数$textの中で改行処理が走ってしまう

そこで、改行コード前にバックスラッシュをつけることで、$textの中で改行されないようにする必要がある。
よって以下のようにすると正しく改行されて予定に反映される。

$description = "カレンダーへの予定追加機能について".¥¥r¥¥n."icsファイルとパラメーター形式" //変数$textの中で改行処理が走らず、icsファイル展開時に改行処理が走る

パラメーターを使用した各種カレンダー追加

icsファイルのダウンロードとは異なり、リンクを踏むとそのリンクに該当するカレンダーの予定追加画面に自動で遷移する方式だ。
以下リンクから一度試していただけるとイメージがつくと思う。

Googleカレンダー

Yahoo!カレンダー

Outlook

※前置きしたようにOutloolのみ一部不備?があり、一度目にリンクを踏んだ際のみ文字化けしてしまう。(二度目以降は正しく表示)

このように、カレンダーごとにパラメーターが指定されており、そこに値を入れることでカレンダーへの予定追加が可能となる。
カレンダーごとのパラメーターは以下。
基本となるURLに続けてパラメーターをカスタマイズして作成可能。

▼Googleカレンダー

基本URL
http://www.google.com/calendar/event?action=TEMPLATE&

パラメーター 説明
text タイトル
dates 開始日時/終了日時
details 予定の詳細
location 場所
add 招待するメールアドレス

その他のパラメーターが気になる方はこちら
https://interactiondesignfoundation.github.io/add-event-to-calendar-docs/services/google.html

上記サイト最下部にgeneratorなるものがあり、これを使うとリンクを自動生成してくれるらしい、、、便利。
http://kalinka.tardate.com/
http://output.jsbin.com/xujuluw

▼Yahoo!カレンダー

基本URL
https://calendar.yahoo.co.jp/?V=60&

パラメーター 説明
TITLE タイトル
ST 開始日時
ET 終了日時
DUR 予定の時間
IN_LOC 場所
DESC 予定の詳細
ENC 文字コード
URL URL

その他のパラメーターが気になる方はこちら
https://interactiondesignfoundation.github.io/add-event-to-calendar-docs/services/yahoo.html

▼Outlook

基本URL
https://outlook.live.com/owa/?path=/calendar/action/compose&

※Outlookのみ日時のフォーマットが異なる

パラメーター 説明
subject タイトル
body 予定の詳細
location 場所
startdt 開始日時(yyyy-mm-ddTH:i:s)
enddt 終了日時(yyyy-mm-ddTH:i:s)
to 出席者のメールアドレス
allday 終日(値はtrue / false)

以上のようにして、各種カレンダーへの予定追加機能を実装する。
今までにない実装経験だったのでシンプルにおもしろかった。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5