1. <?php
  2. /**
  3.  * Photobucket Service API Client
  4.  *
  5.  */
  6.  
  7. require_once 'Zend/Service/Abstract.php';
  8. require_once 'Zend/Oauth.php';
  9. require_once 'Zend/Oauth/Client.php';
  10. require_once 'Zend/Oauth/Consumer.php';
  11. require_once 'Zend/Oauth/Token/Access.php';
  12. require_once 'Zend/Service/Photobucket/Oauth/Client.php';
  13. require_once 'Zend/Service/Photobucket/Exception.php';
  14. require_once 'Zend/Uri.php';
  15. require_once 'Zend/Json.php';
  16. require_once 'Zend/Service/Photobucket/Methods.php';
  17.  
  18. class Zend_Service_Photobucket extends Zend_Service_Abstract
  19. {
  20.  
  21.     /**
  22.      * Local HTTP Client cloned from statically set client
  23.      * @var Zend_Http_Client
  24.      */
  25.     protected $_localHttpClient;
  26.  
  27.     /**
  28.      * URI of Photobucket's REST API
  29.      * @var      string   $api
  30.      */
  31.     protected static $_api_url = 'http://api.photobucket.com';
  32.  
  33.     /**
  34.      * currently logged in username
  35.      * @var      string   $_username
  36.      */
  37.     protected $_username;
  38.  
  39.     /**
  40.      * Zend_Uri of this web service
  41.      * @var Zend_Uri_Http
  42.      */
  43.     protected $_uri = null;
  44.  
  45.     /**
  46.      * Current OAuth Token
  47.      * @var Zend_Oauth_Token_Access
  48.      */
  49.     protected $_token = null;
  50.  
  51.     /**
  52.      * response type processed by the code
  53.      * @var string
  54.      */
  55.     protected $_response_type = self::RESPONSE_TYPE_JSON;
  56.  
  57.     public static $baseOauthOptions = array('requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER,
  58.                                             'version' => '1.0',
  59.                                             'signatureMethod' => 'HMAC-SHA1',
  60.                                             'requestTokenUrl' => 'http://api.photobucket.com/login/request',
  61.                                             'accessTokenUrl' => 'http://api.photobucket.com/login/access',
  62.                                             'userAuthorizationUrl' => 'http://photobucket.com/apilogin/login',
  63.                                            );
  64.     protected $_oauthOptions = array();
  65.  
  66.     const RESPONSE_TYPE_JSON = 'json';
  67.     const RESPONSE_TYPE_XML = 'xml';
  68.     const RESPONSE_TYPE_PHP = 'php';
  69.     const RESPONSE_TYPE_RAW = 'raw';
  70.  
  71.     const STATUS_OK = 'OK';
  72.  
  73.     /**
  74.      * Construct
  75.      *
  76.      * @param string $key API key
  77.      * @param string $secret API secret
  78.      *
  79.      * @return void
  80.      */
  81.     public function __construct(array $oauth_opts, $token = null) {
  82.         $this->setOauthOptions($oauth_opts);
  83.  
  84.         //automatically set up http client
  85.         $client = new Zend_Service_Photobucket_Oauth_Client($this->getOauthOptions(),
  86.                                                             self::$_api_url);
  87.         $client->setConfig(array('strictredirects' => true));
  88.         $this->setLocalHttpClient($client);
  89.  
  90.         if (!$token) $token = new Zend_Oauth_Token_Access();
  91.         $this->setToken($token);
  92.  
  93.         $this->setUri(self::$_api_url);
  94.     }
  95.  
  96.     public function setOauthOptions(array $opts, $no_base = false) {
  97.         if ($no_base) $this->_oauthOptions = $opts;
  98.         else $this->_oauthOptions = array_merge(self::$baseOauthOptions, $opts);
  99.         if (!empty($this->_oauthOptions['appId'])) {
  100.             $this->setAppId($this->_oauthOptions['appId']);
  101.         }
  102.         return $this;
  103.     }
  104.     public function getOauthOptions() {
  105.         return $this->_oauthOptions;
  106.     }
  107.     public function getOauthConsumer() {
  108.         return new Zend_Oauth_Consumer($this->getOauthOptions());
  109.     }
  110.  
  111.     /**
  112.      * setLocalHttpClient
  113.      *
  114.      * @param Zend_Oauth_Client $client client to use
  115.      * @return self
  116.      */
  117.     public function setLocalHttpClient(Zend_Oauth_Client $client) {
  118.         $this->_localHttpClient = $client;
  119.         return $this;
  120.     }
  121.  
  122.     /**
  123.      * getLocalHttpClient
  124.      *
  125.      * @return Zend_Oauth_Client
  126.      */
  127.     public function getLocalHttpClient() {
  128.         return $this->_localHttpClient;
  129.     }
  130.  
  131.     /**
  132.      * set User name
  133.      *
  134.      * @param string $username
  135.      * @return self
  136.      */
  137.     public function setUsername($username) {
  138.         $this->_username = $username;
  139.         return $this;
  140.     }
  141.  
  142.     /**
  143.      * get User name
  144.      *
  145.      * @return string
  146.      */
  147.     public function getUsername() {
  148.         return $this->_username;
  149.     }
  150.  
  151.     public function setToken($token = null) {
  152.         if ($token !== null && !($token instanceof Zend_Oauth_Token_Access)) {
  153.             throw new Zend_Service_Photobucket_Exception('Bad Token');
  154.         }
  155.         $this->_token = $token;
  156.         $this->getLocalHttpClient()->setToken($token);
  157.         return $this;
  158.     }
  159.  
  160.     public function getToken() {
  161.         return $this->_token;
  162.     }
  163.  
  164.     /**
  165.      * Set the URI to use in the request
  166.      *
  167.      * @param string|Zend_Uri_Http $uri URI for the web service
  168.      * @return Zend_Rest_Client
  169.      */
  170.     public function setUri($uri) {
  171.         if ($uri instanceof Zend_Uri) {
  172.             $this->_uri = $uri;
  173.         } else {
  174.             $this->_uri = Zend_Uri::factory($uri);
  175.         }
  176.  
  177.         return $this;
  178.     }
  179.  
  180.     /**
  181.      * Retrieve the current request URI object
  182.      *
  183.      * @return Zend_Uri_Http
  184.      */
  185.     public function getUri() {
  186.         return $this->_uri;
  187.     }
  188.  
  189.     public function setResponseType($type) {
  190.         $this->_response_type = $type;
  191.         return $this;
  192.     }
  193.     public function getResponseType($override = null) {
  194.         if ($override) return $override;
  195.         return $this->_response_type;
  196.     }
  197.  
  198.     /**
  199.      * Call method
  200.      *
  201.      * Any formal error encountered is thrown as an exception.
  202.      *
  203.      * @param mixed $method HTTP Method to call
  204.      * @param array $path   path to call
  205.      * @param array $args   Arguments to send
  206.      * @param bool $responeseType if json or xml, will be parsed automatically
  207.      *
  208.      * @return string response
  209.      */
  210.     public function callMethod($method, $path, $args = array(), $responseType = null) {
  211.         $this->_prepare($path);
  212.         $args['format'] = $this->getResponseType($responseType);
  213.  
  214.         $client = $this->getLocalHttpClient();
  215.         $client->setMethod($method);
  216.  
  217.         switch ($method) {
  218.             case Zend_Oauth_Client::GET:
  219.             case Zend_Oauth_Client::PUT:
  220.             case Zend_Oauth_Client::DELETE:
  221.                 $client->setParameterGet($args);
  222.                 break;
  223.             case Zend_Oauth_Client::POST:
  224.                 $client->setParameterPost($args);
  225.                 break;
  226.         }
  227.  
  228.         try {
  229.             $response = $client->request($method);
  230.         } catch (Exception $e) {
  231.             throw new Zend_Service_Photobucket_Exception($e->getMessage(), $e->getCode());
  232.         }
  233.  
  234.         return $this->parseResponse($response->getBody(), $responseType);
  235.     }
  236.  
  237.     public function callUpload($path, $files, array $args = array(), $responseType = null) {
  238.         $this->_prepare($path);
  239.         $args['format'] = $this->getResponseType($responseType);
  240.  
  241.         $client = $this->getLocalHttpClient();
  242.         $client->setMethod('POST');
  243.  
  244.         $client->setParameterPost($args);
  245.         if (!is_array($files)) {
  246.             $files = array('uploadfile'=>$files);
  247.         }
  248.         foreach ($files as $name => $fn) {
  249.             $client->setFileUpload($fn, $name);
  250.         }
  251.  
  252.         try {
  253.             $response = $client->request('POST');
  254.         } catch (Exception $e) {
  255.             throw new Zend_Service_Photobucket_Exception($e->getMessage(), $e->getCode());
  256.         }
  257.  
  258.         return $this->parseResponse($response->getBody(), $responseType);
  259.     }
  260.  
  261.     /**
  262.      * parseResponse
  263.      *
  264.      * Parses the raw response from Myspace
  265.      *
  266.      * @param string $responseBody Response text unparsed
  267.      * @param string $responseType format of response expected to parse
  268.      *
  269.      * @return mixed Parsed response
  270.      */
  271.     protected function parseResponse($responseBody, $responseType = null) {
  272.         $responseType = $this->getResponseType($responseType);
  273.  
  274.         switch ($responseType) {
  275.             case self::RESPONSE_TYPE_JSON:
  276.                 $result = Zend_Json::decode($responseBody, Zend_Json::TYPE_OBJECT);
  277.                 break;
  278.             case self::RESPONSE_TYPE_XML:
  279.                 $result = simplexml_load_string($responseBody);
  280.                 break;
  281.             case self::RESPONSE_TYPE_PHP:
  282.                 $result = unserialize($responseBody);
  283.                 break;
  284.             case self::RESPONSE_TYPE_RAW:
  285.                 parse_str($responseBody, $result);
  286.                 break;
  287.             default:
  288.                 //unknown type
  289.                 $result = $responseBody;
  290.         }
  291.  
  292.         return $result;
  293.     }
  294.  
  295.     /**
  296.      * Update arguments
  297.      *
  298.      * Updates the arguments with
  299.      * * response type
  300.      * * URL
  301.      *
  302.      * @param string $method Method being called
  303.      * @param string $path path being called
  304.      * @param array $args  Arguments being sent
  305.      *
  306.      * @return self
  307.      */
  308.     protected function _prepare($path) {
  309.         //set path
  310.         $uri = $this->getUri();
  311.         $uri->setPath(rtrim($path,'/'));
  312.         $uri->setQuery('');
  313.  
  314.         $this->getLocalHttpClient()->resetParameters()->setUri($uri);
  315.         return $this;
  316.     }
  317.  
  318.     public function __get($name) {
  319.         $name = strtolower($name);
  320.         return $this->loadMethods($name);
  321.     }
  322.  
  323.     protected $_knownMethodClasses = array();
  324.     public function setMethodClass($name, Zend_Service_Photobucket_Methods $obj) {
  325.         $name = strtolower($name);
  326.         $this->_knownMethodClasses[$name] = $obj;
  327.         return $this;
  328.     }
  329.  
  330.     public function loadMethods($name) {
  331.         $name = strtolower($name);
  332.         if (!empty($this->_knownMethodClasses[$name])) return $this->_knownMethodClasses[$name];
  333.  
  334.         $class = $this->getMethodsClassName($name);
  335.         require_once $this->getMethodsClassPath($name);
  336.  
  337.         return $this->_knownMethodClasses[$name] = new $class($this);
  338.     }
  339.  
  340.     protected function getMethodsClassPath($name) {
  341.         return dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Photobucket'
  342.             . DIRECTORY_SEPARATOR . 'Methods'
  343.             . DIRECTORY_SEPARATOR . ucfirst($name) . '.php';
  344.     }
  345.  
  346.     protected function getMethodsClassName($name) {
  347.         return __CLASS__ . '_Methods_' . ucfirst($name);
  348.     }
  349.  
  350.     public function ping(array $params = array(), $method = 'GET') {
  351.         return $this->callMethod($method, '/ping', $params);
  352.     }
  353.     public function time() {
  354.         $client = $this->getLocalHttpClient();
  355.         $client->setMethod(Zend_Oauth_Client::GET);
  356.  
  357.         try {
  358.             $response = $client->request(Zend_Oauth_Client::GET);
  359.         } catch (Exception $e) {
  360.             throw new Zend_Service_Photobucket_Exception($e->getMessage(), $e->getCode());
  361.         }
  362.  
  363.         return $response->getBody();
  364.     }
  365. }
  366.  
  367.