Bitly.php

Go to the documentation of this file.
00001 <?php
00002 
00031 class Robo47_Service_Bitly extends Zend_Service_Abstract
00032 {
00036     const API_URL = 'http://api.bit.ly';
00037 
00041     const API_PATH_SHORTEN = '/shorten';
00042 
00046     const API_PATH_EXPAND = '/expand';
00047 
00051     const API_PATH_INFO = '/info';
00052 
00056     const API_PATH_STATS = '/stats';
00057 
00061     const API_PATH_ERRORS = '/errors';
00062 
00066     const FORMAT_JSON = 'json';
00067 
00071     const FORMAT_XML = 'xml';
00072 
00076     const FORMAT_RESULT_OBJECT = 'object';
00077 
00081     const FORMAT_RESULT_ARRAY = 'array';
00082 
00086     const FORMAT_RESULT_NATIVE = 'native';
00087 
00093     protected $_login = null;
00099     protected $_apiKey = null;
00105     protected $_version = null;
00113     protected $_format = Robo47_Service_Bitly::FORMAT_JSON;
00119     protected $_callback = '';
00128     protected $_resultFormat = Robo47_Service_Bitly::FORMAT_RESULT_NATIVE;
00129 
00139     public function __construct($login, $apiKey, $format = self::FORMAT_JSON,
00140         $resultFormat = self::FORMAT_RESULT_NATIVE,
00141         $callback = '', $version = '2.0.1')
00142     {
00143         $this->setLogin($login);
00144         $this->setApiKey($apiKey);
00145         $this->setFormat($format);
00146         $this->setResultFormat($resultFormat);
00147         $this->setCallback($callback);
00148         $this->setVersion($version);
00149     }
00150 
00159     public function setFormat($format)
00160     {
00161         $format = strtolower($format);
00162         switch ($format) {
00163             case self::FORMAT_JSON:
00164             case self::FORMAT_XML:
00165                 $this->_format = $format;
00166                 break;
00167             default:
00168                 $message = 'Invalid Format: ' . $format;
00169                 throw new Robo47_Service_Bitly_Exception($message);
00170         }
00171         return $this;
00172     }
00173 
00180     public function setCallback($callback)
00181     {
00182         $this->_callback = $callback;
00183         return $this;
00184     }
00185 
00191     public function getCallback()
00192     {
00193         return $this->_callback;
00194     }
00195 
00201     public function getFormat()
00202     {
00203         return $this->_format;
00204     }
00205 
00212     public function setVersion($version)
00213     {
00214         $this->_version = $version;
00215         return $this;
00216     }
00217 
00223     public function getVersion()
00224     {
00225         return $this->_version;
00226     }
00227 
00234     public function setLogin($login)
00235     {
00236         $this->_login = $login;
00237         return $this;
00238     }
00239 
00246     public function setApiKey($apiKey)
00247     {
00248         $this->_apiKey = $apiKey;
00249         return $this;
00250     }
00251 
00257     public function getLogin()
00258     {
00259         return $this->_login;
00260     }
00261 
00267     public function getApiKey()
00268     {
00269         return $this->_apiKey;
00270     }
00271 
00281     public function setResultFormat($resultFormat)
00282     {
00283         $resultFormat = strtolower($resultFormat);
00284         switch ($resultFormat) {
00285             case self::FORMAT_RESULT_NATIVE:
00286             case self::FORMAT_RESULT_ARRAY:
00287             case self::FORMAT_RESULT_OBJECT:
00288                 $this->_resultFormat = $resultFormat;
00289                 break;
00290             default:
00291                 $message = 'Invalid Result Format: ' . $resultFormat;
00292                 throw new Robo47_Service_Bitly_Exception($message);
00293         }
00294         return $this;
00295     }
00296 
00301     public function getResultFormat()
00302     {
00303         return $this->_resultFormat;
00304     }
00305 
00312     protected function _callApi($requestUri)
00313     {
00314         $httpClient = self::getHttpClient();
00315         $httpClient->setUri($requestUri);
00316         $response = $httpClient->request(Zend_Http_Client::GET);
00317         return $this->_getData($response);
00318     }
00319 
00325     public function xmlToArray($xml)
00326     {
00327         $document = new DOMDocument();
00328         $document->loadXml($xml);
00329         $array = array();
00330         foreach ($document->childNodes as $node) {
00331             $array[$node->nodeName] = $this->_nodeToArray($node);
00332         }
00333         return $array;
00334     }
00335 
00340     protected function _nodeToArray(DOMNode $node)
00341     {
00342         if ($node->hasChildNodes()) {
00343             $array = array();
00344             foreach ($node->childNodes as $childNode) {
00345                 /* @var $childNode DOMNode */
00346                 if ($childNode->nodeName == '#text' ||
00347                     $childNode->nodeName == '#cdata-section') {
00348                     $array = $this->_nodeToArray($childNode);
00349                 } else {
00350                     $nodeName = $childNode->nodeName;
00351                     $array[$nodeName] = $this->_nodeToArray($childNode);
00352                 }
00353             }
00354         } else {
00355             $array = $node->nodeValue;
00356 
00357         }
00358         return $array;
00359     }
00360 
00366     public function xmlToObject($xml)
00367     {
00368         $document = new DOMDocument();
00369         $document->loadXml($xml);
00370         $object = new StdClass();
00371         foreach ($document->childNodes as $node) {
00372             $object->{$node->nodeName} = $this->_nodeToObject($node);
00373         }
00374         return $object;
00375     }
00376 
00381     protected function _nodeToObject(DOMNode $node)
00382     {
00383         if ($node->hasChildNodes()) {
00384             $object = new stdClass();
00385             foreach ($node->childNodes as $childNode) {
00386                 /* @var $childNode DOMNode */
00387                 if ($childNode->nodeName == '#text' ||
00388                     $childNode->nodeName == '#cdata-section') {
00389                     $object = $this->_nodeToArray($childNode);
00390                 } else {
00391                     $nodeName = $childNode->nodeName;
00392                     $object->{$nodeName} = $this->_nodeToObject($childNode);
00393                 }
00394             }
00395         } else {
00396             $object = $node->nodeValue;
00397 
00398         }
00399         return $object;
00400     }
00401 
00409     protected function _getData(Zend_Http_Response $response)
00410     {
00411         if ($response->isError()) {
00412             $message = 'Error on api-call: ' . $response->getMessage();
00413             throw new Robo47_Service_Bitly_Exception($message);
00414         }
00415 
00416         // find errors without parsing xml / json
00417         // @todo parse formats always and move tests into the other switch
00418         //       and refactor a bit, method gets big and ugly
00419         switch ($this->_format) {
00420             case self::FORMAT_XML:
00421                 $regex = preg_quote('<errorCode>0</errorCode>', '/');
00422                 break;
00423             case self::FORMAT_JSON:
00424                 $regex = preg_quote('"errorCode": 0', '/');
00425                 break;
00426         }
00427         if (!preg_match('/' . $regex . '/i', $response->getBody())) {
00428             $message = 'Error on api-call: no errorCode=0 found';
00429             throw new Robo47_Service_Bitly_Exception($message);
00430         }
00431 
00432         // @todo checking for errors ALWAYS!
00433         switch ($this->_resultFormat) {
00434             case self::FORMAT_RESULT_NATIVE;
00435                 $result = $response->getBody();
00436                 break;
00437             case self::FORMAT_RESULT_ARRAY:
00438                 switch ($this->_format) {
00439                     case self::FORMAT_XML:
00440                         $result = $this->xmlToArray($response->getBody());
00441                         break;
00442                     case self::FORMAT_JSON:
00443                         $result = json_decode($response->getBody(), true);
00444                         break;
00445                 }
00446                 break;
00447             case self::FORMAT_RESULT_OBJECT:
00448                 switch ($this->_format) {
00449                     case self::FORMAT_XML:
00450                         $result = $this->xmlToObject($response->getBody());
00451                         break;
00452                     case self::FORMAT_JSON:
00453                         $result = json_decode($response->getBody(), false);
00454                         break;
00455                 }
00456                 break;
00457         }
00458         return $result;
00459     }
00460 
00468     public function generateUrl($path, array $params = array())
00469     {
00470         $defaultParams = array();
00471         $defaultParams['version'] = $this->_version;
00472         $defaultParams['login'] = $this->_login;
00473         $defaultParams['apiKey'] = $this->_apiKey;
00474         $defaultParams['format'] = $this->_format;
00475         if (self::FORMAT_JSON === $defaultParams['format'] &&
00476             !empty($this->_callback)) {
00477             $defaultParams['callback'] = $this->_callback;
00478         }
00479         $defaultParams = array_merge($defaultParams, $params);
00480 
00481         $url = Robo47_Service_Bitly::API_URL;
00482         $url .= $path . '?';
00483         $url .= http_build_query($defaultParams, null, '&');
00484         return $url;
00485     }
00486 
00493     public function shorten($longUrl)
00494     {
00495         $params = array('longUrl' => $longUrl);
00496         $url = $this->generateUrl(self::API_PATH_SHORTEN, $params);
00497         return $this->_callApi($url);
00498     }
00499 
00506     public function expandByShortUrl($shortUrl)
00507     {
00508         $params = array('shortUrl' => $shortUrl);
00509         $url = $this->generateUrl(self::API_PATH_EXPAND, $params);
00510         return $this->_callApi($url);
00511     }
00512 
00519     public function expandByHash($hash)
00520     {
00521         $params = array('hash' => $hash);
00522         $url = $this->generateUrl(self::API_PATH_EXPAND, $params);
00523         return $this->_callApi($url);
00524     }
00525 
00532     public function infoByShortUrl($shortUrl)
00533     {
00534         $params = array('shortUrl' => $shortUrl);
00535 
00536         $url = $this->generateUrl(self::API_PATH_INFO, $params);
00537         return $this->_callApi($url);
00538     }
00539 
00547     public function infoByShortUrlWithKeys($shortUrl, array $keys)
00548     {
00549         $params = array(
00550             'shortUrl' => $shortUrl,
00551             'keys' => implode(',', $keys),
00552         );
00553 
00554         $url = $this->generateUrl(self::API_PATH_INFO, $params);
00555         return $this->_callApi($url);
00556     }
00557 
00564     public function infoByHash($hash)
00565     {
00566         $params = array('hash' => $hash);
00567         $url = $this->generateUrl(self::API_PATH_INFO, $params);
00568         return $this->_callApi($url);
00569     }
00570 
00578     public function infoByHashWithKeys($hash, array $keys)
00579     {
00580         $params = array(
00581             'hash' => $hash,
00582             'keys' => implode(',', $keys),
00583         );
00584 
00585         $url = $this->generateUrl(self::API_PATH_INFO, $params);
00586         return $this->_callApi($url);
00587     }
00588 
00595     public function statsByShortUrl($shortUrl)
00596     {
00597         $params = array('shortUrl' => $shortUrl);
00598         $url = $this->generateUrl(self::API_PATH_STATS, $params);
00599         return $this->_callApi($url);
00600     }
00601 
00608     public function statsByHash($hash)
00609     {
00610         $params = array('hash' => $hash);
00611         $url = $this->generateUrl(self::API_PATH_STATS, $params);
00612         return $this->_callApi($url);
00613     }
00614 
00622     public function errors()
00623     {
00624         $url = $this->generateUrl(self::API_PATH_ERRORS, array());
00625         return $this->_callApi($url);
00626     }
00627 }