*/ class GCalender_Service { /** * */ var $_clientLoginUrl = 'https://www.google.com/accounts/ClientLogin'; /** * */ var $_feedUrlFormat = 'http://www.google.com/calendar/feeds/%s/private/full/'; /** * */ var $_authOptions = array( 'Email' => '', 'Passwd' => '', 'source' => MY_USER_AGENT, 'service' => 'cl', ); /** * @param string * @param string * @return void */ function GCalender_Service($email, $passwd) { if ($email != '' && $passwd != '') { $this->_authOptions['Email'] = $email; $this->_authOptions['Passwd'] = $passwd; } else { // ### } } /** * @todo 日付による指定、25件以上になったときの対処 */ function get($email = '') { $url = $this->_getFeedUrl($email); $res = $this->_getHttpContent($url, 'GET', array(), $this->_buildGoogleLoginHeader($this->_getAuthToken())); return $this->_parseEntry($res); } /** * * @param array * @return bool */ function add($data) { $strEntry = $this->_buildEntry($data); $googlelogin = $this->_buildGoogleLoginHeader($this->_getAuthToken()); $url = $this->_getFeedUrl(); $buf = $this->_getHttpContent($url, 'POST', $strEntry, $googlelogin, CONTENT_TYPE_ATOM); $res = $this->_getHttpContent($this->_getRedirectUrl($buf), 'POST', $strEntry, $googlelogin, CONTENT_TYPE_ATOM); if (strpos($res, 'HTTP/1.1 201 Created') === 0) { return true; } else { return false; } } /** * */ function update() { } /** * */ function delete() { } /** * @return mixed */ function _getAuthToken() { $res = $this->_getHttpContent($this->_clientLoginUrl, 'POST', $this->_authOptions); if (preg_match("'Auth=(.*)'", $res, $match)) { return $match[1]; } else { return false; } } /** * */ function _getHttpContent($url, $method, $post_data = array(), $header = '', $post_contenttype = 'application/x-www-form-urlencoded', $connection = 'close') { $pUrl = parse_url($url); if (isset($pUrl['query'])) { $pUrl['query'] = '?' . $pUrl['query']; if (substr($pUrl['query'], -1, 1) == '_') { $pUrl['query'] = str_replace('_', '', $pUrl['query']); // ### GoogleCalendarのバグ?アンダーバーが含まれる場合が } } else { $pUrl['query'] = ''; } $pUrl['port'] = $pUrl['scheme'] == 'https' ? 443 : 80; $request = $method . ' ' . $pUrl['path'] . $pUrl['query'] . " HTTP/1.1\r\n"; $request .= 'Host: ' . $pUrl['host'] . "\r\n"; $request .= 'User-Agent: '.MY_USER_AGENT."\r\n"; $request .= $header; $request .= 'Connection: '."$connection\r\n"; switch ($method) { case 'POST': case 'PUT': $str = ''; if (is_array($post_data)) { foreach ($post_data as $key => $val) { $str .= $key . '=' . urlencode($val) . '&'; } } else { $str = $post_data; } $request .= "Content-Type: $post_contenttype\r\n"; $request .= "Content-Length: ".strlen($str)."\r\n"; $request .= "\r\n"; $request .= $str; break; default: $request .= "\r\n"; break; } $host = $pUrl['scheme'] == 'https' ? 'ssl://' . $pUrl['host'] : $pUrl['host']; $fp = fsockopen($host, $pUrl['port']); if (!$fp) { die("ERROR\n"); // ### } $this->_debug_print("\$request: $request"); fwrite($fp, $request); $response = ''; while (!feof($fp)) { $buf = fgets($fp); $response .= $buf; } fclose($fp); return $response; } /** * Parse atom feed * * @param string * @return array */ function _parseEntry($buf) { $reg = "'.*?/([a-z0-9]+?).*?(.*?)(.*?).*?.*?.*?'"; $c = preg_match_all($reg, $buf, $match); $data = array(); for ($i = 0; $i < $c; $i++) { $t = mktime(0, 0, 0, $match[7][$i], $match[8][$i], $match[6][$i]); $data[] = array('id' => $match[1][$i], 'title' => $match[2][$i], 'content' => $match[3][$i], 'editid' => $match[4][$i], 'where' => $match[5][$i], 'timestamp' => $t); } return $data; } /** * */ function _getFeedUrl($email = '') { $email = ($email == '') ? $this->_authOptions['Email'] : $email; $email = urlencode($email); return sprintf($this->_feedUrlFormat, $email); } /** * */ function _getRedirectUrl($buf) { if (preg_match("'Location: (.*)'", $buf, $match)) { return $match[1]; } else { return false; } } /** * */ function _buildGoogleLoginHeader($authToken) { return 'Authorization: GoogleLogin auth=' . $authToken . "\r\n"; } /** * */ function _buildEntry() { } /** * */ function _debug_print($str) { if (defined('_DEBUG')) { echo $str . "\n"; } } }