#FullCalendarとは
FullCalendarはオプンソースでエベントを表示するため作られたJavaScriptプラグインです。イメージは以下のようになります。見た目はGoogleカレンダーと似ているものです。
導入する手順は以下のリンクに参照してください。
FullCalendarはすでにGoogleCalendarに連携してエベントを表示するモジュールを持っていますが試してみたらそれはあくまでも自分の公開されているカレンダーのみの表示をサポートしているのは可能です。そういうわけで皆に共有してもらったエベントはGoogleCalendarのサイトでのように表示できないようです。
>FullCalendar - Google Calendar
僕はやりたいのはGmailのシステムアカウントは一つあって皆がこのシステムアカウントに自分のカレンダーを共有してくれて、それでシステムにアクセスすれば共有したカレンダーを統合1画面で全て表示できるようになるのです。インターネットで見つけたソリューションを幾つか試してみましたけれどもやっぱり自ら開発した方がいいと思いますのでGoogleAPIのPHP番を用いていくことにしました
#Google Calendar APIを用いる策
##事前準備
- GoogleCalendarAPIのPHP番の導入
$php composer.phar require google/apiclient:^2.0
- 持っているシステムアカウントのGoogle Calendar APIを有効にする
- このウィザードに従ってプロジェクトを作成してAPIを有効にする
- 認証情報でOAuth ClientIDの認証情報を作成する
- Web Applicationをアプリケーション種類として指定する
Authorized redirect URIsは認証した後成功した場合の認証コードあるいは失敗したのエラーメッセージを送る場所を指定するところです。
例:
- Download JSONを押して認証するに必要な情報を一ファイルでまとめてダウンロードする。(例えば:calendar-php-globalhrm.jsonという名前でダウンロードしてProjectのConfigフォルダーの下に置いておいてください)
- このウィザードに従ってプロジェクトを作成してAPIを有効にする
サーバーサイドのソース
return [
'application_name' => 'global_hrm',
'scope' => [
\Google_Service_Calendar::CALENDAR_READONLY
],
'auth'=> [
'config' => config_path().'/'.'calendar-php-globalhrm.json',
]
];
Route::get('calendar/google' , ['as'=>'api.calendar.google', 'uses'=>'GoogleCalendarController@googleCalendar']);
/*
* Google API Consoleで指定したURLと一緒
*/
Route::get('calendar/access_token' , ['as'=>'api.calendar.access_token', 'uses'=>'GoogleCalendarController@accessToken']);
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Config;
class GoogleCalendarController extends Controller
{
private static $client = null;
private static $service = null;
/*
* 認証された後GoogleAPIサービスが認証結果を指定したリダイレクトURIの後ろにつけて返す
* 成功の場合:認証コードを返す
* 失敗の場合:失敗した理由をメッセージで返す
*/
public function accessToken(Request $request){
//ログアウトの場合
if ($request->has('logout')){
$request->session()->forget('google_access_token');
return json_encode(['succcess'=>true,'message'=>'User has been logged out.']);
}
//認証は成功でしたのでcodeをSessionに保存しておく
if ($request->has('code')){
$authCode = $request->input('code');
$request->session()->put('authentication_code', $authCode);
/*
* route("api.calendar.google")
*/
return redirect()->route("api.calendar.google");
}else{
//失敗の場合は失敗理由を受け取ってCallerへ返す
return json_encode(['succcess'=>true,'message'=>$request->input('error')]);
}
}
/*
* Clientのインスタンスを生成する
*/
private function getGoogleCalendarClient(Request $request) {
//初期化でアクセス情報を指定する
if (null === self::$client) {
self::$client = new \Google_Client();
self::$client->setApplicationName(Config::get('googlecalendar.application_name'));
$scope = implode(' ', Config::get('googlecalendar.scope'));
self::$client->setScopes($scope);
self::$client->setAuthConfig(Config::get('googlecalendar.auth.config')); //GoogleConsoleで生成したファイルを指定する
self::$client->setRedirectUri(route('api.calendar.access_token'));
self::$client->setAccessType('offline');
self::$client->setApprovalPrompt('force');
}
$client = self::$client;
//AccessTokenを持っている場合に
if ($request->session()->has('google_access_token')) {
//有効期限は切られたかどうかの確認
if ($client->isAccessTokenExpired()) {
//google_refresh_tokenは一回目の認証で返してもらえる。二回目からは返したaccesstokenに入れないのでSessionに保存するのは必須
$refreshToken = $request->session()->get('google_refresh_token');
$client->fetchAccessTokenWithRefreshToken($refreshToken);
$request->session()->put('google_access_token', json_encode($client->getAccessToken()));
}
return array('auth'=>true,'client'=>$client);
}else{
//authentication_codeのみを持っている時コードからaccesstokenに変換するのは必要です
if($request->session()->has('authentication_code')){
$authCode= $request->session()->get('authentication_code');
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$refreshToken = $accessToken['refresh_token'];
//ここだけでrefresh_tokenを取れるので保存しておく。
$request->session()->put('google_access_token', json_encode($accessToken));
$request->session()->put('google_refresh_token', $refreshToken);
$client->setAccessToken($accessToken);
$client->refreshToken($refreshToken);
$request->session()->forget('authentication_code');
}else{
//認証されていない場合は認証するページを生成して返す
$authUrl = $client->createAuthUrl();
return array('auth'=>false,'url'=>$authUrl);
}
}
}
public function googleCalendar(Request $request){
try{
$result = $this->getGoogleCalendarClient($request);
// Everything is ok
if ($result['auth'] == true){
if (null === self::$service) {
self::$service = new \Google_Service_Calendar($result['client']);
}
$service = self::$service;
if($request->has('calendar_id')){
$calendarId = $request->input('calendar_id');
}else{
$calendarId = 'primary';
}
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => TRUE,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
if (count($results->getItems()) == 0) {
$events = array();
} else {
$events = array();
//FullCalendarがわかる形に変換する
foreach ($results->getItems() as $item) {
$event = array();
$event['id'] = $item->getID();
$event['title'] = $item->getSummary();
/*
* Start Date
*/
$start = $item->start->dateTime;
if (empty($start)) {
$start = $item->start->date;
}
$event['start'] = $start;
/*
* End Date
*/
$end = $item->end->dateTime;
if (empty($start)) {
$end = $item->end->date;
}
if($start==$end)
$event['allDay'] = true;
else
$event['allDay'] = false;
$event['start'] = $start;
$event['end' ] = $end;
$event['backgroundColor'] = "#f56954";//red
$event['borderColor'] = "#f56954"; //red
$event['url'] = $item->gethtmlLink();
$events[] = $event;
}
//return redirect()->to(self::$sourceUrl)->with('events', $events);
}
//eventsをそのままFullCalendarに渡せば表示してもらうはず
return json_encode(['success'=>true,'redirect'=>false, 'events'=>$events]);
}else{
//return redirect()->to($result['url']);
//認証するページへの移動は必要
return json_encode(['success'=>true,'redirect'=>true,'url'=>$result['url']]);
}
}catch(Exception $e){
return json_encode(['success'=>false, 'message'=>$e->getMessage()]);
}
}
}
以上、