LoginSignup
6

More than 5 years have passed since last update.

GoogelCalendarに連携してFullCalendarでエベントを表示する手順

Last updated at Posted at 2016-10-05

FullCalendarとは

 FullCalendarはオプンソースでエベントを表示するため作られたJavaScriptプラグインです。イメージは以下のようになります。見た目はGoogleカレンダーと似ているものです。

スクリーンショット 2016-10-05 13.12.56.png

導入する手順は以下のリンクに参照してください。

FullCalendar Download

 FullCalendarはすでにGoogleCalendarに連携してエベントを表示するモジュールを持っていますが試してみたらそれはあくまでも自分の公開されているカレンダーのみの表示をサポートしているのは可能です。そういうわけで皆に共有してもらったエベントはGoogleCalendarのサイトでのように表示できないようです。

FullCalendar - Google Calendar

 僕はやりたいのはGmailのシステムアカウントは一つあって皆がこのシステムアカウントに自分のカレンダーを共有してくれて、それでシステムにアクセスすれば共有したカレンダーを統合1画面で全て表示できるようになるのです。インターネットで見つけたソリューションを幾つか試してみましたけれどもやっぱり自ら開発した方がいいと思いますのでGoogleAPIのPHP番を用いていくことにしました

Google Calendar API

Google Calendar APIを用いる策

事前準備

  • GoogleCalendarAPIのPHP番の導入
$php composer.phar require google/apiclient:^2.0
  • 持っているシステムアカウントのGoogle Calendar APIを有効にする
    1. このウィザードに従ってプロジェクトを作成してAPIを有効にする スクリーンショット 2016-10-05 13.58.05.png
    2. 認証情報でOAuth ClientIDの認証情報を作成する スクリーンショット 2016-10-05 14.02.22.png
    3. Web Applicationをアプリケーション種類として指定する  スクリーンショット 2016-10-05 14.03.57.png Authorized redirect URIsは認証した後成功した場合の認証コードあるいは失敗したのエラーメッセージを送る場所を指定するところです。 例: スクリーンショット 2016-10-05 15.27.53.png
    4. Download JSONを押して認証するに必要な情報を一ファイルでまとめてダウンロードする。(例えば:calendar-php-globalhrm.jsonという名前でダウンロードしてProjectのConfigフォルダーの下に置いておいてください)

サーバーサイドのソース

config\ooglecalendar.php
return [
    'application_name' => 'global_hrm',
    'scope' => [
        \Google_Service_Calendar::CALENDAR_READONLY
    ],
    'auth'=> [
        'config' => config_path().'/'.'calendar-php-globalhrm.json',
    ]
];
route.php
    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']);
App\Http\Controllers\GoogleCalendarController.php

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()]);
        }

    }
}

以上、

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
6