File indexing completed on 2024-05-19 06:03:36

0001 <?php
0002 
0003 /**
0004  * Zend Framework
0005  *
0006  * LICENSE
0007  *
0008  * This source file is subject to the new BSD license that is bundled
0009  * with this package in the file LICENSE.txt.
0010  * It is also available through the world-wide-web at this URL:
0011  * http://framework.zend.com/license/new-bsd
0012  * If you did not receive a copy of the license and are unable to
0013  * obtain it through the world-wide-web, please send an email
0014  * to license@zend.com so we can send you a copy immediately.
0015  *
0016  * @category   Zend
0017  * @package    Zend_Service
0018  * @subpackage Audioscrobbler
0019  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0020  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0021  * @version    $Id$
0022  */
0023 
0024 
0025 /**
0026  * @see Zend_Http_Client
0027  */
0028 // require_once 'Zend/Http/Client.php';
0029 
0030 /** @see Zend_Xml_Security */
0031 // require_once 'Zend/Xml/Security.php';
0032 
0033 /**
0034  * @category   Zend
0035  * @package    Zend_Service
0036  * @subpackage Audioscrobbler
0037  * @copyright  Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
0038  * @license    http://framework.zend.com/license/new-bsd     New BSD License
0039  */
0040 class Zend_Service_Audioscrobbler
0041 {
0042     /**
0043      * Zend_Http_Client Object
0044      *
0045      * @var     Zend_Http_Client
0046      * @access  protected
0047      */
0048     protected $_client;
0049 
0050     /**
0051      * Array that contains parameters being used by the webservice
0052      *
0053      * @var     array
0054      * @access  protected
0055      */
0056     protected $_params;
0057 
0058     /**
0059      * Holds error information (e.g., for handling simplexml_load_string() warnings)
0060      *
0061      * @var     array
0062      * @access  protected
0063      */
0064     protected $_error = null;
0065 
0066 
0067     /**
0068      * Sets up character encoding, instantiates the HTTP client, and assigns the web service version.
0069      */
0070     public function __construct()
0071     {
0072         $this->set('version', '1.0');
0073 
0074         if (PHP_VERSION_ID < 50600) {
0075             iconv_set_encoding('output_encoding', 'UTF-8');
0076             iconv_set_encoding('input_encoding', 'UTF-8');
0077             iconv_set_encoding('internal_encoding', 'UTF-8');
0078         } else {
0079             ini_set('output_encoding', 'UTF-8');
0080             ini_set('input_encoding', 'UTF-8');
0081             ini_set('default_charset', 'UTF-8');
0082         }
0083     }
0084 
0085     /**
0086      * Set Http Client
0087      *
0088      * @param Zend_Http_Client $client
0089      */
0090     public function setHttpClient(Zend_Http_Client $client)
0091     {
0092         $this->_client = $client;
0093     }
0094 
0095     /**
0096      * Get current http client.
0097      *
0098      * @return Zend_Http_Client
0099      */
0100     public function getHttpClient()
0101     {
0102         if($this->_client == null) {
0103             $this->lazyLoadHttpClient();
0104         }
0105         return $this->_client;
0106     }
0107 
0108     /**
0109      * Lazy load Http Client if none is instantiated yet.
0110      *
0111      * @return void
0112      */
0113     protected function lazyLoadHttpClient()
0114     {
0115         $this->_client = new Zend_Http_Client();
0116     }
0117 
0118     /**
0119      * Returns a field value, or false if the named field does not exist
0120      *
0121      * @param  string $field
0122      * @return string|false
0123      */
0124     public function get($field)
0125     {
0126         if (array_key_exists($field, $this->_params)) {
0127             return $this->_params[$field];
0128         } else {
0129             return false;
0130         }
0131     }
0132 
0133     /**
0134      * Generic set action for a field in the parameters being used
0135      *
0136      * @param  string $field name of field to set
0137      * @param  string $value value to assign to the named field
0138      * @return Zend_Service_Audioscrobbler Provides a fluent interface
0139      */
0140     public function set($field, $value)
0141     {
0142         $this->_params[$field] = urlencode($value);
0143 
0144         return $this;
0145     }
0146 
0147     /**
0148      * Protected method that queries REST service and returns SimpleXML response set
0149      *
0150      * @param  string $service name of Audioscrobbler service file we're accessing
0151      * @param  string $params  parameters that we send to the service if needded
0152      * @throws Zend_Http_Client_Exception
0153      * @throws Zend_Service_Exception
0154      * @return SimpleXMLElement result set
0155      * @access protected
0156      */
0157     protected function _getInfo($service, $params = null)
0158     {
0159         $service = (string) $service;
0160         $params  = (string) $params;
0161 
0162         if ($params === '') {
0163             $this->getHttpClient()->setUri("http://ws.audioscrobbler.com{$service}");
0164         } else {
0165             $this->getHttpClient()->setUri("http://ws.audioscrobbler.com{$service}?{$params}");
0166         }
0167 
0168         $response     = $this->getHttpClient()->request();
0169         $responseBody = $response->getBody();
0170 
0171         if (preg_match('/No such path/', $responseBody)) {
0172             /**
0173              * @see Zend_Http_Client_Exception
0174              */
0175             // require_once 'Zend/Http/Client/Exception.php';
0176             throw new Zend_Http_Client_Exception('Could not find: ' . $this->_client->getUri());
0177         } elseif (preg_match('/No user exists with this name/', $responseBody)) {
0178             /**
0179              * @see Zend_Http_Client_Exception
0180              */
0181             // require_once 'Zend/Http/Client/Exception.php';
0182             throw new Zend_Http_Client_Exception('No user exists with this name');
0183         } elseif (!$response->isSuccessful()) {
0184             /**
0185              * @see Zend_Http_Client_Exception
0186              */
0187             // require_once 'Zend/Http/Client/Exception.php';
0188             throw new Zend_Http_Client_Exception('The web service ' . $this->_client->getUri() . ' returned the following status code: ' . $response->getStatus());
0189         }
0190 
0191         set_error_handler(array($this, '_errorHandler'));
0192 
0193         if (!$simpleXmlElementResponse = Zend_Xml_Security::scan($responseBody)) {
0194             restore_error_handler();
0195             /**
0196              * @see Zend_Service_Exception
0197              */
0198             // require_once 'Zend/Service/Exception.php';
0199             $exception = new Zend_Service_Exception('Response failed to load with SimpleXML');
0200             $exception->error    = $this->_error;
0201             $exception->response = $responseBody;
0202             throw $exception;
0203         }
0204 
0205         restore_error_handler();
0206 
0207         return $simpleXmlElementResponse;
0208     }
0209 
0210     /**
0211     * Utility function to get Audioscrobbler profile information (eg: Name, Gender)
0212      *
0213     * @return array containing information
0214     */
0215     public function userGetProfileInformation()
0216     {
0217         $service = "/{$this->get('version')}/user/{$this->get('user')}/profile.xml";
0218         return $this->_getInfo($service);
0219     }
0220 
0221     /**
0222      * Utility function get this user's 50 most played artists
0223      *
0224      * @return array containing info
0225     */
0226     public function userGetTopArtists()
0227     {
0228         $service = "/{$this->get('version')}/user/{$this->get('user')}/topartists.xml";
0229         return $this->_getInfo($service);
0230     }
0231 
0232     /**
0233      * Utility function to get this user's 50 most played albums
0234      *
0235      * @return SimpleXMLElement object containing result set
0236     */
0237     public function userGetTopAlbums()
0238     {
0239         $service = "/{$this->get('version')}/user/{$this->get('user')}/topalbums.xml";
0240         return $this->_getInfo($service);
0241     }
0242 
0243     /**
0244      * Utility function to get this user's 50 most played tracks
0245      * @return SimpleXML object containing resut set
0246     */
0247     public function userGetTopTracks()
0248     {
0249         $service = "/{$this->get('version')}/user/{$this->get('user')}/toptracks.xml";
0250         return $this->_getInfo($service);
0251     }
0252 
0253     /**
0254      * Utility function to get this user's 50 most used tags
0255      *
0256      * @return SimpleXMLElement object containing result set
0257      */
0258     public function userGetTopTags()
0259     {
0260         $service = "/{$this->get('version')}/user/{$this->get('user')}/tags.xml";
0261         return $this->_getInfo($service);
0262     }
0263 
0264     /**
0265      * Utility function that returns the user's top tags used most used on a specific artist
0266      *
0267      * @return SimpleXMLElement object containing result set
0268      */
0269     public function userGetTopTagsForArtist()
0270     {
0271         $service = "/{$this->get('version')}/user/{$this->get('user')}/artisttags.xml";
0272         $params = "artist={$this->get('artist')}";
0273         return $this->_getInfo($service, $params);
0274     }
0275 
0276     /**
0277      * Utility function that returns this user's top tags for an album
0278      *
0279      * @return SimpleXMLElement object containing result set
0280      */
0281     public function userGetTopTagsForAlbum()
0282     {
0283         $service = "/{$this->get('version')}/user/{$this->get('user')}/albumtags.xml";
0284         $params = "artist={$this->get('artist')}&album={$this->get('album')}";
0285         return $this->_getInfo($service, $params);
0286     }
0287 
0288     /**
0289      * Utility function that returns this user's top tags for a track
0290      *
0291      * @return SimpleXMLElement object containing result set
0292      */
0293     public function userGetTopTagsForTrack()
0294     {
0295         $service = "/{$this->get('version')}/user/{$this->get('user')}/tracktags.xml";
0296         $params = "artist={$this->get('artist')}&track={$this->get('track')}";
0297         return $this->_getInfo($service, $params);
0298     }
0299 
0300     /**
0301      * Utility function that retrieves this user's list of friends
0302      * @return SimpleXMLElement object containing result set
0303      */
0304     public function userGetFriends()
0305     {
0306         $service = "/{$this->get('version')}/user/{$this->get('user')}/friends.xml";
0307         return $this->_getInfo($service);
0308     }
0309 
0310     /**
0311      * Utility function that returns a list of people with similar listening preferences to this user
0312      *
0313      * @return SimpleXMLElement object containing result set
0314      */
0315     public function userGetNeighbours()
0316     {
0317         $service = "/{$this->get('version')}/user/{$this->get('user')}/neighbours.xml";
0318         return $this->_getInfo($service);
0319     }
0320 
0321     /**
0322      * Utility function that returns a list of the 10 most recent tracks played by this user
0323      *
0324      * @return SimpleXMLElement object containing result set
0325      */
0326     public function userGetRecentTracks()
0327     {
0328         $service = "/{$this->get('version')}/user/{$this->get('user')}/recenttracks.xml";
0329         return $this->_getInfo($service);
0330     }
0331 
0332     /**
0333      * Utility function that returns a list of the 10 tracks most recently banned by this user
0334      *
0335      * @return SimpleXMLElement object containing result set
0336      */
0337     public function userGetRecentBannedTracks()
0338     {
0339         $service = "/{$this->get('version')}/user/{$this->get('user')}/recentbannedtracks.xml";
0340         return $this->_getInfo($service);
0341     }
0342 
0343     /**
0344      * Utility function that returns a list of the 10 tracks most recently loved by this user
0345      *
0346      * @return SimpleXMLElement object containing result set
0347      */
0348     public function userGetRecentLovedTracks()
0349     {
0350         $service = "/{$this->get('version')}/user/{$this->get('user')}/recentlovedtracks.xml";
0351         return $this->_getInfo($service);
0352     }
0353 
0354     /**
0355      * Utility function that returns a list of dates of available weekly charts for a this user
0356      *
0357      * Should actually be named userGetWeeklyChartDateList() but we have to follow audioscrobbler's naming
0358      *
0359      * @return SimpleXMLElement object containing result set
0360      */
0361     public function userGetWeeklyChartList()
0362     {
0363         $service = "/{$this->get('version')}/user/{$this->get('user')}/weeklychartlist.xml";
0364         return $this->_getInfo($service);
0365     }
0366 
0367 
0368     /**
0369      * Utility function that returns weekly album chart data for this user
0370      *
0371      * @param integer $from optional UNIX timestamp for start of date range
0372      * @param integer $to optional UNIX timestamp for end of date range
0373      * @return SimpleXMLElement object containing result set
0374      */
0375     public function userGetWeeklyAlbumChart($from = NULL, $to = NULL)
0376     {
0377         $params = "";
0378 
0379         if ($from != NULL && $to != NULL) {
0380             $from = (int)$from;
0381             $to = (int)$to;
0382             $params = "from={$from}&to={$to}";
0383         }
0384 
0385         $service = "/{$this->get('version')}/user/{$this->get('user')}/weeklyalbumchart.xml";
0386         return $this->_getInfo($service, $params);
0387     }
0388 
0389     /**
0390      * Utility function that returns weekly artist chart data for this user
0391      *
0392      * @param integer $from optional UNIX timestamp for start of date range
0393      * @param integer $to optional UNIX timestamp for end of date range
0394      * @return SimpleXMLElement object containing result set
0395      */
0396     public function userGetWeeklyArtistChart($from = NULL, $to = NULL)
0397     {
0398         $params = "";
0399 
0400         if ($from != NULL && $to != NULL) {
0401             $from = (int)$from;
0402             $to = (int)$to;
0403             $params = "from={$from}&to={$to}";
0404         }
0405 
0406         $service = "/{$this->get('version')}/user/{$this->get('user')}/weeklyartistchart.xml";
0407         return $this->_getInfo($service, $params);
0408     }
0409 
0410     /**
0411      * Utility function that returns weekly track chart data for this user
0412      *
0413      * @param integer $from optional UNIX timestamp for start of date range
0414      * @param integer $to optional UNIX timestamp for end of date range
0415      * @return SimpleXMLElement object containing result set
0416      */
0417     public function userGetWeeklyTrackChart($from = NULL, $to = NULL)
0418     {
0419         $params = "";
0420 
0421         if ($from != NULL && $to != NULL) {
0422             $from = (int)$from;
0423             $to = (int)$to;
0424             $params = "from={$from}&to={$to}";
0425         }
0426 
0427         $service = "/{$this->get('version')}/user/{$this->get('user')}/weeklytrackchart.xml";
0428         return $this->_getInfo($service, $params);
0429     }
0430 
0431 
0432     /**
0433      * Utility function that returns a list of artists similiar to this artist
0434      *
0435      * @return SimpleXMLElement object containing result set
0436      */
0437     public function artistGetRelatedArtists()
0438     {
0439         $service = "/{$this->get('version')}/artist/{$this->get('artist')}/similar.xml";
0440         return $this->_getInfo($service);
0441     }
0442 
0443     /**
0444      * Utility function that returns a list of this artist's top listeners
0445      *
0446      * @return SimpleXMLElement object containing result set
0447      */
0448     public function artistGetTopFans()
0449     {
0450         $service = "/{$this->get('version')}/artist/{$this->get('artist')}/fans.xml";
0451         return $this->_getInfo($service);
0452     }
0453 
0454     /**
0455      * Utility function that returns a list of this artist's top-rated tracks
0456      *
0457      * @return SimpleXMLElement object containing result set
0458      */
0459     public function artistGetTopTracks()
0460     {
0461         $service = "/{$this->get('version')}/artist/{$this->get('artist')}/toptracks.xml";
0462         return $this->_getInfo($service);
0463     }
0464 
0465     /**
0466      * Utility function that returns a list of this artist's top-rated albums
0467      *
0468      * @return SimpleXMLElement object containing result set
0469      */
0470     public function artistGetTopAlbums()
0471     {
0472         $service = "/{$this->get('version')}/artist/{$this->get('artist')}/topalbums.xml";
0473         return $this->_getInfo($service);
0474     }
0475 
0476     /**
0477      * Utility function that returns a list of this artist's top-rated tags
0478      *
0479      * @return SimpleXMLElement object containing result set
0480      */
0481     public function artistGetTopTags()
0482     {
0483         $service = "/{$this->get('version')}/artist/{$this->get('artist')}/toptags.xml";
0484         return $this->_getInfo($service);
0485     }
0486 
0487 
0488     /**
0489      * Get information about an album
0490      *
0491      * @return SimpleXMLElement
0492      */
0493     public function albumGetInfo()
0494     {
0495         $service = "/{$this->get('version')}/album/{$this->get('artist')}/{$this->get('album')}/info.xml";
0496         return $this->_getInfo($service);
0497     }
0498 
0499     /**
0500      * Get top fans of the current track.
0501      *
0502      * @return SimpleXMLElement
0503      */
0504     public function trackGetTopFans()
0505     {
0506         $service = "/{$this->get('version')}/track/{$this->get('artist')}/{$this->get('track')}/fans.xml";
0507         return $this->_getInfo($service);
0508     }
0509 
0510     /**
0511      * Get top tags of the current track.
0512      *
0513      * @return SimpleXMLElement
0514      */
0515     public function trackGetTopTags()
0516     {
0517         $service = "/{$this->get('version')}/track/{$this->get('artist')}/{$this->get('track')}/toptags.xml";
0518         return $this->_getInfo($service);
0519     }
0520 
0521     /**
0522      * Get Top Tags.
0523      *
0524      * @return SimpleXMLElement
0525      */
0526     public function tagGetTopTags()
0527     {
0528         $service = "/{$this->get('version')}/tag/toptags.xml";
0529         return $this->_getInfo($service);
0530     }
0531 
0532     /**
0533      * Get top albums by current tag.
0534      *
0535      * @return SimpleXMLElement
0536      */
0537     public function tagGetTopAlbums()
0538     {
0539         $service = "/{$this->get('version')}/tag/{$this->get('tag')}/topalbums.xml";
0540         return $this->_getInfo($service);
0541     }
0542 
0543     /**
0544      * Get top artists by current tag.
0545      *
0546      * @return SimpleXMLElement
0547      */
0548     public function tagGetTopArtists()
0549     {
0550         $service = "/{$this->get('version')}/tag/{$this->get('tag')}/topartists.xml";
0551         return $this->_getInfo($service);
0552     }
0553 
0554     /**
0555      * Get Top Tracks by currently set tag.
0556      *
0557      * @return SimpleXMLElement
0558      */
0559     public function tagGetTopTracks()
0560     {
0561         $service = "/{$this->get('version')}/tag/{$this->get('tag')}/toptracks.xml";
0562         return $this->_getInfo($service);
0563     }
0564 
0565     /**
0566      * Get weekly chart list by current set group.
0567      *
0568      * @see set()
0569      * @return SimpleXMLElement
0570      */
0571     public function groupGetWeeklyChartList()
0572     {
0573         $service = "/{$this->get('version')}/group/{$this->get('group')}/weeklychartlist.xml";
0574         return $this->_getInfo($service);
0575     }
0576 
0577     /**
0578      * Retrieve weekly Artist Charts
0579      *
0580      * @param  int $from
0581      * @param  int $to
0582      * @return SimpleXMLElement
0583      */
0584     public function groupGetWeeklyArtistChartList($from = NULL, $to = NULL)
0585     {
0586 
0587         if ($from != NULL && $to != NULL) {
0588             $from = (int)$from;
0589             $to = (int)$to;
0590             $params = "from={$from}&$to={$to}";
0591         } else {
0592             $params = "";
0593         }
0594 
0595         $service = "/{$this->get('version')}/group/{$this->get('group')}/weeklyartistchart.xml";
0596         return $this->_getInfo($service, $params);
0597     }
0598 
0599     /**
0600      * Retrieve Weekly Track Charts
0601      *
0602      * @param  int $from
0603      * @param  int $to
0604      * @return SimpleXMLElement
0605      */
0606     public function groupGetWeeklyTrackChartList($from = NULL, $to = NULL)
0607     {
0608         if ($from != NULL && $to != NULL) {
0609             $from = (int)$from;
0610             $to = (int)$to;
0611             $params = "from={$from}&to={$to}";
0612         } else {
0613             $params = "";
0614         }
0615 
0616         $service = "/{$this->get('version')}/group/{$this->get('group')}/weeklytrackchart.xml";
0617         return $this->_getInfo($service, $params);
0618     }
0619 
0620     /**
0621      * Retrieve Weekly album charts.
0622      *
0623      * @param int $from
0624      * @param int $to
0625      * @return SimpleXMLElement
0626      */
0627     public function groupGetWeeklyAlbumChartList($from = NULL, $to = NULL)
0628     {
0629         if ($from != NULL && $to != NULL) {
0630             $from = (int)$from;
0631             $to = (int)$to;
0632             $params = "from={$from}&to={$to}";
0633         } else {
0634             $params = "";
0635         }
0636 
0637         $service = "/{$this->get('version')}/group/{$this->get('group')}/weeklyalbumchart.xml";
0638         return $this->_getInfo($service, $params);
0639     }
0640 
0641     /**
0642      * Saves the provided error information to this instance
0643      *
0644      * @param  integer $errno
0645      * @param  string  $errstr
0646      * @param  string  $errfile
0647      * @param  integer $errline
0648      * @param  array   $errcontext
0649      * @return void
0650      */
0651     public function _errorHandler($errno, $errstr, $errfile, $errline, array $errcontext)
0652     {
0653         $this->_error = array(
0654             'errno'      => $errno,
0655             'errstr'     => $errstr,
0656             'errfile'    => $errfile,
0657             'errline'    => $errline,
0658             'errcontext' => $errcontext
0659             );
0660     }
0661 
0662     /**
0663      * Call Intercept for set($name, $field)
0664      *
0665      * @param  string $method
0666      * @param  array  $args
0667      * @return Zend_Service_Audioscrobbler
0668      */
0669     public function __call($method, $args)
0670     {
0671         if(substr($method, 0, 3) !== "set") {
0672             // require_once "Zend/Service/Exception.php";
0673             throw new Zend_Service_Exception(
0674                 "Method ".$method." does not exist in class Zend_Service_Audioscrobbler."
0675             );
0676         }
0677         $field = strtolower(substr($method, 3));
0678 
0679         if(!is_array($args) || count($args) != 1) {
0680             // require_once "Zend/Service/Exception.php";
0681             throw new Zend_Service_Exception(
0682                 "A value is required for setting a parameter field."
0683             );
0684         }
0685         $this->set($field, $args[0]);
0686 
0687         return $this;
0688     }
0689 }