画面仕様
ユーザ情報入力画面

ユーザー情報入力画面は、Googleカレンダーとtoodledoのユーザー情報入力と同期実行ボタンを持つ画面。
利用方法
Googleカレンダーのユーザ名とパスワードには、Googleにログインするときのユーザ名とパスワードを入力します。
Google認証はOAuth2になりました。(2014.12.16)
Googleカレンダーのマイカレンダーには、Googleカレンダーで作ったマイカレンダーの名前を入力します。

ToododoのUnique ID には、Toodledoの設定画面で表示される Unique IDを入力します。

初めて同期ボタンを押すと、同期システムの初期化を行います。このときはまだ、イベントの同期は行われていません。
Googleカレンダーのマイカレンダーにイベントを登録したり、すでにあるイベントを変更してから、再び同期ボタンを押すと、Toodledoでそのイベントを見ることができます。逆にToodledoでイベントを登録したり変更してから同期ボタンを押すと、Googleカレンダーのマイカレンダーにイベントが登録されます。
ToodledoからGoogleカレンダーの終日イベントを登録する場合は、イベントのStart Date / Timeの時刻を空欄で登録します。
同期項目

画面イベント機能仕様
ユーザ情報入力画面のイベント機能を説明する。
ユーザ情報入力画面
「同期」ボタンクリックイベント
Googleカレンダーとtoodledoの入力済みユーザ名とパスワードを、Googleカレンダーについてはマイカレンダー名をAPIに送る。
- toodledoの認証に問題がある場合は、そのむねメッセージを画面に表示する。
- マイカレンダー名がGoogleカレンダーに見つからない場合は、その旨メッセージを画面に表示する。
- それぞれのAPIからイベント情報を入手し相互に同期させる。
- いずれか、または両者の認証に問題がある場合は、そのむねメッセージを画面に表示する。
「popupwindow」アンカークリックイベント
「同期ポップアップ画面」を表示する。
このとき、Googleカレンダーとtoodledoのユーザ情報をpostメソッドで「同期ポップアップ画面」に渡す。
Googleカレンダーに対する初期動作
以下の操作はユーザプログラムからの操作方法が不明であるため機能仕様に含めないことにする。
当該サービスから初めて同期オペレーションを行ったさい、Googleカレンダーに対し以下のカレンダー名のカレンダー追加をGoogleログインアカウントに実行する。
toodledoカレンダーは、toodledoイベントとの同期カレンダーとして利用される。
完了toodledoは、toodledoの完了イベントを登録する。
イベント新規登録
- Googleカレンダーからイベントを新規登録した場合、toodledoイベントにフォルダーを未指定、同期するイベント要素以外すべてデフォルトの値で新規登録する。
- toodledoからイベントを新規登録した場合、Googleカレンダーイベントに、同期するイベント要素を設定したイベントを新規登録する。
イベント削除
当該サービスはイベントの削除を行わない。
イベントを削除したい場合、ユーザーはGoogledoカレンダーとtoodledoそれぞれのサービスアプリケーションでイベントを削除すること。
Googleカレンダーないしtoodledoの片方のみからイベントを削除した場合、当該サービスの同期オペレーションによって新規イベントに同期してしまうので注意すること。
変更の競合
Googleカレンダーイベントの変更と、toodledoイベントの変更に競合が発生した場合、いずれか過去の変更を破棄する。
保存情報
当該サービスアプリケーションが保存する情報を記載する。(全てtoodledoアカウント毎に保存する)
- 最終同期日時。
- GoogleカレンダーイベントUIDとtoodledoイベントUIDのマッピング情報(CSV形式)
マッピング情報の削除は、toodledoイベント側で完了となったイベントを対象とする。
イベント操作内容
更新イベントの取得
- Googleカレンダーサービスより、最終同期日時以降に更新されたGoogleカレンダーイベント一覧「Googleカレンダー更新イベント一覧」を取得する。
- 「Googleカレンダー更新イベント一覧」の各イベントについて「Googleカレンダー更新イベント操作」を実施する。
- toodledoサービスより、最終同期日時以降に更新されたtoodledoイベント一覧「toodledo更新イベント一覧」を取得する。
- 「Toodledoイベント更新イベント一覧」の各イベントについて「Toodledo更新イベント操作」を実施する。
Googleカレンダー更新イベント操作
- GoogleカレンダーイベントUIDがマッピング情報に未登録の場合、
当該イベントUIDをマッピング情報に記載する(toodledoイベントUIDは空)。さらにカレンダーイベントの同期項目をToodledoイベントに設定してToodledoイベントを追加する。いじょうで、当該操作を終了する。
- GoogleカレンダーイベントUIDにマッピングされているToodledoイベントUIDをマッピング情報から取得し、当該ToodledoイベントUIDをキーにToodledoイベントをToodledoのAPIから取得する。
- 取得したToodledoイベントの更新日がGoogleカレンダーイベントの更新日より未来である場合、そのまま現状を維持し当該操作を終了する。
- Googleカレンダーイベントの同期項目をToodledoイベントに設定しToodledoイベントを更新。当該捜査を終了する。
Toodledo更新イベント操作
- Toodledoイベントの「状態」が「完了」である場合、そのまま現状を維持し当該操作を終了する。
- ToodledoイベントUIDがマッピング情報に未登録の場合、
当該イベントUIDをマッピング情報に記載し(GoogleカレンダーイベントUIDは空)当該操作を終了する。
- GToodledoイベントUIDにマッピングされているGoogleカレンダーイベントUIDをマッピング情報から取得し、当該GoogleカレンダーイベントUIDをキーにGoogleカレンダーイベントをGoogleカレンダーのAPIから取得する。
- 取得したGoogleカレンダーイベントの更新日がToodledoイベントの更新日より未来である場合、そのまま現状を維持し当該操作を終了する。
- Toodledoイベントの同期項目をGoogleカレンダーイベントに設定しGoogleカレンダーイベントを更新。当該捜査を終了する。
APIエラー時の挙動
Googleカレンダーないしtoodledoがエラーを返却した場合の挙動を纏める。
- イベント毎の同期はその時点で中断する。
- すでに同期しているイベントについてはロールバックせず同期を有効とする。
- 最終同期日時の更新はしない。
- 画面に中断理由を表示する。
最終同期日時を更新しないことで、次回の同期ですでに同期済みのイベントも同期の対象となるが、同期済みを同期しても特にデータが変わることはないので問題ない。
イベントを手動削除後同期を行った場合の挙動
機能仕様が曖昧なので、以下の通りの検証を行うこととする。
状態 |
結果 |
確認日 |
カレンダーのイベントを手動で削除した直後、同期を行う。 |
カレンダー及びタスク画面に変化はない。 |
|
カレンダーのイベントを手動で削除し、
これに紐尽くタスクイベントに変更を加えた後、同期を行う。 |
削除したカレンダーイベントが復活する。 |
|
タスクのイベントを手動で削除した直後、同期を行う |
カレンダー及びタスク画面に変化はない。 |
|
タスクのイベントを手動で削除し、
これに紐尽くカレンダーイベントに変更を加えた後、同期を行う。 |
削除したタスクイベントが復活する。 |
|
カレンダーのイベントと、これに紐尽くタスクのイベントを
手動で削除した後、同期を行う。 |
カレンダーおよびタスク画面に
削除されたタスクは表示されない。 |
|
意外な注意事項
toodledoイベントの追加編集にて開始日(startdate)にUNIXタイムスタンプを指定しても、時刻部分は破棄されてしまう。
実装調査
Googleカレンダー:マイカレンダー一覧を取得する
ソースコード(閉じる)
$service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Calendar($client);
|
$listFeed= $service->getCalendarListFeed();
echo $listFeed[0]->Title;
|
指定日以降に更新されたイベントをセレクトする。
詳細(閉じる)
Googleカレンダーから指定日以降に更新されたイベントをセレクトする。
検証用基点イベント
TITLE |
updated |
startdatetime |
|
いい感じ |
2013-11-24T02:26:14.000Z |
2013.11.24 20:00 |
|
終日だね |
2013-11-24T02:26:15.000Z |
2013.11.24 00:00 |
|
外出 |
2013-11-23T04:09:14.000Z |
2013.11.23 14:00 |
|
過去 |
2013-11-24T02:49:20.000Z |
2013.11.23 09:00 |
|
終日 |
2013-11-23T08:46:26.000Z |
2013.11.23 00:00 |
|
2013年11月23日4時9分14秒から15秒の間に更新されたイベントを抽出する。
$service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$service = new Zend_Gdata_Calendar($client);
|
query = $service->newEventQuery();
$query->setUpdatedMin('2013-11-23T04:09:14');
$query->setUpdatedMax('2013-11-23T04:09:15');
$eventFeed = $service->getCalendarEventFeed($query);
|
Toodledoから指定日以降に更新されたイベントをセレクトする。
title |
modified |
|
|
サラダ菜 |
2011-08-28 10:29:18 |
|
|
Todo のヘルプを入手 |
2011-08-28 05:43:22 |
|
|
2011年8月28日5時43分22秒以降(指定時含まず)に更新されたイベントを取得する。
$obj = new Toodledo($userid, $password, $appid);
$result = $obj->request('getTasks',array('end'=>2,'modafter'=>'2011-08-28 05:43:22'), Toodledo::RAW);
|
イベントを追加する
実装(閉じる)
Googleカレンダーにイベントを追加する
マイカレンダーの名前からイベント登録URIを生成する(呑みこみ不足故、
サンプル丸呑み)
- マイカレンダーの名前から当該マイカレンダーのインデックス番号をGoogleカレンダーに問い合わせる。
- マイカレンダーのインデックス番号から、当該マイカレンダーの識別文字列を取得する。
- マイカレンダーの識別文字列を使って、イベント登録URIを作成する
1. |
$listFeed= $service->getCalendarListFeed();
$index = 0;
foreach ($listFeed as $calendar) {
if ($calendar->title == $name) {
break;
}
$index ++;
}
|
2. |
$listFeed= $service->getCalendarListFeed();
$i = 0;
foreach ($listFeed as $calendar) {
if ($i == $index) {
// カレンダーリストのidの取得
$listId = $calendar->id;
// カレンダーのユーザーID取得
$uid = substr($listId, strrpos($listId, "/") + 1);
break;
}
$i ++;
}
return $uid;
|
3. |
$postUri = "http://www.google.com/calendar/feeds/" . $uid . "/private/full";
|
イベントの内容をイベント登録URIに追加する。
$event= $service->newEventEntry(); // 空新規イベントインスタンス
$event->title = $service->newTitle($title); // 新規イベントのタイトル
$event->content = $service->newContent($content); // 新規イベントのメモ
$tzOffset = "+09";
$when = $service->newWhen(); // 空開始終了日時インスタンス
$when->startTime = "{$startDate}T{$startTime}:00.000{$tzOffset}:00";
$when->endTime = "{$endDate}T{$endTime}:00.000{$tzOffset}:00";
$event->when = array($when);
$service->insertEvent($event,"http://www.google.com/calendar/feeds/" . $user . "/private/full")
|
Toodledoにイベントを追加する
http://www.toodledo.com/info/api_doc_tasks.php
http://api.toodledo.com/api.php?method=addTask;key=YourKey;
title=new years;priority=1;repeat=0;length=30;duedate=2010-01-01
$taskInfo = array(
'title' => 'たんたいてすとによる',
'note' => 'めもめも',
'startdate' => '2013-12-30',
'starttime' => '12:34 am',
'duedate' => '2013-12-30',
'duetime' => '4:56 pm'
);
$result = $obj->request('addTask', $taskInfo, Toodledo::RAW);
print_r($result);
|
$result
<?xml version="1.0" encoding="UTF-8"?>
<added>213992551</added>
|

イベントを変更する
詳細(閉じる)
Googleカレンダーのイベントを変更する[TASK(private)]
$service = Zend_Gdata_Calendar::AUTH_SERVICE_NAME;
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
$this->service = new Zend_Gdata_Calendar($client);
|
$this->_googleCalendar->setTargetEvent($eventId);
$this->_googleCalendar->updateEvent(
'タイトル替えちゃったyo',
'メモも買えちゃったyo',
'2013-12-28 13:00',
'2013-12-28 14:00'
);
|
/**
* 編集イベントを設定する
* @param $eventId
*/
public function setTargetEvent($eventId)
{
$this->_targetEvent = $this->getEventFromId($eventId);
}
|
/**
* イベントIDからイベントオブジェクトを取得する
* @param unknown $eventId
*/
public function getEventFromId($eventId)
{
//Zendライブラリオブジェクトで渡されるケースに対応
$sEventId = sprintf("%s", $eventId);
try {
$event = $this->_service->getCalendarEventEntry($sEventId);
} catch (Zend_Gdata_App_Exception $e) {
$this->exceptionErrorMessage = $e->getMessage();
return FALSE;
}
return $event;
}
|
/**
* イベントを変更する
* @param unknown $title
* @param unknown $memo
* @param unknown $startDateTime
* @param string $endDateTime
*/
public function updateEvent(
$title,
$memo,
$startDateTime,
$endDateTime = ''
){
$this->_targetEvent->title = $this->_service->newTitle($title);
$this->_targetEvent->content = $this->_service->newContent($memo);
$when = $this->_createWhen($startDateTime,$endDateTime);
$this->_targetEvent->when = array($when);
try {
$this->_targetEvent->save();
} catch (Zend_Gdata_App_Exception $e) {
$this->exceptionErrorMessage = $e->getMessage();
return FALSE;
}
return TRUE;
}
|
/**
* イベントに設定する開始終了日時オブジェクトを生成する
* @param unknown $startDateTime YYYY-MM-DD HH:SS
* @param string $endDateTime YYYY-MM-DD HH:SS
* @return unknown
*/
protected function _createWhen(
$startDateTime,
$endDateTime=''
){
//開始日時($startDateTime)、終了日時($endDateTime)
// を、日付と時刻に分離。さらに時刻が無ければ終日フラグを設定
$this->_createStartDateTimeEndDateTime(
$startDate,
$startTime,
$endDate,
$endTime,
$allDayFlg,
$startDateTime,
$endDateTime);
$when = $this->_service->newWhen();
$tzOffset = "+09";
if ($allDayFlg == TRUE) {
$when->startTime = "{$startDate}";
$when->endTime = "{$endDate}";
} else {
$when->startTime = "{$startDate}T{$startTime}:00.000{$tzOffset}:00";
$when->endTime = "{$endDate}T{$endTime}:00.000{$tzOffset}:00";
}
return $when;
}
|
/**
* 開始日時($startDateTime)、終了日時($endDateTime)
* を、日付と時刻に分離。さらに時刻が無ければ終日フラグを設定
* @param unknown $startDate
* @param unknown $startTime
* @param unknown $endDate
* @param unknown $endTime
* @param unknown $allDayFlg
* @param unknown $startDateTime
* @param string $endDateTime
* @return boolean
*/
protected function _createStartDateTimeEndDateTime(
&$startDate,
&$startTime,
&$endDate,
&$endTime,
&$allDayFlg,
$startDateTime,
$endDateTime=''
){
if (!self::validDateTime($startDateTime)) {
return FALSE;
}
if ($endDateTime != '') {
if (!self::validDateTime($endDateTime)) {
return FALSE;
}
}
$allDayFlg = FALSE;
/*** 開始と終了が同じ日時の場合は登録しない */
if ($startDateTime == $endDateTime) {
return FALSE;
}
/*** 終日判定 */
if (strlen($startDateTime) == strlen('YYYY-MM-DD')) {
$allDayFlg = TRUE;
$startDate = $startDateTime;
/*** 翌日作成 */
$baseDate = str_replace('-', '', $startDate).'0000';
$objDateMath = new DateMath($baseDate);
$objDateMath->getDateAfterDays(1);
$endDate = ''
. $objDateMath->iResultYear
. '-'
. $objDateMath->iResultMonth
. '-'
. $objDateMath->iResultDay;
}
/*** 開始終了時刻初期化 */
$startTime = '00:00';
$endTime = '01:00';
/*** 日/時分割 */
if (!$allDayFlg) {
$divide = explode(' ', $startDateTime);
$startDate = $divide[0];
$startTime = $divide[1];
$divide = explode(' ', $endDateTime);
$endDate = $divide[0];
$endTime = $divide[1];
}
return TRUE;
}
|
Toodledoのイベントを変更する[TASK(private)]
$taskInfo = array(
'id' => '214034545',
'title' => 'たんたいてすとによるを変更',
'note' => 'めもめもも変更',
'startdate' => '2013-12-29',
'starttime' => '12:34 pm',
'duedate' => '2013-12-30',
'duetime' => '10:56 pm'
);
$result = $this->_toodledo->request('editTask', $taskInfo, Toodledo::RAW);
|

同期処理方式
Googleカレンダー/toodledo同期サービスの処理方法を記載する。
- 最終同期日時保存ファイルを読み込む
- 最終同期保存ファイルが存在しない場合、システム日時を最終同期日時とする。
- 最終同期日時保存ファイルにシステム日時を保存する。
- 前述の「イベント操作内容」にしたがい、Googleカレンダー更新イベント操作およびToodledo更新イベント操作を行う。
以上
情報記録方式
Googleカレンダー/toodledo同期サービスが独自に保存する情報の記録方式を記載する。
最終同期日時
{YYYY-MM-DD}T{HH:mm:ss}
Googleカレンダー用フォーマット:2013-11-23T04:09:14
toodle用フォーマット:2011-08-28 05:43:22
イベントマップ
{GoogleカレンダーイベントID},{toodledoイベントID}
ToodledoアプリケーションID隠蔽方式
ソースコードを公開するので、ToodledoのアプリケーションIDの設定アルゴリズムも白日となる。
アプリケーションIDをファイルに埋め込んだ場合、そのファイルの所在がプログラムを解説することで容易に知ることができる。
サーバーのデフォルトの設定では、場所がわかれば "http://../場所" でブラウザでそこに記載された内容を表示することができる。
もちろん、アクセスコントロールファイルを変更すれば表示できなくなる。しかし、変更が初期化されるリスクは高い。
そこで、サーバの設定を変えることなくアプリケーションIDを隠蔽するため以下の方式をとる。
登録ファイル名
|
appid.php |
フォーマット |
<?php
//start-data
//toodlede-appid,{アプリケーションID} |
読み込み方法
|
テキストファイルとして読み込む
「//start-data」の次の行から、CSV解析を行う。 |
解析アルゴリズム |
$appConf = flie('appid.php');
$index = array_search('//start-data', $appConf);
$elements = explode(",", $appConf[$index]);
$appId = $elements[1];
|
この方式により、ブラウザで「http://../appid.php」にアクセスしても、白紙が表示されるだけとなる。
test evidence
表示(閉じる)
Todoイベントリストエビデンス
0件
Array
(
[@attributes] => Array
(
[num] => 0
[total] => 0
[start] => 0
[end] => 1000
)
)
|
2件
Array
(
[@attributes] => Array
(
[num] => 2
[total] => 2
[start] => 0
[end] => 1000
)
[task] => Array
(
[0] => Array
(
[id] => 208651389
[parent] => 0
[children] => 0
[title] => ほしい鞄
[tag] => 買い物
[folder] => 1914315
[context] => 出かけたい場所
[goal] => ストレス解消
[added] => 2013-10-26
[modified] => 2013-12-31 03:52:18
[startdate] => 2013-12-31
[duedate] => Array
(
[@attributes] => Array
(
[modifier] =>
)
)
[duetime] => Array
(
)
[starttime] => Array
(
)
[reminder] => 0
[completed] => Array
(
)
[repeat] => 0
[rep_advanced] => Array
(
)
[status] => 5
[star] => 0
[priority] => 0
[length] => 0
[timer] => 0
[note] => https://www.evernote.com/shard/s89/sh/fdd29ba0-3d2f-4f8e-a8f6-5cbebe3baff8/c470710aaf619cdbb8aff8fe0e91ea2dsoreda
)
[1] => Array
(
[id] => 210360366
[parent] => 0
[children] => 0
[title] => 寝床検討
[tag] => 思考
[folder] => 1914315
[context] => 場所を問わずできる
[goal] => 健康維持
[added] => 2013-11-14
[modified] => 2013-12-31 03:52:03
[startdate] => 2013-12-31
[duedate] => Array
(
[@attributes] => Array
(
[modifier] =>
)
)
[duetime] => Array
(
)
[starttime] => Array
(
)
[reminder] => 0
[completed] => Array
(
)
[repeat] => 0
[rep_advanced] => Array
(
)
[status] => 3
[star] => 0
[priority] => 2
[length] => 0
[timer] => 0
[note] => koreda
)
)
)
|
1件
count($task)とした場合、1を期待するものの実際には24が帰ってくる(連想配列の数)
Array
(
[@attributes] => Array
(
[num] => 1
[total] => 1
[start] => 0
[end] => 1000
)
[task] => Array
(
[id] => 210360366
[parent] => 0
[children] => 0
[title] => 寝床検討
[tag] => 思考
[folder] => 1914315
[context] => 場所を問わずできる
[goal] => 健康維持
[added] => 2013-11-14
[modified] => 2013-12-31 03:55:53
[startdate] => 2013-12-31
[duedate] => Array
(
[@attributes] => Array
(
[modifier] =>
)
)
[duetime] => Array
(
)
[starttime] => Array
(
)
[reminder] => 0
[completed] => Array
(
)
[repeat] => 0
[rep_advanced] => Array
(
)
[status] => 3
[star] => 0
[priority] => 2
[length] => 0
[timer] => 0
[note] => koredaよ
)
)
|
Array
(
[num] => 1
[total] => 1
[start] => 0
[end] => 1000
[task] => Array
(
[0] => Array
(
[id] => 208651389
[parent] => 0
[children] => 0
[title] => ほしい鞄
[tag] => 買い物
[folder] => 1914315
[context] => Array
(
[id] => 976351
[_content] => 出かけたい場所
)
[goal] => Array
(
[id] => 299346
[_content] => ストレス解消
)
[added] => 2013-10-26
[modified] => 2014-01-01 04:10:51
[startdate] => 2014-01-31
[duedate] => Array
(
[modifier] =>
[_content] => 2014-01-31
)
[duetime] => 1:00 pm
[starttime] => 12:30 pm
[reminder] => 0
[completed] =>
[repeat] => 0
[rep_advanced] =>
[status] => 5
[star] => 0
[priority] => 0
[length] => 30
[timer] => Array
(
[onfor] => 0
[_content] => 0
)
[note] => https://www.evernote.com/shard/s89/sh/fdd29ba0-3d2f-4f8e-a8f6-5cbebe3baff8/c470710aaf619cdbb8aff8fe0e91ea2d
soreda
)
)
)
|
カレンダーイベントリストエビデンス
Array
(
[0] => Array
(
[ID] => Zend_Gdata_App_Extension_Id Object
(
[_rootElement:protected] => id
[_rootNamespace:protected] => atom
[_rootNamespaceURI:protected] =>
[_extensionElements:protected] => Array
(
)
[_extensionAttributes:protected] => Array
(
)
[_text:protected] => http://www.google.com/calendar/feeds/0rhh763d7t49tfnn28bgkuj5lg%40group.calendar.google.com/private/full/rjulqtl9f9uuh8nggep0oqpgj8
[_namespaces:protected] => Array
(
[atom] => Array
(
[1] => Array
(
[0] => http://www.w3.org/2005/Atom
)
)
[app] => Array
(
[1] => Array
(
[0] => http://purl.org/atom/app#
)
[2] => Array
(
[0] => http://www.w3.org/2007/app
)
)
)
)
[NAME] => Zend_Gdata_App_Extension_Title Object
(
[_rootElement:protected] => title
[_type:protected] => text
[_rootNamespace:protected] => atom
[_rootNamespaceURI:protected] =>
[_extensionElements:protected] => Array
(
)
[_extensionAttributes:protected] => Array
(
)
[_text:protected] => 散歩&検討inスマホ
[_namespaces:protected] => Array
(
[atom] => Array
(
[1] => Array
(
[0] => http://www.w3.org/2005/Atom
)
)
[app] => Array
(
[1] => Array
(
[0] => http://purl.org/atom/app#
)
[2] => Array
(
[0] => http://www.w3.org/2007/app
)
)
)
)
[START_TIME] => 1388552400
[END_TIME] => 1388556000
[ALLDAY] => 1
[UPDATED] => Zend_Gdata_App_Extension_Updated Object
(
[_rootElement:protected] => updated
[_rootNamespace:protected] => atom
[_rootNamespaceURI:protected] =>
[_extensionElements:protected] => Array
(
)
[_extensionAttributes:protected] => Array
(
)
[_text:protected] => 2014-01-01T10:04:46.000Z
[_namespaces:protected] => Array
(
[atom] => Array
(
[1] => Array
(
[0] => http://www.w3.org/2005/Atom
)
)
[app] => Array
(
[1] => Array
(
[0] => http://purl.org/atom/app#
)
[2] => Array
(
[0] => http://www.w3.org/2007/app
)
)
)
)
[CONTENT] => Zend_Gdata_App_Extension_Content Object
(
[_rootElement:protected] => content
[_src:protected] =>
[_type:protected] => text
[_rootNamespace:protected] => atom
[_rootNamespaceURI:protected] =>
[_extensionElements:protected] => Array
(
)
[_extensionAttributes:protected] => Array
(
)
[_text:protected] => やったよね
[_namespaces:protected] => Array
(
[atom] => Array
(
[1] => Array
(
[0] => http://www.w3.org/2005/Atom
)
)
[app] => Array
(
[1] => Array
(
[0] => http://purl.org/atom/app#
)
[2] => Array
(
[0] => http://www.w3.org/2007/app
)
)
)
)
)
)
|
WEB動作でToodledoがエラーになるので
$method getTasks
$params Array [4]
end 2
modafter 1389528065
unix 1
$url http://api.toodledo.com/api.php?method=getTasks;end=2;modafter=1389528065;unix=1;key=26a0c6f7ffa64ee685394e24dd76840f
=====
$url http://api.toodledo.com/api.php?method=getTasks;end=2;modafter=1389529811;unix=1;key=26a0c6f7ffa64ee685394e24dd76840f
$token td52d2550563a29
td52d2550563a29
key 26a0c6f7ffa64ee685394e24dd76840f
26a0c6f7ffa64ee685394e24dd76840f
getの
$params Array [3]
end 2
modafter 2013-12-28 05:43:22
unix 1
$params Array [2]
modafter 1389528065
unix 1
Exceptionが苦手なのでエラーリターンに変更
ToodledoAPIのオープンソースでは、APIから期待しないレスポンスがあるとExceptionを発行している。
これらを全て、エラーメッセージテキストを設定してのエラーリターンに変更する。
表示(閉じる)
オリジナル |
変更 |
メンバー変数/定数------> |
public $exeptionMessage = '';
const EXERROR_EMPTY_RESPONCE = ''Empty response'';
const EXERROR_INVALID_RESPONCE = 'Invalid response while getting token';
|
public function request($method, $params=array(), $output=self::DEFAULT_RETURN){
if (!empty($this->key)) $params['key'] = $this->key;
$url = self::APIURL . 'method='.$method . (!empty($params) ? ';' . http_build_query($params, '', ';') : '');
$string = file_get_contents($url);
if (empty($string))
throw new Exception('Empty response');
if ($output === self::RAW)
return $string;
// Wrap with <response> so outer-most wrapper is accesible with $xml->foo
if (substr($string,0,2) === '<?' && ($pos=strpos($string,'?>')) !== false && $pos < strpos($string, '<', 1))
$string = substr_replace($string, '<response>', $pos+2, 0) . '</response>';
else
$string = '<response>' . $string . '</response>';
$xml = new SimpleXMLElement($string);
$error = $xml->error;
if (!empty($error))
throw new Exception((string)$error);
if ($output === self::ARR)
return self::simplexml2array($xml);
return $xml;
}
|
$this->exceptionMessage=EXERROR_EMPTY_RESPONCE;
return FALSE; |
$this->exceptionMessage=(string)$error;
return FALSE;
|
protected function getToken($userid, $appid=null) {
$cache_path = $this->_cacheDir . '/toodledo.token.' . $userid;
if (file_exists($cache_path) && filemtime($cache_path) >= time() - self::TOKENCACHETIME) // 3.5 hours
return file_get_contents($cache_path);
$params = array('userid'=>$userid);
if (!empty($appid)) $params['appid'] = $appid;
$response = $this->request('getToken', $params, self::XML);
$token = $response->token;
if (empty($token))
throw new Exception('Invalid response while getting token');
$token = (string)$token;
file_put_contents($cache_path, $token);
return $token;
} |
$this->exceptionMessage=EXERROR_INVALID_RESPONCE;
return FALSE; |
ソースコードリスト
http://pear.php.net/manual/ja/package.xml.xml-serializer.php
https://hariushi-lib.googlecode.com/svn/trunk/DateMath.php
https://hariushi-lib.googlecode.com/svn/trunk/Google/Calendar.php
https://hariushi-lib.googlecode.com/svn/trunk/Math.php
https://hariushi-lib.googlecode.com/svn/trunk/Request/Request.php
https://hariushi-lib.googlecode.com/svn/trunk/Session.php
https://hariushi-lib.googlecode.com/svn/trunk/Toodledo/api/Toodledo.php
https://task-shoot-calendar.googlecode.com/svn/trunk/application/configs/application.ini
https://task-shoot-calendar.googlecode.com/svn/trunk/application/controllers/ErrorController.php
https://task-shoot-calendar.googlecode.com/svn/trunk/application/controllers/IndexController.php
https://task-shoot-calendar.googlecode.com/svn/trunk/application/models/AuthController.php
https://task-shoot-calendar.googlecode.com/svn/trunk/application/models/EventmapController.php
https://task-shoot-calendar.googlecode.com/svn/trunk/application/views/scripts/index/index.phtml
https://task-shoot-calendar.googlecode.com/svn/trunk/application/views/scripts/index/index2.phtml
https://task-shoot-calendar.googlecode.com/svn/trunk/application/views/scripts/index/mini.phtml
https://task-shoot-calendar.googlecode.com/svn/trunk/application/views/scripts/index/wait.phtml
https://task-shoot-calendar.googlecode.com/svn/trunk/public/include_path_env.php
https://task-shoot-calendar.googlecode.com/svn/trunk/public/index.php
マジックワードメソッドの改修
ソースコード公開に当たり、toodledoのアプリケーションIDを隠蔽するために設置されたマジックワードメソッドについての説明です。
IndexController::syncAction() の
$appid = Models_EventmappController::getAppIdToodledo();
はマジックワードメソッドの呼び出しです。これを
$appid = あなたが取得したアプリケーションコード;
としてください。
[TOP]|[編集]|[新規] [TASK(PRIVATE)]
Last-modified: ※作成中