<?php
/* vim: set expandtab tabstop=4 shiftwidth=4: */
// +----------------------------------------------------------------------+
// | PHP Version 5                                                        |
// +----------------------------------------------------------------------+
// | Copyright (c) 2010 Takahiro Ooishi                                   |
// +----------------------------------------------------------------------+
// | This source file is subject to version 3.0 of the PHP license,       |
// | that is bundled with this package in the file LICENSE, and is        |
// | available through the world-wide-web at the following url:           |
// | http://www.php.net/license/3_0.txt.                                  |
// | If you did not receive a copy of the PHP license and are unable to   |
// | obtain it through the world-wide-web, please send a note to          |
// | license@php.net so we can mail you a copy immediately.               |
// +----------------------------------------------------------------------+
// | Author: Takahiro Ooishi <taka0125.biz@gmail.com>                     |
// +----------------------------------------------------------------------+
//
// $Id$

class Http_CurlAgent extends Http_AgentTemplate
{
    protected $connection = null;

    protected function open()
    {
        $this->connection = curl_init();
    }

    protected function close()
    {
        if ($this->isNotConnected()) return;
        curl_close($this->connection);
    }

    function setBasicAuthenticationAccount($user, $password)
    {
        $this->setOption(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        $this->setOption(CURLOPT_USERPWD, "{$user}:{$password}");
        return true;
    }

    function setOptions($options)
    {
        $this->options = array(
            CURLOPT_DNS_USE_GLOBAL_CACHE => false, // グローバル DNS キャッシュを利用しない
            CURLOPT_NOPROGRESS => true,            // 進捗確認なし
            CURLOPT_TIMEOUT => $this->timeout,     // タイムアウト(秒)
            CURLOPT_VERBOSE => false,              // 詳細表示なし
            CURLOPT_HEADER => false,               // ヘッダ出力なし
            CURLOPT_FAILONERROR => true,           // 400 以上のコードが返ってきた際に処理失敗
            CURLOPT_RETURNTRANSFER => true,        // 結果を文字列とし格納
            CURLOPT_FILETIME => true,              // ファイルの更新日時取得
            CURLOPT_TIMECONDITION => true,
            CURLOPT_FOLLOWLOCATION => true,        // 301に対応
            CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)', // ユーザエージェント
        );

        if ($this->isInvalidOptions($options)) return true;

        foreach ($options as $name => $option) {
            $this->options[$name] = $option;
        }
        return true;
    }

    function setOption($name, $option)
    {
        $this->options[$name] = $option;
    }

    function send($url, $request)
    {
        if ($this->isInvalidRequest($request)) throw new ValidationException($request, 'Invalid Request.');

        $this->prepare($url, $request);
    
        $contents = curl_exec($this->connection);
        $infomations = curl_getinfo($this->connection);
        return new Http_Response($contents, $infomations);
    }

    protected function prepare($url, $request)
    {
        $url = $request->buildUrl($url);

        if ($request->isUseCookie()) {
            $this->setCookie($request);
        }

        $this->setOption(CURLOPT_URL, $url);

        if ($request->existsPostParams()) {
            $this->setPostOptions($request);
        } else {
            $this->setOption(CURLOPT_POST, false);
        }

        curl_setopt_array($this->connection, $this->options);
    }

    protected function setCookie($request)
    {
        $this->setOption(CURLOPT_COOKIEJAR, $request->cookieFile());
        $this->setOption(CURLOPT_COOKIEFILE, $request->cookieFile());
    }

    protected function setPostOptions($request)
    {
        $queries = http_build_query($request->postParams());
        $this->setOption(CURLOPT_POSTFIELDS, $queries);
        $this->setOption(CURLOPT_POST, true);
    }

    protected function isInvalidOptions($params)
    {
        if (!is_array($params)) return true;
        return false;
    }

    protected function isInvalidRequest($request)
    {
        if (!is_a($request, 'Http_Request')) return true;
        return false;
    }

    protected function isNotConnected()
    {
        if (is_null($this->connection)) return true;
        return false;
    }
}
