2010年12月30日木曜日

CodeIgniterでGoogleCalendarAPIのテスト(2)

さてちょっと時間が空いてしまいましたがGoogleCalendarAPIをCI上から利用してカレンダー機能にアクセスはほぼ実装が終わりました。そのあとjsなどをいじっていたので更新が遅くなってしまった訳ですが各機能についてご紹介したいと思います。

前回IBMのサンプルをそのまま用いてカレンダーの予定からタイトルやサマリを取得した訳ですがサマリだとちょっと見づらいので取得する情報をbasicからfullへと変更し各情報の詳細を取得出来るように変更しました。

public function getCalendarEntryList() {

 try{
  $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
  $client =Zend_Gdata_ClientLogin::getHttpClient($this->user, $this->pass, $gcal);
  $gcal = new Zend_Gdata_Calendar($client);

  $query = $gcal->newEventQuery();
  $query->setUser('default');
  $query->setVisibility('private');
  $query->setProjection('full');
  $query->setOrderby('starttime');

  $feed=$gcal->getCalendarEventFeed($query);

  $data['title'] = (string)$feed->title;
  $data['totalResults'] = (String)$feed->totalResults;

  $events = array();
  foreach ($feed as $event) {
   $obj = new stdClass;

   $obj->title = $event->title;

   $when = $event->when;
   $obj->when = date('Y/n/j',strtotime($when[0]->getStartTime()));
   $obj->startTime = date('G:i',strtotime($when[0]->getStartTime()));
   $obj->endTime = date('G:i',strtotime($when[0]->getEndTime()));

   $reminders = $when[0]->reminders;
   if (count($reminders)!=0) {
    foreach ($reminders as $reminder) {
     if ($reminder->getMethod()=='email') {
      $obj->reminder_email = $reminder->getMinutes();
     } else {
      $obj->reminder_alert = $reminder->getMinutes();
     }
    }
   }
   $obj->content = $event->content;
   $obj->edit_key = $event->id;

   $where = $event->where;
   $obj->where = $where[0]->getValueString();

   $events[] = $obj;
  }

  $data['events'] = $events;
 }catch(Exception $e){
  echo "エラー:".$e->getMessage();
 }

 return $data;
}

ソースをご覧頂くとEventQuery生成部分でbasicがfullに変更されているのがおわかり頂けるかと思います。またforeach文の中で各種詳細データを取得しているのが前回との変更点です。

詳細データの取得に関して注意が必要なところは「when」「reminders」そして「where」等の情報はイベントデータ内に配列として保持されている点です。基本的にwhenやwhereは1つだけ保持していると思われるので$when[0]等で決め打ちでアクセスしてしまっています。またリマインダについてはGoogleカレンダー上では複数登録することが出来ますが今回はメールとアラートもしくはメール+アラートという3つの選択肢から選択し設定時間は1つだけ保持できる仕様としております。

続いては削除メソッドです。

public function deleteEntry() {
 try {
  $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
  $client =Zend_Gdata_ClientLogin::getHttpClient($this->user, $this->pass, $gcal);
  $gcal = new Zend_Gdata_Calendar($client);

  $edit_key = $this->input->post('edit_key', TRUE);
  if (isset($edit_key)) {
   $event = $gcal->getCalendarEventEntry('http://www.google.com/calendar/feeds/default/private/full/'.$edit_key);
   $event->delete();
  }
 }catch(Exception $e){
  echo "エラー:".$e->getMessage();
 }
}

イベントエントリに含まれているidを使って個別EventEntryを取得してdelete()メソッドを実行するだけで削除が可能です。Contactsの時はeditキーを送っていましたがZFの実装がこのようになっています。これはなんなく実装できました。

次は登録メソッドを見てみたいと思います。

public function add_entry() {
 try {
  $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
  $client =Zend_Gdata_ClientLogin::getHttpClient($this->user, $this->pass, $gcal);
  $gcal = new Zend_Gdata_Calendar($client);

  $dates = explode('/', $this->input->post('when', TRUE));
  $stimes = explode(':', $this->input->post('start_time', TRUE));
  $etimes = explode(':', $this->input->post('end_time', TRUE));
  date_default_timezone_set('Asia/Tokyo');
  $stime = date(DATE_RFC3339, mktime($stimes[0],$stimes[1],0,$dates[1],$dates[2],$dates[0]));
  $etime = date(DATE_RFC3339, mktime($etimes[0],$etimes[1],0,$dates[1],$dates[2],$dates[0]));

  $event = $gcal->newEventEntry();
  $event->title = $gcal->newTitle($this->input->post('title', TRUE));
  $when = $gcal->newWhen();
  $when->startTime = $stime;
  $when->endTime = $etime;
  if (isset($_POST['reminder_cbox'])) {
   $time = $this->input->post('reminder_time', TRUE);
   $method = $this->input->post('reminder', TRUE);
   $reminders = array();
   switch ($method) {
    case 'm':
     $reminder = $gcal->newReminder();
     $reminder->method = "email";
     $reminder->minutes = $time;
     $reminders[] = $reminder;
     break;
    case 'p':
     $reminder = $gcal->newReminder();
     $reminder->method = "alert";
     $reminder->minutes = $time;
     $reminders[] = $reminder;
     break;
    case 'mp':
     $reminder = $gcal->newReminder();
     $reminder->method = "email";
     $reminder->minutes = $time;
     $reminders[] = $reminder;
     $reminder = $gcal->newReminder();
     $reminder->method = "alert";
     $reminder->minutes = $time;
     $reminders[] = $reminder;
     break;
   }
   $when->reminders = $reminders;
  }
  $event->when = array($when);
  $event->where = array($gcal->newWhere($this->input->post('where', TRUE)));
  $event->content = $gcal->newContent($this->input->post('content', TRUE));

  $newEvent = $gcal->insertEvent($event);
 }catch(Exception $e){
  echo "エラー:".$e->getMessage();
 }
}

この部分はわりと苦労しました。日時をRFC3339形式にして送らないといけませんがこれはphpのdate()メソッドが対応してくれていますので$_POSTから取得した日時データをexplode()メソッドでバラして生成しています。冒頭で書いたようにリマインダについては「メールのみ」「ポップアップのみ」そして「メールとポップアップ併用」という3種類を選択可能とし時間は1つだけ指定できる仕様のためこのような実装になっています。「when」「reminders」そして「where」についてはしっかりと配列で渡してあげることをお忘れなく。これを忘れるとエラーとなります。

また各種データについてZF側でインスタンス生成メソッドが用意されているのでそのメソッドを利用してデータを登録しています。xmlを生成していたContactsに比べてとても楽チンになっているので助かりました。いや…逆にメソッドを調べるのが大変だったかも?(笑

最後にデータ修正です。

public function correct_entry() {
 try {
  $gcal = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
  $client =Zend_Gdata_ClientLogin::getHttpClient($this->user, $this->pass, $gcal);
  $gcal = new Zend_Gdata_Calendar($client);

  $dates = explode('/', $this->input->post('when', TRUE));
  $stimes = explode(':', $this->input->post('start_time', TRUE));
  $etimes = explode(':', $this->input->post('end_time', TRUE));
  date_default_timezone_set('Asia/Tokyo');
  $stime = date(DATE_RFC3339, mktime($stimes[0],$stimes[1],0,$dates[1],$dates[2],$dates[0]));
  $etime = date(DATE_RFC3339, mktime($etimes[0],$etimes[1],0,$dates[1],$dates[2],$dates[0]));

  $event = $gcal->getCalendarEventEntry($this->input->post('edit_key', TRUE));
  $event->title = $gcal->newTitle($this->input->post('title', TRUE));
  $when = $gcal->newWhen();
  $when->startTime = $stime;
  $when->endTime = $etime;
  if (isset($_POST['reminder_cbox'])) {
   $time = $this->input->post('reminder_time', TRUE);
   $method = $this->input->post('reminder', TRUE);
   $reminders = array();
   switch ($method) {
    case 'm':
     $reminder = $gcal->newReminder();
     $reminder->method = "email";
     $reminder->minutes = $time;
     $reminders[] = $reminder;
     break;
    case 'p':
     $reminder = $gcal->newReminder();
     $reminder->method = "alert";
     $reminder->minutes = $time;
     $reminders[] = $reminder;
     break;
    case 'mp':
     $reminder = $gcal->newReminder();
     $reminder->method = "email";
     $reminder->minutes = $time;
     $reminders[] = $reminder;
     $reminder = $gcal->newReminder();
     $reminder->method = "alert";
     $reminder->minutes = $time;
     $reminders[] = $reminder;
     break;
   }
   $when->reminders = $reminders;
  }
  $event->when = array($when);
  $event->where = array($gcal->newWhere($this->input->post('where', TRUE)));
  $event->content = $gcal->newContent($this->input->post('content', TRUE));

  $event->save();
 }catch(Exception $e){
  echo "エラー:".$e->getMessage();
 }
}

内容については登録時とほぼ同じですがeditキーを使ってEventEntryを取得しその内容を書き換えてsave()メソッドで登録しております。ここで注意が必要なのが削除時や個別イベントデータ取得時に利用するidとデータ修正を行うeditキーは別のデータということです。

IBMのサンプルはbasicでデータを取得しているためこの違いには言及していませんでしたが以下のxmlデータをご覧ください。

<atom:id>http://www.google.com/calendar/feeds/default/private/full/57a84t1b243radd31209erdd9k≷/atom:id>
<atom:link href="http://www.google.com/calendar/event?eid=NTdhODR0MWIyNDNyYWRkMzEyMDllcmRkOWtfMjAxMDEyMjdUMDIzMDAwWiB0ZXN0LmthZXBhcGFAbQ" rel="alternate" type="text/html" title="alternate"/>
<atom:link href="http://www.google.com/calendar/feeds/default/private/full/57a84t1b243radd31209erdd9k" rel="self" type="application/atom+xml"/>
<atom:link href="http://www.google.com/calendar/feeds/default/private/full/57a84t1b243radd31209erdd9k/63429101549" rel="edit" type="application/atom+xml"/>

最後のeditだけ数字のデータが付加されているのがおわかり頂けるかと思います。このデータを渡してあげないとデータ修正は上手くいかずエントリの先頭のデータが書き換えられてしまったりしましたのでご注意ください。

さて実際のブラウザでの表示も掲載しておきたいと思います。


こんな具合にイベントのタイトルと時間、説明と場所が表示されリマインダについてはアイコン表示にしてあります。下の削除と編集リンクからそれぞれの機能が利用できて一番下の「新しいイベントを追加」で新規イベント登録が出来ます。最下段の検索機能についてはまだ実装しておりません。この後実装予定です。


上記はイベントの登録と修正に利用するフォームです。日時と時間の入力はjqueryを利用して入力補助をしています。またリマインダについてはチェックを入れるとセレクトフォームが表示されデータ登録が可能となります。いや…jsで遊んでみたかったんです。jqueryを使うととっても楽にいろいろと出来るようになりますねぇ。もっと勉強しないと!

0 件のコメント:

コメントを投稿