Skip to content

Instantly share code, notes, and snippets.

@sasezaki
Created May 3, 2012 16:44
Show Gist options
  • Save sasezaki/2587138 to your computer and use it in GitHub Desktop.
Save sasezaki/2587138 to your computer and use it in GitHub Desktop.
Photozou(photo upload service) API Client - for Multi Access
<?php
set_include_path($_SERVER['HOME'].'/dev/zendframework_zf2/library/');
require_once 'Zend/Loader/StandardAutoloader.php';
$loader = new Zend\Loader\StandardAutoloader;
$loader->registerNamespace('Hasty', $_SERVER['HOME'].'/dev/padraic_hasty/src/Hasty');
$loader->registerNamespace('Symfony', $_SERVER['HOME'].'/dev/symfony_symfony/src/Symfony');
$loader->registerNamespace('Guzzle', $_SERVER['HOME'].'/dev/guzzle_guzzle/src/Guzzle');
$loader->registerNamespace('React', $_SERVER['HOME'].'/dev/react-php_react/src/React');
$loader->register();
$config = array(
'photozou' => array(
'user' => '',
'password' => ''
),
);
<?php
namespace Photozou;
use DOMDocument;
use Zend\Http\Request;
use Zend\Http\Client as HttpClient;
use Zend\Uri\UriFactory;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
class ApiActor
{
const BASE_URL = 'http://api.photozou.jp/rest/';
public $path;
public $params;
protected $handlers = array();
public $requestMethodMap = array(
'nop' => 'GET',
'photo_add' => 'POST',
'photo_add_album' => 'POST',
'photo_info' => 'GET',
);
public function __construct($path, $params = array(), $method = null)
{
$this->path = $path;
$this->params = $params;
}
public function handle($body, $locator = null)
{
$handler = $this->getHandler();
return $handler($body, $locator);
}
protected function getHandler()
{
if (isset($this->handlers[$this->path])) {
return $this->handlers[$this->path];
}
// set default handler
switch ($this->path) {
case 'photo_add':
$this->handlers['photo_add'] = function($body) {
$encoder = new XmlEncoder;
return $encoder->decode($body, 'xml');
};
break;
case 'photo_info':
$this->handlers['photo_info'] = function($body) {
$encoder = new XmlEncoder;
return $encoder->decode($body, 'xml');
};
break;
default:
// fallback
return function($body) {
return $body;
};
break;
}
return $this->handlers[$this->path];
}
public function setHandler($path, $callback)
{
$this->handlers[$path] = $callback;
}
}
class ZFHttpClient
{
private $client;
public function __construct($username = null, $password = null)
{
$client = new HttpClient;
$client->setAuth($username, $password);
$this->client = $client;
}
public function setLocator()
{}
// convinience method
public function setProgressBar()
{
}
public function nop()
{
$actor = new ApiActor('nop');
$response = $this->client->send($this->getRequest($actor));
return $actor->handle($response->getBody());
}
public function photo_add($photo, $params)
{
$actor = new ApiActor('photo_add', $params);
$this->client->setFileUpload($photo, 'photo');
$response = $this->client->send($this->getRequest($actor));
return $actor->handle($response->getBody());
}
public function photo_info($photo_id)
{
$actor = new ApiActor('photo_info', compact('photo_id'));
$response = $this->client->send($this->getRequest($actor));
return $actor->handle($response->getBody());
}
protected function getRequest($actor)
{
$request = new Request();
$request->setUri(ApiActor::BASE_URL.$actor->path);
$request->setMethod($actor->requestMethodMap[$actor->path]);
if ($actor->params) $request->query()->fromArray($actor->params);
return $request;
}
}
abstract class AbstractParallelClient
{
protected $actors = array();
// todo
//public function setAuth();
public function nop()
{
$this->actors[] = new ApiActor('nop');
return $this;
}
public function photo_info($photo_id)
{
$this->actors[] = new ApiActor('photo_info', compact('photo_id'));
return $this;
}
abstract function run();
}
class HastyClient extends AbstractParallelClient
{
private $pool;
public function __construct()
{
$this->pool = new \Hasty\Pool;
}
public function run()
{
$results = array();
foreach ($this->actors as $actor) {
$request = $this->getRequest($actor);
$request->on('complete', function($response, $pool) use ($actor, &$results) {
$results[] = $actor->handle($response->getContent());
});
$this->pool->attach($request);
}
$this->pool->run();
$this->actors = array();
return $results;
}
protected function getRequest($actor)
{
$uri = UriFactory::factory(ApiActor::BASE_URL.$actor->path);
if ($actor->params) $uri->setQuery($actor->params);
$request = new \Hasty\Request($uri->toString());
$request->setMethod($actor->requestMethodMap[$actor->path]);
return $request;
}
}
class GuzzleClient extends AbstractParallelClient
{
public function __construct()
{
$this->client = new \Guzzle\Http\Client;
}
public function run()
{
$results = array();
foreach ($this->actors as $actor) {
$request = $this->getRequest($actor);
$request->getEventDispatcher()->addListener('request.success', function ($event) use ($actor, &$results) {
$results[] = $actor->handle($event['response']->getBody(true));
});
$requests[] = $request;
}
try {
$this->client->send($requests);
} catch (\Exception $e) {
$this->actors = array();
throw $e;
}
$this->actors = array();
return $results;
}
protected function getRequest($actor)
{
$url = \Guzzle\Http\Url::factory(ApiActor::BASE_URL.$actor->path);
if ($actor->params) $url->setQuery($actor->params);
$request = new \Guzzle\Http\Message\Request($actor->requestMethodMap[$actor->path], $url);
return $request;
}
}
class ReactClient extends AbstractParallelClient
{
private $loop;
public function __construct(\React\EventLoop\LoopInterface $loop = null)
{
if ($loop === null) {
$loop = \React\EventLoop\Factory::create();
}
$this->loop = $loop;
}
public function run()
{
$returns = array();
foreach ($this->actors as $actor) {
$request = $this->getRequest($actor);
$loop = $this->loop;
$this->loop->addReadStream($request->read_stream, function($readStream) use ($loop, $actor, &$returns) {
$responseBody = stream_get_contents($readStream);
$loop->removeStream($readStream);
$returns[] = $actor->handle($responseBody);
return;
});
}
$this->loop->run();
$this->actors = array();
return $returns;
}
public function getRequest($actor)
{
$request = new \stdClass;
$url = ApiActor::BASE_URL.$actor->path;
$url .= ($actor->params) ? '?'. http_build_query($actor->params) : '';
$request->read_stream = fopen($url, 'r');
return $request;
}
}
global $config;
$clientClass = isset($argv[1]) ? 'Photozou\\'.ucfirst($argv[1]).'Client' : die('choose Hasty or Guzzle or React');
if ($clientClass == 'ZFHttpClient') {
$client = new ZFHttpClient($config['photozou']['user'], $config['photozou']['password']);
$ret = $client->photo_info(17561757);
var_dump($ret);
} else {
$client = new $clientClass;
$client->photo_info(17561757);
$client->photo_info(17561757);
var_dump($client->run());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment