View Source

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFPROP:Proposal Zone Template}

{zone-data:component-name}
Zend_Service_Flickr
{zone-data}

{zone-data:proposer-list}
[Jurian Sluiman|mailto:subscribe@juriansluiman.nl]
{zone-data}

{zone-data:liaison}
TBD
{zone-data}

{zone-data:revision}
1.0 - 10 November 2009: Initial Draft.
{zone-data}

{zone-data:overview}
Zend_Service_Flickr is a component to fetch data from Flickr, using the available API. At this moment there is another Zend_Service_Flickr component, but this proposal is for a completely new and more feature rich component.

The component is initiated to provide a more user intuitive api to fetch data from Flickr. This means objects are instantiated for every user, photo, or set. This provides an api to use without knowledge about the Flickr api.

{tip:title=Code available}Current working implementation is hosted at Google Code: [Sozfo_Service_Flickr|http://code.google.com/p/sozfo/source/browse/#svn/trunk/library/Sozfo/Service/Flickr].{tip}

{info:title=Backwards compatibility}
Because the old Zend_Service_Flickr object has a complete different strucure, keeping backwards compatibility is almost impossible. The only method to do such, is merging both apis into one component or keeping the old one and name the new component differently (ZendX perhaps?).
{info}
{zone-data}

{zone-data:references}
* [Flickr|http://flickr.com]
* [Flickr API overview|http://www.flickr.com/services/api/]
* [Zend_Service_Flickr|http://framework.zend.com/manual/en/zend.service.flickr.html]
* [Sozfo_Service_Flickr|http://code.google.com/p/sozfo/source/browse/#svn/trunk/library/Sozfo/Service/Flickr]
{zone-data}

{zone-data:requirements}
* This component *will* use the Flickr API to handle requests concerning certain Flickr aspects.
* This component *will* be able to process authentication
* This component *will* be able to find users, photos, sets, collections, groups and tags
* This component *will not* be able to find activities, blogs, favorites, interestingness, machinetags, pandas, geolocation, comments, notes and places
* This component *will not* be able to write operations. Currently the scope is to have a feature rich, but read-only, component
{zone-data}

{zone-data:dependencies}
* Zend_Exception
* Zend_Cache
* Zend_Loader_PluginLoader
* Zend_Rest_Client
{zone-data}

{zone-data:operation}
This component has the idea of being intuitive to use, without knowlegde of the Flickr api and an ORM like class structure. The supported Flickr objects are translated into php classes and have methods to load related objects (user :: get photos, collection :: get sets, photo :: get tags etc).
The Flickr api is called in the REST format and returns a serialized php response.

With a factory method from the Zend_Service_Flickr class it's possible to instantiate all objects. These objects inherit an abstract class with methods to perform the actual request. Zend_Service_Flickr uses the plugin loader to load the appropriate classs. These classes needs to implement the Zend_Service_Flickr_Interface for api consistency.
{zone-data}

{zone-data:milestones}
* Milestone 1: Design notes ready at proposers wiki
* Milestone 2: Working prototype ready
* Milestone 3: Unit tests ready
* Milestone 4: Component included in the framework

If a milestone is already done, begin the description with "\[DONE\]", like this:
* Milestone #: \[DONE\] Unit tests ...
{zone-data}

{zone-data:class-list}
* Zend_Service_Flickr
* Zend_Service_Flickr_Abstract
* Zend_Service_Flickr_Auth
* Zend_Service_Flickr_Collection
* Zend_Service_Flickr_Exception
* Zend_Service_Flickr_Group
* Zend_Service_Flickr_Interface
* Zend_Service_Flickr_Photo
* Zend_Service_Flickr_Set
* Zend_Service_Flickr_Tag
* Zend_Service_Flickr_User
{zone-data}

{zone-data:use-cases}
{composition-setup}

{deck:id=use-cases1}
{card:label=UC 1: Find user's photos}
{code:type=php}
$flickr = new Zend_Service_Flickr;
$user = $flickr->factory('user')->find('my_username');
$photos = $user->getPhotos();

foreach ($photos as $photo) {
echo '<img src="' . $photo->location('thumbnail') . " alt="' . $photo->getTitle() . '">';
}
{code}
{card}

{card:label=UC 2: Collections and sets}
{code:type=php}
$flickr = new Zend_Service_Flickr;
$user = $flickr->factory('user')->find('my_username');
$collection = $flickr->factory('collection');

$tree = $collection->getTree($user);
foreach ($tree as $collection) {
echo '<h1>' . $collection->getTitle() . '</h1>';
if (null !== $collection->getSets()) {
echo '<ul>';
foreach ($collection->getSets() as $set) {
echo '<li>' . $set->getTitle() . '</li>';
}
echo '</ul>';
}
}
{code}
{card}

{deck}
{zone-data}

{zone-data:skeletons}
{code}
class Sozfo_Service_Flickr
{
protected $_loader;
protected $_store = array();
protected $_key;
protected $_secret;
protected $_token;
protected $_cache;

/**
* Set Fickr API key
* @param string $key
* @return Sozfo_Service_Flickr
*/
public function setKey ($key) {}

/**
* Get Flickr API key
* @return string
*/
public function getKey() {}

/**
* Set Flickr API secret
* @param string $secret
* @return Sozfo_Service_Flickr
*/
public function setSecret ($secret) {}

/**
* Get Flickr API secret
* @return string
*/
public function getSecret() {}

/**
* Set token from Flickr authentication
* @param string $token
* @return Sozfo_Service_Flickr
*/
public function setToken ($token) {}

/**
* Get token from Flickr authentication
* @return string
*/
public function getToken() {}

/**
* Set cache instance
* @param Zend_Cache_Core $cache
* @return Sozfo_Service_Flickr
*/
public function setCache (Zend_Cache_Core $cache) {}

/**
* Checks whether a cache instance is registered
* @return bool
*/
public function hasCache () {}

/**
* Get cache instance
* @return Zend_Cache_Core|void
*/
public function getCache () {}

/**
* Factory method to create Sozfo_Service_Flickr objects
*
* The factory method provides a generic interface to create
* all Sozfo_Service_Flickr_* objects. It registers this
* Sozfo_Service_Flickr instance to them automatically.
* @param string $name Object to create
* @param mixed $id Identification for the object, optionally
* @throws Sozfo_Service_Flickr_Exception When class could not be loaded
* @return mixed Object created by factory
*/
public function factory ($name, $id = null) {}

/**
* Getter for the pluginloader
* @return Zend_Loader_PluginLoader
*/
protected function _getLoader () {}
}

/**
* Exception thrown by the Sozfo_Service_Flickr and Sozfo_Service_Flickr_* objects
*/
class Sozfo_Service_Flickr_Exception extends Sozfo_Service_Exception {
}

/**
* Interface for all Sozfo_Service_Flickr_* objects
*/
interface Sozfo_Service_Flickr_Interface
{

function setBroker (Sozfo_Service_Flickr $broker);
}

/**
* Abstract implementation of the Sozfo_Service_Flickr_Interface
*/
abstract class Sozfo_Service_Flickr_Abstract implements Sozfo_Service_Flickr_Interface
{
/**
* Base for all Flickr requests
*/
const URI_BASE = 'http://www.flickr.com';

protected $_id;
protected $_broker;
protected $_restClient;

public function __construct ($id = null) {}

public function __set($name, $value) {}

public function __get($name) {}

public function setOptions(array $options) {}

public function setId ($id) {}

public function getId () {}

public function setBroker (Sozfo_Service_Flickr $broker) {}

public function getBroker () {}

/**
* Request method doing the request towards Flickr
*
* The function builds the request with the given options and looks
* if it's possible to sign the request. When cache is available, it will
* use the cached result.
* @param string $method Method to use. No need to prepend "flickr."
* @param array $options Options to configure request method
* @return mixed Response from request
*/
protected function _request ($method, array $options = array()) {}

/**
* Rest Client getter
*
* @return Zend_Rest_Client
*/
protected function _getRestClient () {}

/**
* Prepare options for the request
*
* @param string $method Flickr Method to call
* @param array $options User Options
* @param array $defaultOptions Default Options
* @return array Merged array of user and default/required options
*/
protected function _prepareOptions ($method, array $options, array $defaultOptions) {}

/**
* Sign the request with secret and token
*
* @param array $options Request options
* @param string $secret Secret part of Flickr API key
* @param string $token Token from authentication
* @return array signed options for request
*/
protected function _sign (array $options, $secret, $token) {}

/**
* Check response for errors
*
* @throws Sozfo_Service_Flickr_Exception
*/
protected function _checkErrors ($response) {}

/**
* Strip response from _content array keys
*
* Flickr returns the content inside arrays with content
* keys _content. When these keys are found, they will
* be stripped and the array value will replace this array.
* This is to keep the response clean and understandable.
* @param object|array $response Response from Rest client
* @return object|array Stripped content from response
*/
protected function _stripContent( $response ) {}
}

class Sozfo_Service_Flickr_Auth extends Sozfo_Service_Flickr_Abstract
{
const format = 'http://flickr.com/services/auth/?api_key=%s&perms=%s&extra=%s&api_sig=%s';
const perms = array('read', 'write', 'delete');

protected $_perms = 'read';

/**
* Set permission
* @throws Sozfo_Service_Flickr_Exception When $perms not one of self::perms
* @see self::perms
* @param string $perms
* @return Sozfo_Service_Flickr
*/
public function setPerms ($perms) {}

/**
* Return the permission
*/
public function getPerms () {}

/**
* Get url to redirect to return a frob
*
* Flickr auth has two steps: get a frob
* and with the frob, do a request to get
* a token. Save the token to do further
* requests.
* @see self::getTokenFromFrob()
* @return string url to get a frob
*/
public function getFrobUrl() {}

/**
* Get from a given frob a token
*
* Flickr auth step two. Save the returned token
* to do more requests later on.
* @param string $frob
* @return string token
*/
public function getTokenFromFrob ($frob) {}
}

class Sozfo_Service_Flickr_User extends Sozfo_Service_Flickr_Abstract
{
protected $_username;
protected $_realname;
protected $_location;
protected $_profileUrl;
protected $_photosUrl;
protected $_mobileUrl;
protected $_pro;
protected $_count;
protected $_views;

protected $_groups;
protected $_photos;

public function find ($id) {}

public function findByUsername ($name) {}

public function findByEmail ($email) {}

public function findByUrl ($url) {}

public function import ($data) {}

public function setUsername ($name) {}

public function getUsername () {}

public function getName () {}

public function setRealname ($name) {}

public function getRealname () {}

public function setLocation ($location) {}

public function getLocation () {}

public function setProfileUrl ($url) {}

public function getProfileUrl () {}

public function setPhotosUrl ($url) {}

public function getPhotosUrl () {}

public function setMobileUrl ($url) {}

public function getMobileUrl () {}

public function setPro ($pro) {}

public function getPro () {}

public function isPro () {}

public function setCount ($count) {}

public function getCount () {}

public function setViews ($view) {}

public function getViews () {}

public function getGroups () {}

public function getPhotos ($page = 1, $perPage = 100) {}

protected function _loadInfo() {}
}

class Sozfo_Service_Flickr_Photo extends Sozfo_Service_Flickr_Abstract
{
const format = 'http://farm%d.static.flickr.com/%d/%s_%s%s.%s';

protected $_id;
protected $_title;
protected $_description;
protected $_sets = array();
protected $_tags;
protected $_owner;
protected $_media;
protected $_thumb;
protected $_url;
protected $_secret;
protected $_originalsecret;
protected $_originalformat;
protected $_farm;
protected $_server;

protected $_sizes = array(
'square' => '_s',
'thumbnail' => '_t',
'small' => '_m',
'medium' => '',
'large' => '_b',
'original' => '_o' );

public function location ($size = 'medium') {}

public function import ($data) {}

public function setTitle ($title) {}

public function getTitle () {}

public function setDescription ($description) {}

public function getDescription () {}

public function setSets (array $sets) {}

public function appendSet (Sozfo_Service_Flickr_Set $set) {}

public function getSets () {}

public function setOwner (Sozfo_Service_Flickr_User $owner) {}

public function getOwner () {}

public function setMedia ($media) {}

public function getMedia () {}

public function setThumb ($thumb) {}

public function getThumb () {}

public function setUrl ($url) {}

public function getUrl () {}

public function setSecret ($secret) {}

public function getSecret () {}

public function setOriginalSecret ($secret) {}

public function getOriginalSecret () {}

public function setFarm ($farm) {}

public function getFarm () {}

public function setServer ($server) {}

public function getServer () {}

public function getTags () {}

protected function _loadInfo() {}
}

class Sozfo_Service_Flickr_Set extends Sozfo_Service_Flickr_Abstract
{
protected $_primary;
protected $_title;
protected $_description;
protected $_owner;
protected $_photos;
protected $_count = array('photos' => 0,
'videos' => 0);

public function import ($data) {}

public function getList (Sozfo_Service_Flickr_User $user) {}

public function setPrimary (Sozfo_Service_Flickr_Photo $primary) {}

public function getPrimary () {}

public function setTitle ($title) {}

public function getTitle () {}

public function setDescription ($description) {}

public function getDescription () {}

public function setOwner (Sozfo_Service_Flickr_User $owner) {}

public function getOwner () {}

public function setPhotos (array $photos) {}

public function getPhotos ($privacy = null, $filter = null) {}

public function setCount (array $count) {}

public function getCount () {}

public function getContext (Sozfo_Service_Flickr_Photo $photo) {}

protected function _loadInfo() {}
}

class Sozfo_Service_Flickr_Collection extends Sozfo_Service_Flickr_Abstract
{
protected $_title;
protected $_description;
protected $_iconsmall;
protected $_iconlarge;
protected $_sets;
protected $_secret;
protected $_server;
protected $_owner;

public function import ($data) {}

public function getTree (Sozfo_Service_Flickr_User $user = null) {}

public function setTitle ($title) {}

public function getTitle () {}

public function setDescription ($description) {}

public function getDescription () {}

public function setIconSmall ($icon) {}

public function getIconSmall () {}

public function setIconLarge ($icon) {}

public function getIconLarge () {}

public function setSets (array $sets) {}

public function getSets () {}

public function setSecret ($secret) {}

public function getSecret () {}

public function setServer ($server) {}

public function getServer () {}

public function setOwner (Sozfo_Service_Flickr_User $owner) {}

public function getOwner () {}

protected function _loadInfo () {}
}

class Sozfo_Service_Flickr_Group extends Sozfo_Service_Flickr_Abstract
{
protected $_name;
protected $_description;
protected $_memberCount;
protected $_members;
protected $_photos;

public function import ($data) {}

public function getList ($page = 1, $perPage = 400) {}

public function setName ($name) {}

public function getName () {}

public function setDescription ($description) {}

public function getDescription () {}

public function setMemberCount ($count) {}

public function getMemberCount () {}

public function setMembers (array $members) {}

public function getMembers ($page = 1, $perPage = 100) {}

public function setPhotos (array $photos) {}

public function getPhotos ($tag = null, Sozfo_Service_Flickr_User $user = null, $page = 1, $perPage = 100) {}

public function getContext (Sozfo_Service_Flickr_Photo $photo) {}

protected function _loadInfo() {}
}

class Sozfo_Service_Flickr_Tag extends Sozfo_Service_Flickr_Abstract
{
protected $_owner;
protected $_name;
protected $_rawName;
protected $_related;

public function import ($data) {}

public function setOwner (Sozfo_Service_Flick_User $owner) {}

public function getOwner () {}

public function setName ($name) {}

public function getName () {}

public function setRawName ($rawName) {}

public function getRawName () {}

public function getRelated () {}
}

{code}
{zone-data}

{zone-template-instance}]]></ac:plain-text-body></ac:macro>