Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[

Zend Framework: Zend_Service_Audioscrobbler Component Proposal

Proposed Component Name Zend_Service_Audioscrobbler
Developer Notes http://framework.zend.com/wiki/display/ZFDEV/Zend_Service_Audioscrobbler
Proposers Chris Hartjes
Derek Martin
Revision 1.0 - 1 July 2006 (wiki revision: 21)

Table of Contents

1. Overview

Zend_Service_Audioscrobbler provides a simple API to access Audioscrobbler's web services

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

  • A simple API for accessing Audioscrobbler's web services

4. Dependencies on Other Framework Components

  • Zend_Service_Rest
  • Zend_Service_Exception

5. Theory of Operation

Results from Audioscrobbler's REST services are returned as SimpleXML objects, otherwise a Zend_Service_Exception is thrown containing an informative error message.

6. Milestones / Tasks

alpha 0.01 released November 15th, 2006

7. Class Index

  • Zend_Service_Audioscrobbler

8. Use Cases

UC-01
UC-02
UC-03

9. Class Skeletons

Zend_Service_Audioscrobbler __construct ()
void albumGetInfo ()
SimpleXML artistGetRelatedArtists ()
SimpleXML artistGetTopAlbums ()
SimpleXML artistGetTopFans ()
SimpleXML artistGetTopTags ()
SimpleXML artistGetTopTracks ()
void get ( $field, string $key)
void group ()
void groupGetWeeklyArtistChartList ()
void groupGetWeeklyChartList ()
void set (string $field, $value, string $val)
void tagGetTopArtists ()
void tagGetTopTags ()
void tagGetTopTracks ()
void trackGetTopFans ()
void trackGetTopTags ()
SimpleXML userGetFriends ()
SimpleXML userGetNeighbours ()
array userGetProfileInformation ()
SimpleXML userGetRecentBannedTracks ()
SimpleXML userGetRecentLovedTracks ()
SimpleXML userGetRecentTracks ()
SimpleXML userGetTopAlbums ()
array userGetTopArtists ()
SimpleXML userGetTopTags ()
SimpleXML userGetTopTagsForAlbum ()
SimpleXML userGetTopTagsForArtist ()
SimpleXML userGetTopTagsForTrack ()
SimpleXML userGetTopTracks ()
SimpleXML userGetWeeklyAlbumChart ($from, $to)
SimpleXML userGetWeeklyArtistChart ($from, $to)
SimpleXML userGetWeeklyChartList ()
SimpleXML userGetWeeklyTrackChart ($from, $to)

]]></ac:plain-text-body></ac:macro>

]]></ac:plain-text-body></ac:macro>

Labels:
zend_service_audioscrobbler zend_service_audioscrobbler Delete
proposal proposal Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jul 11, 2006

    <p>I'll confess that I don't know what Audioscrobbler is, but surely there is a better way to implement an interface to it than a class with almost 60 methods. <ac:emoticon ac:name="wink" /> Isn't it possible to split it up somehow?</p>

  2. Jul 29, 2006

    <p>Hi Matthew. </p>

    <p>Audioscrobbler is a site that tracks what you listen to via their iTunes/Winamp/etc plug-in installed, or via streaming audio at <a class="external-link" href="http://www.last.fm">http://www.last.fm</a></p>

    <p>Our goal was to simply provide a php interface to Audioscrobbler's existing web service. There is a 1:1 correlation between our methods and their service URLs, right down to the method naming.</p>

    <p>We would have loved not to have 60 methods, but then our API wouldn't correlate to theirs. Plus, that would have meant more thinking for us <ac:emoticon ac:name="wink" /></p>

    <p>ttys,</p>

    <p>Derek</p>

    1. Aug 28, 2006

      <p>Perhaps you could use __call to transparently pass methods to the Audioscrobbler object and then throw an error only if the Audioscrobbler method is non-existent? It would mean a much leaner component and probably a lot less work to maintain it whenever the service is upgraded.</p>

      1. Sep 28, 2006

        <p>I haven't used __call much so I'll take a look at that. If it makes for a better component, I'm definitely in favour of it.</p>

    2. Sep 28, 2006

      <p>Yeah, I've been doing a bunch of work on this lately and have simplified a lot of the function calls to minimize duplication. Check out the latest in SVN in the incubator</p>

  3. Jul 30, 2006

    <p>I use Last.fm and I love it, but I must ask, is the framework a good place to have this? I see uses for the Amazon, Flickr and Yahoo! service implementations, but how would this one be beneficial to the framework apart from providing some interaction with the framework?</p>

    1. Aug 28, 2006

      <blockquote>
      <p>Subject: RE: <ac:link><ri:page ri:content-title="fw-general" /></ac:link> MIA – orm & acl?<br />
      Date: Tue, 11 Jul 2006 16:08:23 -0700<br />
      From: Andi Gutmans <andi@zend.com></p>

      <p>Well I don't know about AudioScrobbler specifically as I haven't reviewed it<br />
      yet, but all Zend_Service_* contributions are very important IMO. We are<br />
      planning to review them very soon and we'd definitely like the amount of<br />
      out-of-the-box sevices in Zend Framework grow rapidly. We think although it<br />
      might not be difficult to consume many of these services with standard PHP,<br />
      having concrete implementations in the Zend Framework will make them even<br />
      easier to use.</p>

      <p>It'd be extremely cool if this would become the best place to use any of the<br />
      popular Web Services on the Internet. </p></blockquote>

  4. Aug 29, 2006

    <ac:macro ac:name="note"><ac:parameter ac:name="title">Zend Comments</ac:parameter><ac:rich-text-body>
    <p>The proposal is approved on the condition that the following issues are addressed by the proposal author.</p>

    <p>Public properties make the <code>set*</code> methods redundant. Ideas for resolution:</p>

    <ul>
    <li>Change the properties to be protected and using the existing <code>set*</code> methods along with new corresponding <code>get*</code> methods.</li>
    <li>Override <code>_get()</code> and <code>_set()</code>, storing properties in a protected array.</li>
    </ul>

    <p>Another option would be to pass the "properties" as method arguments:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    <?php
    $as = new Zend_Service_Audioscrobbler();
    $profileInfo = $as->userGetProfileInformation('BigDaddy71');
    $relatedArtists = $as->artistGetRelatedArtists('LCD Soundsystem');
    // ...
    ?>
    ]]></ac:plain-text-body></ac:macro>

    <p>No underscores within variable names and compliance with other <a href="http://framework.zend.com/wiki/x/PQ">coding standards</a>.</p>

    <p>What is the reason that <code>setDate()</code> and <code>getInfo()</code> methods are designated private? Should they not be inherited and accessible by subclasses, and if so, why not?</p>

    <p>We should leverage Zend_Date as it becomes available for date-specific operations.</p>

    <p>How do Zend_Service_Audioscrobbler and the Audioscrobbler web services support limiting the number of records returned by a request?</p>

    <p>The API presented causes extra effort to programmatically select functionality, due to the practice of essentially embedding options into the method names. Usually function names accept parameters to select between different, related behaviors. For example, the proposal shows:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    public function userGetRecentWeeklyArtistChart()
    public function userGetRecentWeeklyAlbumChart()
    public function userGetRecentWeeklyTrackChart()
    public function userGetPreviousWeeklyArtistChart()
    public function userGetPreviousWeeklyAlbumChart()
    public function userGetPreviousWeeklyTrackChart()
    ]]></ac:plain-text-body></ac:macro>

    <p>Using class constants having string values we could nicely refactor the above list of methods to something like:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    getChart($type, $recent = true)
    ]]></ac:plain-text-body></ac:macro>

    <p>Similarly, what about:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    // source = 'user' | 'artist'
    // type = 'artists' | 'albums' | 'tracks' | etc.
    getTop($source, $type)
    ]]></ac:plain-text-body></ac:macro>
    </ac:rich-text-body></ac:macro>

    1. Sep 28, 2006

      <p>Hi Darby,</p>

      <p>I've finally managed to set some time aside to address these issues. Here are my thoughts:</p>

      <ul>
      <li>I'll make the variables protected and user get and set methods as appropriate</li>
      </ul>

      <p>That really does make sense and is consistent</p>

      <ul>
      <li>I'll remove the underscores to make it compliant with coding standards</li>
      </ul>

      <ul>
      <li>Zend_Date is a good idea for the time stamp parameters, but Audioscrobbler currently only accepts timestamps so the ability to convert would be ok</li>
      </ul>

      <ul>
      <li>I'm not sure if Audioscrobbler limits the result sets it sends out, I will ask them</li>
      </ul>

      <ul>
      <li>I've massively simplified the API to reduce the number of functions</li>
      </ul>

      <p>That was just silly on our part in the first place <ac:emoticon ac:name="wink" /></p>

      <ul>
      <li>I will investigate how I might make something work like your suggestion on an API with calls like getTop($source, $type, $params = NULL) to make it look really slick.</li>
      </ul>

      <p>Thanks again for all the great suggestions.</p>

  5. Mar 30, 2007

    <p>Thank you for implementing the interface to the Audioscrobbler web service in Zend Framework! Currently, there is an annoying bug in the private getInfo() method, though. The following code example:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    $as = new Zend_Service_Audioscrobbler();
    $as->set('artist', 'This is an unknown artist.');
    $as->set('track', 'Track does not matter.');
    $tags = $as->trackGetTopTags();
    ]]></ac:plain-text-body></ac:macro>

    <p>results in a PHP Fatal error:</p>

    <p>PHP Fatal error: Call to a member function getStatus() on a non-object in /var/httpd/servers/noise.graefe.net/lib/ZendFramework-0.9.1-Beta/library/Zend/Service/Audioscrobbler.php on line 165</p>

    <p>My suggestion is to change the error handling in getInfo() to something like this:</p>

    <ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
    if ($response == 'No such path') {
    throw new Zend_Http_Client_Exception('Could not find: ' . $this->_client->getUri());
    } else if ($request->isError()) {
    if (is_object($response))

    Unknown macro: { throw new Zend_Http_Client_Exception('The web service ' . $this->_client->getUri() . ' returned the following status code}

    else

    Unknown macro: { throw new Zend_Http_Client_Exception( $response ); }

    } else {
    return simplexml_load_string($response);
    }
    ]]></ac:plain-text-body></ac:macro>

    <p>I would have opened an issue in the tracker but either I'm to blind to find the button to do so, or I'm not allowed to. <ac:emoticon ac:name="smile" /></p>