powered by nequal
Home » Services_MixiAPI » Timeline » 589

Diffs

Services_MixiAPI/trunk/sample/mixi_station221.php

@@ -0,0 +1,137 @@
+<?php
+/**
+ * 「ログインできません」になるけど、WSSE認証のコードイメージは
+ * こんな感じ。Services_Hatenaでもやってる。
+ *
+ * @see http://www.kiske.info/blog/archives/2007/04/phpatomapi.html
+ * @see http://catbot.net/blog/2006/02/services_hatena_php.html
+ */
+error_reporting(E_ALL);
+require_once 'HTTP/Request.php';
+
+//$user = '[mixiのログインID]';
+//$pass = '[mixiのパスワード]';
+//$id = '[mixiのユーザーID]';
+$user = getenv('SERVICES_MIXI_USER');
+$pass = getenv('SERVICES_MIXI_PWD');
+$id = getenv('SERVICES_MIXI_ID');
+if (!$user) {
+    die('user is not set');
+}
+if (!$pass) {
+    die('password is not set');
+}
+if (!$id) {
+    die('id is not set');
+}
+
+
+function execute($user, $pass, $url, $is_debug = false) {
+    $nonce = pack('H*', sha1(md5(time().rand().posix_getpid())));
+    $created = date('Y-m-d\TH:i:s') . 'Z';
+    $digest = base64_encode(pack('H*', sha1($nonce . $created . $pass)));
+    $wsse_header = sprintf('UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"', $user, $digest, base64_encode($nonce), $created);
+    if ($is_debug) {
+        var_dump($wsse_header);
+    }
+
+    $request = new HTTP_Request($url);
+    $request->addHeader('X-WSSE', $wsse_header);
+
+    if (PEAR::isError($request->sendRequest())) {
+        die('request failed');
+    }
+    $response = $request->getResponseBody();
+    if ($is_debug) {
+        var_dump($response);
+        echo '<hr>';
+    }
+
+    $xml = new SimpleXMLElement($response);
+    return $xml;
+}
+
+$xml = execute($user, $pass, 'http://mixi.jp/atom/tracks/r=2/member_id=' . $id);
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    $updated_iso8601 = $entry->updated;
+
+    $updated = date('Y/m/d H:i:s', mktime(substr($updated_iso8601, 11, 2),
+                                          substr($updated_iso8601, 14, 2),
+                                          substr($updated_iso8601, 17, 2),
+                                          substr($updated_iso8601, 5, 2),
+                                          substr($updated_iso8601, 8, 2),
+                                          substr($updated_iso8601, 0, 4)
+                                          ));
+    printf(
+        '<li><a href="%s" title="%sさん">%s</a>さん (%s)</li>',
+        $entry->link->href,
+        $entry->author->name,
+        $entry->author->name,
+        $updated
+    );
+}
+echo '</ul>';
+echo '<hr>';
+
+/**
+ * マイミク一覧
+ */
+$xml = execute($user, $pass, 'http://mixi.jp/atom/friends/r=1/member_id=' . $id);
+
+
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    printf(
+        '<li><a href="%s" title="%sさん (%s)">%s</a>さん (%s)</li>',
+        $entry->link[0]['href'],
+        $entry->title,
+        $entry->category['label'],
+        $entry->title,
+        $entry->category['label']
+    );
+}
+echo '</ul>';
+echo '<hr>';
+
+/**
+ * マイミク日記、コミュニティなど最新更新一覧
+ */
+$xml = execute($user, $pass, 'http://mixi.jp/atom/updates/r=1/member_id=' . $id);
+
+
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    switch ($entry->category['term']) {
+    case 'diary':
+        printf('<li>%s</li>', $entry->content);
+        break;
+    case 'comment':
+    case 'album':
+    case 'video':
+        printf(
+            '<li><a href="%s" title="%s">%s</a> (<a href="%s" title="%s">%s</a>さんの%s)</li>',
+            $entry->link['href'],
+            $entry->title,
+            $entry->title,
+            $entry->author->url,
+            $entry->author->name,
+            $entry->author->name,
+            $entry->category['label']
+        );
+        break;
+    case 'bbs':
+        printf(
+            '<li><a href="%s" title="%s">%s</a> (「<a href="%s" title="%s">%s</a>」の%s)</li>',
+            $entry->link['href'],
+            $entry->title,
+            $entry->title,
+            $entry->author->url,
+            $entry->author->name,
+            $entry->author->name,
+            $entry->category['label']
+        );
+        break;
+    default:
+    }
+}

Services_MixiAPI/trunk/sample/test.php

@@ -0,0 +1,121 @@
+<?php
+error_reporting(E_ALL);
+require_once '../Services/MixiAPI/Factory.php';
+
+//$user = '[mixiのログインID]';
+//$pass = '[mixiのパスワード]';
+//$id = '[mixiのユーザーID]';
+$user = getenv('SERVICES_MIXI_USER');
+$pass = getenv('SERVICES_MIXI_PWD');
+$id = getenv('SERVICES_MIXI_ID');
+if (!$user) {
+    die('user is not set');
+}
+if (!$pass) {
+    die('password is not set');
+}
+if (!$id) {
+    die('id is not set');
+}
+
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_FOOTPRINT,
+               $user, $pass, $id);
+$service->execute();
+$xml = new SimpleXMLElement($service->get());
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    $updated_iso8601 = $entry->updated;
+
+    $updated = date('Y/m/d H:i:s', mktime(substr($updated_iso8601, 11, 2),
+                                          substr($updated_iso8601, 14, 2),
+                                          substr($updated_iso8601, 17, 2),
+                                          substr($updated_iso8601, 5, 2),
+                                          substr($updated_iso8601, 8, 2),
+                                          substr($updated_iso8601, 0, 4)
+                                          ));
+    printf(
+        '<li><a href="%s" title="%sさん">%s</a>さん (%s)</li>',
+        $entry->link['href'],
+        $entry->author->name,
+        $entry->author->name,
+        $updated
+    );
+}
+echo '</ul>';
+echo '<hr>';
+
+/**
+ * マイミク一覧
+ */
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_MYMIXI,
+               $user, $pass, $id);
+$service->execute();
+$xml = new SimpleXMLElement($service->get());
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    printf(
+        '<li><a href="%s" title="%sさん (%s)">%s</a>さん (%s)</li>',
+        $entry->link[0]['href'],
+        $entry->title,
+        $entry->category['label'],
+        $entry->title,
+        $entry->category['label']
+    );
+}
+echo '</ul>';
+echo '<hr>';
+
+/**
+ * マイミク日記、コミュニティなど最新更新一覧
+ */
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_WHATSNEW,
+               $user, $pass, $id);
+$service->execute();
+$xml = new SimpleXMLElement($service->get());
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    switch ($entry->category['term']) {
+    case 'diary':
+        $updated_iso8601 = $entry->updated;
+
+        $updated = date('Y/m/d H:i:s', mktime(substr($updated_iso8601, 11, 2),
+                                              substr($updated_iso8601, 14, 2),
+                                              substr($updated_iso8601, 17, 2),
+                                              substr($updated_iso8601, 5, 2),
+                                              substr($updated_iso8601, 8, 2),
+                                              substr($updated_iso8601, 0, 4)
+                                              ));
+        printf('<li>%s %s</li>', $entry->content, $updated);
+        break;
+    case 'comment':
+    case 'album':
+    case 'video':
+        printf(
+            '<li><a href="%s" title="%s">%s</a> (<a href="%s" title="%s">%s</a>さんの%s)</li>',
+            $entry->link['href'],
+            $entry->title,
+            $entry->title,
+            $entry->author->url,
+            $entry->author->name,
+            $entry->author->name,
+            $entry->category['label']
+        );
+        break;
+    case 'bbs':
+        printf(
+            '<li><a href="%s" title="%s">%s</a> (「<a href="%s" title="%s">%s</a>」の%s)</li>',
+            $entry->link['href'],
+            $entry->title,
+            $entry->title,
+            $entry->author->uri,
+            $entry->author->name,
+            $entry->author->name,
+            $entry->category['label']
+        );
+        break;
+    default:
+    }
+}

Services_MixiAPI/trunk/sample/sample_test.php

@@ -0,0 +1,124 @@
+<?php
+ini_set("include_path", dirname(__FILE__)."/src/" . PATH_SEPARATOR . ini_get("include_path"));
+require_once "Services/MixiAPI/Factory.php";
+
+error_reporting(E_ALL);
+
+//$user = '[mixiのログインID]';
+//$pass = '[mixiのパスワード]';
+//$id = '[mixiのユーザーID]';
+$user = getenv('SERVICES_MIXI_USER');
+$pass = getenv('SERVICES_MIXI_PWD');
+$id = getenv('SERVICES_MIXI_ID');
+if (!$user) {
+    die('user is not set');
+}
+if (!$pass) {
+    die('password is not set');
+}
+if (!$id) {
+    die('id is not set');
+}
+
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_FOOTPRINT,
+               $user, $pass, $id);
+$service->execute();
+$xml = new SimpleXMLElement($service->get());
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    $updated_iso8601 = $entry->updated;
+
+    $updated = date('Y/m/d H:i:s', mktime(substr($updated_iso8601, 11, 2),
+                                          substr($updated_iso8601, 14, 2),
+                                          substr($updated_iso8601, 17, 2),
+                                          substr($updated_iso8601, 5, 2),
+                                          substr($updated_iso8601, 8, 2),
+                                          substr($updated_iso8601, 0, 4)
+                                          ));
+    printf(
+        '<li><a href="%s" title="%sさん">%s</a>さん (%s)</li>',
+        $entry->link['href'],
+        $entry->author->name,
+        $entry->author->name,
+        $updated
+    );
+}
+echo '</ul>';
+echo '<hr>';
+
+/**
+ * マイミク一覧
+ */
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_MYMIXI,
+               $user, $pass, $id);
+$service->setLastLogin(60);
+$service->execute();
+$xml = new SimpleXMLElement($service->get());
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    printf(
+        '<li><a href="%s" title="%sさん (%s)">%s</a>さん (%s)</li>',
+        $entry->link[0]['href'],
+        $entry->title,
+        $entry->category['label'],
+        $entry->title,
+        $entry->category['label']
+    );
+}
+echo '</ul>';
+echo '<hr>';
+
+/**
+ * マイミク日記、コミュニティなど最新更新一覧
+ */
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_WHATSNEW,
+               $user, $pass, $id);
+$service->execute();
+$xml = new SimpleXMLElement($service->get());
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    switch ($entry->category['term']) {
+    case 'diary':
+        $updated_iso8601 = $entry->updated;
+
+        $updated = date('Y/m/d H:i:s', mktime(substr($updated_iso8601, 11, 2),
+                                              substr($updated_iso8601, 14, 2),
+                                              substr($updated_iso8601, 17, 2),
+                                              substr($updated_iso8601, 5, 2),
+                                              substr($updated_iso8601, 8, 2),
+                                              substr($updated_iso8601, 0, 4)
+                                              ));
+        printf('<li>%s %s</li>', $entry->content, $updated);
+        break;
+    case 'comment':
+    case 'album':
+    case 'video':
+        printf(
+            '<li><a href="%s" title="%s">%s</a> (<a href="%s" title="%s">%s</a>さんの%s)</li>',
+            $entry->link['href'],
+            $entry->title,
+            $entry->title,
+            $entry->author->url,
+            $entry->author->name,
+            $entry->author->name,
+            $entry->category['label']
+        );
+        break;
+    case 'bbs':
+        printf(
+            '<li><a href="%s" title="%s">%s</a> (「<a href="%s" title="%s">%s</a>」の%s)</li>',
+            $entry->link['href'],
+            $entry->title,
+            $entry->title,
+            $entry->author->uri,
+            $entry->author->name,
+            $entry->author->name,
+            $entry->category['label']
+        );
+        break;
+    default:
+    }
+}

Services_MixiAPI/trunk/sample/sample.php

@@ -0,0 +1,115 @@
+<?php
+ini_set("include_path", dirname(__FILE__)."/src/" . PATH_SEPARATOR . ini_get("include_path"));
+require_once "Services/MixiAPI/Factory.php";
+
+error_reporting(E_ALL);
+
+/**
+ * $user,$pass,$idを適宜書き換えてください
+ */
+$user = '[mixiのログインID]';
+$pass = '[mixiのパスワード]';
+$id = '[mixiのユーザーID]';
+
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_FOOTPRINT,
+               $user, $pass, $id);
+$service->execute();
+$xml = new SimpleXMLElement($service->get());
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    $updated_iso8601 = $entry->updated;
+
+    $updated = date('Y/m/d H:i:s', mktime(substr($updated_iso8601, 11, 2),
+                                          substr($updated_iso8601, 14, 2),
+                                          substr($updated_iso8601, 17, 2),
+                                          substr($updated_iso8601, 5, 2),
+                                          substr($updated_iso8601, 8, 2),
+                                          substr($updated_iso8601, 0, 4)
+                                          ));
+    printf(
+        '<li><a href="%s" title="%sさん">%s</a>さん (%s)</li>',
+        $entry->link['href'],
+        $entry->author->name,
+        $entry->author->name,
+        $updated
+    );
+}
+echo '</ul>';
+echo '<hr>';
+
+/**
+ * マイミク一覧
+ */
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_MYMIXI,
+               $user, $pass, $id);
+$service->setLastLogin(60);
+$service->execute();
+$xml = new SimpleXMLElement($service->get());
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    printf(
+        '<li><a href="%s" title="%sさん (%s)">%s</a>さん (%s)</li>',
+        $entry->link[0]['href'],
+        $entry->title,
+        $entry->category['label'],
+        $entry->title,
+        $entry->category['label']
+    );
+}
+echo '</ul>';
+echo '<hr>';
+
+/**
+ * マイミク日記、コミュニティなど最新更新一覧
+ */
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_WHATSNEW,
+               $user, $pass, $id);
+$service->execute();
+$xml = new SimpleXMLElement($service->get());
+echo '<ul>';
+foreach ($xml->entry as $entry) {
+    switch ($entry->category['term']) {
+    case 'diary':
+        $updated_iso8601 = $entry->updated;
+
+        $updated = date('Y/m/d H:i:s', mktime(substr($updated_iso8601, 11, 2),
+                                              substr($updated_iso8601, 14, 2),
+                                              substr($updated_iso8601, 17, 2),
+                                              substr($updated_iso8601, 5, 2),
+                                              substr($updated_iso8601, 8, 2),
+                                              substr($updated_iso8601, 0, 4)
+                                              ));
+        printf('<li>%s %s</li>', $entry->content, $updated);
+        break;
+    case 'comment':
+    case 'album':
+    case 'video':
+        printf(
+            '<li><a href="%s" title="%s">%s</a> (<a href="%s" title="%s">%s</a>さんの%s)</li>',
+            $entry->link['href'],
+            $entry->title,
+            $entry->title,
+            $entry->author->url,
+            $entry->author->name,
+            $entry->author->name,
+            $entry->category['label']
+        );
+        break;
+    case 'bbs':
+        printf(
+            '<li><a href="%s" title="%s">%s</a> (「<a href="%s" title="%s">%s</a>」の%s)</li>',
+            $entry->link['href'],
+            $entry->title,
+            $entry->title,
+            $entry->author->uri,
+            $entry->author->name,
+            $entry->author->name,
+            $entry->category['label']
+        );
+        break;
+    default:
+    }
+}

Services_MixiAPI/trunk/sample/mixi_post_diary.php

@@ -0,0 +1,56 @@
+<?php
+ini_set("include_path", dirname(__FILE__)."/src/" . PATH_SEPARATOR . ini_get("include_path"));
+require_once 'Services/MixiAPI/Diary.php';
+require_once 'Services/MixiAPI/Image.php';
+require_once 'Services/MixiAPI/Factory.php';
+
+error_reporting(E_ALL);
+
+/**
+ * $user,$pass,$idを適宜書き換えてください
+ */
+$user = '[mixiのログインID]';
+$pass = '[mixiのパスワード]';
+$id = '[mixiのユーザーID]';
+
+/**
+ * 日記オブジェクトの作成
+ */
+$title = 'Services_MixiAPIを使った投稿テスト';
+$subject = <<< EOD
+mixiも裏で色々と用意しているみたいですね。
+
+「あしあと」がatom+WSSE認証で配信されているようなので、試]]>してみました。WSSE認証については以下を参照ということで。
+
+    * Web Services Security UsernameToken Profile 1.0(pdf)
+    * はてなブックマークAtomAPIだのWSSEだの
+    * はてなフォトライフatomapiとは - はてなダイアリー
+
+以下サンプルですが、X-WSSEリクエストヘッダの内容を作っている部分は、PEAR::Services_HatenaとServices_Hatena - PHPの挑戦 (ハズレ日記)を参考にさせてもらいました。
+
+つーか、ほとんどそのままですね ;-)
+EOD;
+$diary = new Services_MixiAPI_Diary($title, $subject);
+$diary->setImage(new Services_MixiAPI_Image('./2905457_723594618.jpg'));
+
+/**
+ * 日記投稿APIオブジェクトの作成
+ */
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_POSTDIARY,
+               $user, $pass, $id);
+
+/**
+ * 日記オブジェクトをセット
+ */
+$service->setDiary($diary);
+
+/**
+ * リクエスト送信
+ */
+$service->execute();
+
+/**
+ * 結果のXML
+ */
+var_dump($service->get());

Services_MixiAPI/trunk/sample/mixi_album.php

@@ -0,0 +1,97 @@
+<?php
+ini_set("include_path", dirname(__FILE__)."/src/" . PATH_SEPARATOR . ini_get("include_path"));
+require_once 'Services/MixiAPI/Image.php';
+require_once 'Services/MixiAPI/Factory.php';
+
+error_reporting(E_ALL);
+
+//$user = '[mixiのログインID]';
+//$pass = '[mixiのパスワード]';
+//$id = '[mixiのユーザーID]';
+$user = getenv('SERVICES_MIXI_USER');
+$pass = getenv('SERVICES_MIXI_PWD');
+$id = getenv('SERVICES_MIXI_ID');
+if (!$user) {
+    die('user is not set');
+}
+if (!$pass) {
+    die('password is not set');
+}
+if (!$id) {
+    die('id is not set');
+}
+
+
+
+/**
+ * フォトアルバムAPIオブジェクトの作成
+ */
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_ALBUMLIST,
+               $user, $pass, $id);
+
+/**
+ * リクエスト送信
+ */
+$service->execute();
+
+/**
+ * 結果のXMLからアルバム名を取得
+ */
+$xml = new SimpleXMLElement($service->get());
+$xml->registerXPathNamespace('default', 'http://www.w3.org/2007/app');
+$xml->registerXPathNamespace('atom', 'http://www.w3.org/2005/Atom');
+foreach ($xml->xpath('//default:collection[contains(@href, "/album_id=")]/atom:title') as $element) {
+    echo $element . "\n";
+}
+
+
+
+/**
+ * フォトアルバムAPIオブジェクトの作成
+ */
+$service = Services_MixiAPI_Factory::getInstance(
+               Services_MixiAPI_Factory::API_MODE_PHOTOALBUM,
+               $user, $pass, $id);
+
+/**
+ * アルバムIDをセット
+ */
+$service->setAlbumId('18709833');
+
+/**
+ * リクエスト送信
+ */
+$service->execute();
+
+/**
+ * 結果のXMLから写真タイトルとURLを取得
+ */
+$xml = new SimpleXMLElement($service->get());
+$xml->registerXPathNamespace('atom', 'http://www.w3.org/2005/Atom');
+foreach ($xml->xpath('//atom:entry') as $element) {
+    printf("%s(%s)\n", $element->title, $element->link['href']);
+}
+
+
+
+/**
+ * メソッドをセット
+ * デフォルトはServices_MixiAPI_PhotoAlbum::METHOD_LIST
+ */
+$service->setMethod(Services_MixiAPI_PhotoAlbum::METHOD_POST);
+
+/**
+ * 写真オブジェクトをセット
+ */
+$service->setImage(new Services_MixiAPI_Image('./2905457_723594618.jpg'));
+
+/**
+ * リクエスト送信
+ */
+$service->execute();
+
+/**
+ * 結果のXML
+ */
+var_dump($service->get());

Services_MixiAPI/trunk/Services/MixiAPI/API.php

@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * Service interface for Mixi API
+ *
+ * PHP version 5
+ *
+ * LICENSE: This source file is subject to version 3.01 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_01.txt.  If you did not receive a copy
+ * the PHP License and are unable to obtain it through the web,
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+
+/**
+ * Service interface for Mixi API
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   Release: 0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+interface Services_MixiAPI_API {
+
+    /**
+     * return the API url
+     *
+     * @param  strint $id   mixi id
+     * @return string the API url
+     * @access public
+     */
+    public function getApiUrl($id);
+
+    /**
+     * execute service
+     *
+     * @param  strint $user username
+     * @param  strint $pass password
+     * @param  strint $id   mixi id
+     * @access public
+     */
+    public function execute($user, $pass, $id);
+}

Services_MixiAPI/trunk/Services/MixiAPI/PhotoAlbum.php

@@ -0,0 +1,161 @@
+<?php
+
+/**
+ * The photo album service class for Mixi API
+ *
+ * PHP version 5
+ *
+ * LICENSE: This source file is subject to version 3.01 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_01.txt.  If you did not receive a copy
+ * the PHP License and are unable to obtain it through the web,
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2008 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ */
+
+require_once 'Services/MixiAPI/AbstractAPI.php';
+
+/**
+ * Post a diary service class for Mixi API
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2008 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   Release: 0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ */
+class Services_MixiAPI_PhotoAlbum extends Services_MixiAPI_AbstractAPI {
+
+    /**
+     * 'post' method
+     */
+    const METHOD_POST = HTTP_REQUEST_METHOD_POST;
+
+    /**
+     * 'list' method
+     */
+    const METHOD_LIST = HTTP_REQUEST_METHOD_GET;
+
+
+    /**
+     * a Services_MixiAPI_Image object
+     */
+    private $image = null;
+
+    /**
+     * album id
+     */
+    private $album_id = null;
+
+    /**
+     * request method
+     */
+    private $method = HTTP_REQUEST_METHOD_GET;
+
+
+    /**
+     * return the API url
+     *
+     * @param  strint $id   mixi id
+     * @return string    the API url
+     * @access public
+     */
+    public function getApiUrl($id) {
+        return 'http://photo.mixi.jp/atom/r=4/member_id=' . $id . '/album_id=' . $this->album_id;
+    }
+
+    /**
+     * setup HTTP_Request object without WSSE Authorization
+     *
+     * @param  HTTP_Request $request HTTP_Request object
+     * @return void
+     * @access protected
+     */
+    protected function setupRequest(HTTP_Request $request) {
+        if (is_null($this->album_id)) {
+            throw new RuntimeException('album id must be set');
+        }
+        if ($this->method === HTTP_REQUEST_METHOD_POST) {
+            if (is_null($this->image)) {
+                throw new RuntimeException('Service_MixiAPI_Image object must be set');
+            }
+            $request->addHeader('Content-Type', 'image/jpeg');
+            $request->setBody($this->image->getContentsData());
+        }
+        $request->setMethod($this->method);
+    }
+
+    /**
+     * set an image to post
+     *
+     * @param Services_MixiAPI_Image object $image a Services_MixiAPI_Image object
+     * @return void
+     */
+    public function setImage($image) {
+        if (is_array($image) &&
+            count($image) === 1) {
+            $image = $image[0];
+        }
+        if (get_class($image) === 'Services_MixiAPI_Image') {
+            $this->image = $image;
+        } else {
+            throw new InvalidArgumentException('Invalid argument');
+        }
+    }
+
+    /**
+     * set an album id
+     *
+     * @param string $id album id
+     * @return void
+     */
+    public function setAlbumId($id) {
+        if (is_array($id) &&
+            count($id) === 1) {
+            $id = $id[0];
+        }
+        $this->album_id = $id;
+    }
+
+    /**
+     * set a method
+     *
+     * @param string $method a request method
+     * @return void
+     */
+    public function setMethod($method) {
+        if (is_array($method) &&
+            count($method) === 1) {
+            $method = $method[0];
+        }
+        if ($this->method !== self::METHOD_POST &&
+            $this->method !== self::METHOD_LIST) {
+            throw new InvalidArgumentException('Invalid argument');
+        }
+        $this->method = $method;
+    }
+
+    /**
+     * execute service
+     *
+     * @param  strint $user username
+     * @param  strint $pass password
+     * @param  strint $id   mixi id
+     * @return string fetched result in the xml format
+     * @access public
+     * @throws Exception Exception description (if any) ...
+     */
+    public function execute($user, $pass, $id)
+    {
+        return parent::execute($user, $pass, $id);
+    }
+}

Services_MixiAPI/trunk/Services/MixiAPI/AlbumList.php

@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * AlbumList service class for Mixi API
+ *
+ * PHP version 5
+ *
+ * LICENSE: This source file is subject to version 3.01 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_01.txt.  If you did not receive a copy
+ * the PHP License and are unable to obtain it through the web,
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+
+require_once 'Services/MixiAPI/AbstractAPI.php';
+
+/**
+ * AlbumList service class for Mixi API
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   Release: 0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+class Services_MixiAPI_AlbumList extends Services_MixiAPI_AbstractAPI {
+
+    /**
+     * return the API url
+     *
+     * @param  strint $id   mixi id
+     * @return string    the API url
+     * @access public
+     */
+    public function getApiUrl($id) {
+        return 'http://photo.mixi.jp/atom/r=4';
+    }
+}

Services_MixiAPI/trunk/Services/MixiAPI/MyMixi.php

@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * My Mixi service class for Mixi API
+ *
+ * PHP version 5
+ *
+ * LICENSE: This source file is subject to version 3.01 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_01.txt.  If you did not receive a copy
+ * the PHP License and are unable to obtain it through the web,
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+
+require_once 'Services/MixiAPI/AbstractAPI.php';
+
+/**
+ * My Mixi service class for Mixi API
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   Release: 0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+class Services_MixiAPI_MyMixi extends Services_MixiAPI_AbstractAPI {
+
+    private $last_login = null;
+
+    /**
+     * return the API url
+     *
+     * @param  strint $id   mixi id
+     * @return string    the API url
+     * @access public
+     */
+    public function getApiUrl($id) {
+        $url = 'http://mixi.jp/atom/friends/r=1/member_id=' . $id;
+        if (!is_null($this->last_login)) {
+            $url .= '?last-login=' . $this->last_login;
+        }
+        return $url;
+    }
+
+    public function setLastLogin($last_login)
+    {
+        if (is_array($last_login) &&
+            count($last_login) === 1) {
+            $last_login = $last_login[0];
+        }
+        if ((int)$last_login !== 60) {
+            throw new InvalidArgumentException('last login must be 60');
+        }
+        $this->last_login = (int)$last_login;
+    }
+}

Services_MixiAPI/trunk/Services/MixiAPI/AbstractAPI.php

@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * Abstract service class for Mixi API
+ *
+ * PHP version 5
+ *
+ * LICENSE: This source file is subject to version 3.01 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_01.txt.  If you did not receive a copy
+ * the PHP License and are unable to obtain it through the web,
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+
+require_once 'Services/MixiAPI/API.php';
+require_once 'HTTP/Request.php';
+
+/**
+ * Abstract service class for Mixi API
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   Release: 0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+abstract class Services_MixiAPI_AbstractAPI implements Services_MixiAPI_API {
+
+    protected $headers = array();
+
+    /**
+     * execute service
+     *
+     * @param  strint $user username
+     * @param  strint $pass password
+     * @param  strint $id   mixi id
+     * @return string fetched result in the xml format
+     * @access public
+     * @throws Exception Exception description (if any) ...
+     */
+    public function execute($user, $pass, $id) {
+        $request = new HTTP_Request($this->getApiUrl($id));
+        $request->addHeader('X-WSSE', $this->buildWSSEAuth($user, $pass));
+        $this->setupRequest($request);
+        if (PEAR::isError($request->sendRequest())) {
+            throw new RuntimeException('request failed : ' . $this->getApiUrl($id));
+        }
+        $this->headers = $request->getResponseHeader();
+        return $request->getResponseBody();
+    }
+
+    /**
+     * build HTTP header for WSSE Authorization
+     *
+     * @param  string $user user name
+     * @param  string $pass password
+     * @return string WSSE HTTP header
+     */
+    private function buildWSSEAuth($user, $pass) {
+        $nonce = pack('H*', sha1(md5(time().rand().uniqid(rand(), true))));
+        $created = gmdate('Y-m-d\TH:i:s') . 'Z';
+        $digest = base64_encode(pack('H*', sha1($nonce . $created . $pass)));
+        $wsse_header = sprintf('UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"', $user, $digest, base64_encode($nonce), $created);
+        return $wsse_header;
+    }
+
+    /**
+     * setup HTTP_Request object without WSSE Authorization
+     *
+     * @param  HTTP_Request $request HTTP_Request object
+     * @return void
+     * @access protected
+     */
+    protected function setupRequest(HTTP_Request $request) {
+    }
+}

Services_MixiAPI/trunk/Services/MixiAPI/PostDiary.php

@@ -0,0 +1,146 @@
+<?php
+
+/**
+ * Post a diary service class for Mixi API
+ *
+ * PHP version 5
+ *
+ * LICENSE: This source file is subject to version 3.01 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_01.txt.  If you did not receive a copy
+ * the PHP License and are unable to obtain it through the web,
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2008 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ */
+
+require_once 'Services/MixiAPI/AbstractAPI.php';
+
+/**
+ * Post a diary service class for Mixi API
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2008 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   Release: 0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ */
+class Services_MixiAPI_PostDiary extends Services_MixiAPI_AbstractAPI {
+
+    /**
+     * a Services_MixiAPI_Diary object
+     */
+    private $diary = null;
+
+    /**
+     * the API url
+     */
+    private $url = null;
+
+
+    /**
+     * return the API url
+     *
+     * @param  strint $id   mixi id
+     * @return string    the API url
+     * @access public
+     */
+    public function getApiUrl($id) {
+        return is_null($this->url) ? 'http://mixi.jp/atom/diary/member_id=' . $id : $this->url;
+    }
+
+    /**
+     * setup HTTP_Request object without WSSE Authorization
+     *
+     * @param  HTTP_Request $request HTTP_Request object
+     * @return void
+     * @access protected
+     */
+    protected function setupRequest(HTTP_Request $request) {
+        if (is_null($this->diary)) {
+            throw new RuntimeException('Service_MixiAPI_Diary object must be set');
+        }
+        if ($this->diary->hasImage()) {
+            $request->addHeader('Content-Type', 'image/jpeg');
+            $request->setBody($this->diary->getImage()->getContentsData());
+        } else {
+            $request->setBody($this->diary->getContentsData());
+        }
+        $request->setMethod(HTTP_REQUEST_METHOD_POST);
+    }
+
+    /**
+     * set a Services_MixiAPI_Diary object
+     *
+     * @param Services_MixiAPI_Diary object $diary a Services_MixiAPI_Diary object
+     * @return void
+     */
+    public function setDiary($diary) {
+        if (is_array($diary) &&
+            count($diary) === 1) {
+            $diary = $diary[0];
+        }
+        if (get_class($diary) === 'Services_MixiAPI_Diary') {
+            $this->diary = $diary;
+        } else {
+            throw new InvalidArgumentException('Invalid argument');
+        }
+    }
+
+    /**
+     * return 'location'
+     *
+     * @return string 'location' string
+     */
+    public function getLocation()
+    {
+        return isset($this->headers['location']) ? $this->headers['location'] : null;
+    }
+
+    /**
+     * set the request url
+     *
+     * @param string $url th request url
+     * @return void
+     */
+    public function setApiUrl($url)
+    {
+        $this->url = $url;
+    }
+
+    /**
+     * execute service
+     *
+     * @param  strint $user username
+     * @param  strint $pass password
+     * @param  strint $id   mixi id
+     * @return string fetched result in the xml format
+     * @access public
+     * @throws Exception Exception description (if any) ...
+     */
+    public function execute($user, $pass, $id)
+    {
+        /**
+         * the order of request
+         * 1. image
+         * 2. text
+         *
+         * @see http://creazy.net/2008/07/post_a_mixi_dialy_from_php.html
+         */
+        if ($this->diary->hasImage()) {
+            parent::execute($user, $pass, $id);
+            $this->setApiUrl($this->getLocation());
+            $this->diary->removeImage();
+        }
+        return parent::execute($user, $pass, $id);
+    }
+
+}

Services_MixiAPI/trunk/Services/MixiAPI/WhatsNew.php

@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * What's new service class for Mixi API
+ *
+ * PHP version 5
+ *
+ * LICENSE: This source file is subject to version 3.01 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_01.txt.  If you did not receive a copy
+ * the PHP License and are unable to obtain it through the web,
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+
+require_once 'Services/MixiAPI/AbstractAPI.php';
+
+/**
+ * What's new service class for Mixi API
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   Release: 0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+class Services_MixiAPI_WhatsNew extends Services_MixiAPI_AbstractAPI {
+
+    /**
+     * return the API url
+     *
+     * @param  strint $id   mixi id
+     * @return string    the API url
+     * @access public
+     */
+    public function getApiUrl($id) {
+        return 'http://mixi.jp/atom/updates/r=1/member_id=' . $id;
+    }
+}

Services_MixiAPI/trunk/Services/MixiAPI/Image.php

@@ -0,0 +1,26 @@
+<?php
+final class Services_MixiAPI_Image
+{
+    private $filename = null;
+    public function __construct($filename)
+    {
+        $this->filename = $filename;
+    }
+
+    public function getFilename()
+    {
+        return $this->filename;
+    }
+    public function getContentType()
+    {
+        return $this->contents['title'];
+    }
+    public function getContentsData()
+    {
+        if (is_readable($this->filename)) {
+            return file_get_contents($this->filename);
+        }
+
+        throw new RuntimeException($this->filename . 'not found');
+    }
+}

Services_MixiAPI/trunk/Services/MixiAPI/Footprint.php

@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * Footprint service class for Mixi API
+ *
+ * PHP version 5
+ *
+ * LICENSE: This source file is subject to version 3.01 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_01.txt.  If you did not receive a copy
+ * the PHP License and are unable to obtain it through the web,
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+
+require_once 'Services/MixiAPI/AbstractAPI.php';
+
+/**
+ * Footprint service class for Mixi API
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   Release: 0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+class Services_MixiAPI_Footprint extends Services_MixiAPI_AbstractAPI {
+
+    /**
+     * return the API url
+     *
+     * @param  strint $id   mixi id
+     * @return string    the API url
+     * @access public
+     */
+    public function getApiUrl($id) {
+        return 'http://mixi.jp/atom/tracks/r=2/member_id=' . $id;
+    }
+}

Services_MixiAPI/trunk/Services/MixiAPI/Factory.php

@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * Service factory class for Mixi API
+ *
+ * PHP version 5
+ *
+ * LICENSE: This source file is subject to version 3.01 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_01.txt.  If you did not receive a copy
+ * the PHP License and are unable to obtain it through the web,
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+
+require_once 'Services/MixiAPI.php';
+
+/**
+ * Service factory class for Mixi API
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   Release: 0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+final class Services_MixiAPI_Factory {
+
+    /**
+     * 'Footprint' API mode
+     */
+    const API_MODE_FOOTPRINT = 'Footprint';
+
+    /**
+     * 'MyMixi' API mode
+     */
+    const API_MODE_MYMIXI = 'MyMixi';
+
+    /**
+     * 'What's New' API mode
+     */
+    const API_MODE_WHATSNEW = 'WhatsNew';
+
+    /**
+     * 'PostDiary' API mode
+     */
+    const API_MODE_POSTDIARY = 'PostDiary';
+
+    /**
+     * 'PhotoAlbum' API mode
+     */
+    const API_MODE_PHOTOALBUM = 'PhotoAlbum';
+
+    /**
+     * 'AlbumList' API mode
+     */
+    const API_MODE_ALBUMLIST = 'AlbumList';
+
+    /**
+     * constructor
+     *
+     * @return void
+     * @access private
+     */
+    private function __construct() {
+    }
+
+    /**
+     * create and return an service instance
+     *
+     * @param  string    $api  the API mode
+     * @param  string    $user username
+     * @param  string    $pass password
+     * @param  string    $id   mixi id
+     * @access public
+     * @throws InvalidArgumentException throws InvalidArgumentException if errors occur
+     * @throws RuntimeException throws RuntimeException if class not found
+     * @static
+     */
+    public static function getInstance($api, $user, $pass, $id) {
+        if (is_null($user) || !is_string($user) || $user === '') {
+            throw new InvalidArgumentException('user must be string');
+        }
+        if (is_null($pass) || !is_string($pass) || $pass === '') {
+            throw new InvalidArgumentException('pass must be string');
+        }
+        if (is_null($id) || !is_string($id) || $id === '') {
+            throw new InvalidArgumentException('id must be string');
+        }
+
+        $const_name = 'Services_MixiAPI_Factory::API_MODE_' . strtoupper($api);
+        if (!defined($const_name)) {
+            throw new InvalidArgumentException('Invalid API "' . $api . '"');
+        }
+
+        require_once 'Services/MixiAPI/' . $api . '.php';
+        $classname = 'Services_MixiAPI_' . $api;
+        if (class_exists($classname)) {
+            return new Services_MixiAPI($user, $pass, $id, new $classname());
+        } else {
+            throw new RuntimeException('missing the class "' . $classname . '"');
+        }
+    }
+}

Services_MixiAPI/trunk/Services/MixiAPI/Diary.php

@@ -0,0 +1,46 @@
+<?php
+final class Services_MixiAPI_Diary
+{
+    private $image = null;
+    private $contents = array();
+    public function __construct($title, $contents)
+    {
+        $this->contents['title'] = $title;
+        $this->contents['contents'] = $contents;
+    }
+
+    public function setImage(Services_MixiAPI_Image $image)
+    {
+        $this->image = $image;
+    }
+    public function getImage()
+    {
+        return $this->image;
+    }
+    public function hasImage()
+    {
+        return !is_null($this->image);
+    }
+    public function removeImage()
+    {
+        $this->image = null;
+    }
+    public function getTitle()
+    {
+        return $this->contents['title'];
+    }
+    public function getContents()
+    {
+        return $this->contents['contents'];
+    }
+    public function getContentsData()
+    {
+        return sprintf('<?xml version="1.0" encoding="UTF-8"?>'
+                     . '<entry xmlns="http://www.w3.org/2007/app">'
+                     . '<title><![CDATA[%s]]></title>'
+                     . '<summary><![CDATA[%s]]></summary>'
+                     . '</entry>',
+                       str_replace(']]>', ']]&gt;', $this->getTitle()),
+                       str_replace(']]>', ']]&gt;', $this->getContents()));
+    }
+}

Services_MixiAPI/trunk/Services/MixiAPI.php

@@ -0,0 +1,119 @@
+<?php
+
+/**
+ * Web API wrapper for Mixi
+ *
+ * PHP version 5
+ *
+ * LICENSE: This source file is subject to version 3.01 of the PHP license
+ * that is available through the world-wide-web at the following URI:
+ * http://www.php.net/license/3_01.txt.  If you did not receive a copy
+ * the PHP License and are unable to obtain it through the web,
+ * send a note to license@php.net so we can mail you a copy immediately.
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+
+require_once 'Services/MixiAPI/API.php';
+
+/**
+ * Web API wrapper for Mixi
+ *
+ * @category  Services
+ * @package   Services_MixiAPI
+ * @author    Hideyuki Shimooka <shimooka@doyouphp.jp>
+ * @copyright 2007 Hideyuki Shimooka
+ * @license   http://www.php.net/license/3_01.txt The PHP License, version 3.01
+ * @version   Release: 0.0.1
+ * @link      http://pear.php.net/package/Services_MixiAPI
+ * @see       References to other sections (if any)...
+ */
+class Services_MixiAPI {
+
+    /**
+     * username
+     * @var    string
+     * @access private
+     */
+    private $user;
+
+    /**
+     * password
+     * @var    string
+     * @access private
+     */
+    private $pass;
+
+    /**
+     * mixi id
+     * @var    string
+     * @access private
+     */
+    private $id;
+
+    /**
+     * a service instance
+     * @var    object Service_MixiAPI_API
+     * @access private
+     */
+    private $api;
+
+    /**
+     * fetched result in the xml format
+     * @var    string
+     * @access private
+     */
+    private $result;
+
+    /**
+     * constructor
+     *
+     * @param  strint $user username
+     * @param  strint $pass password
+     * @param  strint $id   mixi id
+     * @param  Services_MixiAPI_API $api  Services_MixiAPI_API object
+     * @access public
+     */
+    public function __construct($user, $pass, $id, Services_MixiAPI_API $api) {
+        $this->user = $user;
+        $this->pass = $pass;
+        $this->id = $id;
+        $this->api = $api;
+    }
+
+    /**
+     * execute your service
+     *
+     * @return void
+     * @access public
+     */
+    public function execute() {
+        $this->result = $this->api->execute($this->user, $this->pass, $this->id);
+    }
+
+    /**
+     * return fetched result in the xml format
+     *
+     * @return string fetched result
+     * @access public
+     */
+    public function get() {
+        return $this->result;
+    }
+
+    public function __call($method, $args)
+    {
+        if (is_callable(array($this->api, $method))) {
+            return call_user_func(array($this->api, $method), $args);
+        }
+
+        throw new BadMethodCallException($method . ' method does not exist');
+    }
+}