user_validate($username,$password); if (!$auth_data) { self::$authenticated = false; } else { self::$authenticated = true; self::$alias = $auth_data['0']['Alias']; } } // __construct /** * user_validate * This takes a username, password and returns a key'd array of the * result data */ public function user_validate($username,$password) { $username = urlencode($username); $password = urlencode($password); $xml_doc = self::run_query("/user/validate?username=$username&hexPass=$password"); // Set the right parent $this->_containerTag = 'User'; $data = $this->run_parse($xml_doc); return $data; } // user_validate /** * user_lookup_profile * This takes a username and the md5 password and returns the users profile information */ public function user_lookup_profile($username,$password) { $username = urlencode($username); $password = urlencode($password); $xml_doc = self::run_query("/user/lookup/profile?username=$username&hexPass=$password"); // Set the right parent $this->_containerTag = 'User'; $data = $this->run_parse($xml_doc); return $data; } // user_lookup_profile /** * lookup_artists * This returns the data for a given mystrands artist (based on ID) * If it's an array of ids pass as [] = ID, [] = ID */ public function lookup_artists($ids) { // This allows multiple artists in a single query // so build the string if needed if (is_array($ids)) { foreach ($ids as $id) { $string .= '&id=' . intval($id); } $string = ltrim($string,'&'); $string = '?' . $string; } else { $string = '?id=' . intval($ids); } $xml_doc = self::run_query("/lookup/artists$string"); // Set the right parent $this->_containerTag = 'SimpleArtist'; $data = $this->run_parse($xml_doc); return $data; } // lookup_artists /** * lookup_albums * This returns the data for a given mystrands album (based on ID) * If it's an array of ids pass as [] = ID, [] = ID * You can optionally pass an alias to this, if you do you can get * the 'buy' links as UserPurchaseURI */ public function lookup_albums($ids,$alias='') { // This allows multiple albums in a single query, // so build it accordingly if (is_array($ids)) { foreach ($ids as $id) { $string .= '&id=' . intval($id); } $string = ltrim($string,'&'); $string = '?' . $string; } else { $string = '?id=' . intval($ids); } // If they have passed an alias if ($alias) { $string .= '&alias=' . urlencode($alias); } $xml_doc = self::run_query("/lookup/albums$string"); // Set the right parent $this->_containerTag = 'SimpleAlbum'; $data = $this->run_parse($xml_doc); return $data; } // lookup_albums /** * lookup_tracks * This returns the data for a given mystrands track (based on ID) * If it's an array of ids pass as [] = ID, [] = ID * This can take an optional alias, if passed UserPurchaseURI will * be returned */ public function lookup_tracks($ids,$alias='') { // This allows for multiple entires, so build accordingly if (is_array($ids)) { foreach ($ids as $id) { $string .= '&id=' . intval($id); } $string = ltrim($string,'&'); $string = '?' . $string; } // end if array else { $string = '?id=' . intval($ids); } // If they have passed an alias if ($alias) { $string .= '&alias=' . urlencode($alias); } $xml_doc = self::run_query("/lookup/tracks$string"); // Set the parent $this->_containerTag = 'SimpleTrack'; $data = $this->run_parse($xml_doc); return $data; } // lookup_tracks /** * lookup_album_tracks * This takes a album ID and then returns the track list for it */ public function lookup_album_tracks($mystrands_album_id,$alias='') { $mystrands_album_id = intval($mystrands_album_id); if ($alias) { $alias_txt = '&alias=' . urlencode($alias); } $xml_doc = self::run_query("/lookup/album/tracks?id=$mystrands_album_id$alias_txt"); // Set the right parent $this->_containerTag = 'AlbumTrack'; $data = $this->run_parse($xml_doc); return $data; } // lookup_album_tracks /** * lookup_artist_albums * This returns a list of the albums for a given artist ID you can * pass an optional limit and offset */ public function lookup_artist_albums($artist_id,$limit='',$offset='') { $artist_id = intval($artist_id); $limit = $limit ? intval($limit) : $this->limit; $offset = $offset ? intval($offset) : '0'; $xml_doc = self::run_query("/lookup/artist/albums?id=$artist_id&num=$limit&skip=$offset"); // Set the container $this->_containerTag = 'SimpleAlbum'; $data = $this->run_parse($xml_doc); return $data; } // lookup_artist_albums /** * search_albums * This searches for albums of the given name in MyStrands */ public function search_albums($name,$limit='',$offset='') { $name = urlencode($name); $limit = $limit ? intval($limit) : $this->limit; $offset = $offset ? intval($offset) : '0'; $xml_doc = self::run_query("/search/albums?searchText=$name&num=$limit&skip=$offset"); // Set the right parent $this->_containerTag = 'SimpleAlbum'; $data = $this->run_parse($xml_doc); return $data; } // search_albums /** * search_artists * This searches for artists of the given name in MyStrands */ public function search_artists($name,$limit='',$offset='') { $name = urlencode($name); $limit = $limit ? intval($limit) : $this->limit; $offset = $offset ? intval($offset) : '0'; $xml_doc = self::run_query("/search/artists?searchText=$name&num=$limit&skip=$offset"); // Set the right parent $this->_containerTag = 'SimpleArtist'; $data = $this->run_parse($xml_doc); return $data; } // search_artists /** * search_tracks * This searches for tracks on Mystrands based on the search text */ public function search_tracks($name,$limit='',$offset='') { $name = urlencode($name); $limit = $limit ? intval($limit) : $this->limit; $offset = $offset ? intval($offset) : '0'; $xml_doc = self::run_query("/search/tracks?searchText=$name&num=$limit&skip=$offset"); // Set the right parent $this->_containerTag = 'SimpleTrack'; $data = $this->run_parse($xml_doc); return $data; } // search_tracks /** * match_artists * This does a best choice match on the artist name(s) passed */ public function match_artists($values) { // If it's not, turn it into one! if (!is_array($values)) { $values = array($values); } foreach ($values as $value) { $artist_text .= '&name=' . urlencode($value); } $artist_text = ltrim($artist_text,'&'); $artist_text = '?' . $artist_text; $xml_doc = self::run_query("/match/artists$artist_text"); // Set the right parent $this->_containerTag = 'SimpleArtist'; $data = $this->run_parse($xml_doc); return $data; } // match_artists /** * match_albums * This does its best to match on the album name with an attached artist name * This function expects matches paris album,artist as such * [0]['artist'] = artist name, [0]['album'] = album name */ public function match_albums($values) { // We're less forgiving here if (!is_array($values)) { return false; } foreach ($values as $value) { if (!$value['artist'] || !$value['album']) { next; } $query_text .= '&name=' . urlencode($value['artist']) . '|' . urlencode($value['album']); } $query_text = ltrim($query_text,'&'); $query_text = '?' . $query_text; $xml_doc = self::run_query("/match/albums$query_text"); // Set the right parent $this->_containerTag = 'SimpleAlbum'; $data = $this->run_parse($xml_doc); return $data; } // match_albums /** * match_tracks * This expects a trifectum of information as such * [0]['artist'] = artist name * [0]['album'] = album name * [0]['track] = track */ public function match_tracks($values) { // We're not very forgiving here if (!is_array($values)) { return false; } foreach ($values as $value) { if (!$value['artist'] || !$value['album'] || !$value['track']) { next; } $query_text .= '&name' . urlencode($value['artist']) . '|' . urlencode($value['album']) . '|' . urlencode($value['track']); } // end foreach $query_text = ltrim($query_text,'&'); $query_text = '?' . $query_text; $xml_doc = self::run_query("/match/tracks$query_text"); // Set up the parent $this->_containerTag = 'SimpleTrack'; $data = $this->run_parse($xml_doc); return $data; } // match_tracks /** * recommend_artists * This generates recomendations for other artists, takes at least one artist (ID/Name) as * as seed, filters allowed, this user is used unless another alias is passed * $values should be ['id'][] = ID, ['id'][] = ID, ['name'][] = NAME, ['name'][] = NAME */ public function recommend_artists($values,$limit='',$offset='',$alias='') { if (!is_array($values['id'])) { $values['id'] = array(); } if (!is_array($values['name'])) { $values['name'] = array(); } // Build out the ids first foreach ($values['id'] as $id) { $id_string .= '&id=' . intval($id); } // Now for z-names foreach ($values['name'] as $name) { $name_string .= '&name=' . urlencode($name); } // Clean up remaining stuff $filters = $this->filter; $offset = $offset ? intval($offset) : '0'; $limit = $limit ? intval($limit) : $this->limit; $alias = $alias ? urlencode($alias) : urlencode(self::$alias); $xml_doc = self::run_query("/recommend/artists?alias=$alias$id_string$name_string&num=$limit&skip=$offset$filters"); $this->_containerTag = 'SimpleArtist'; $data = $this->run_parse($xml_doc); return $data; } // recommend_artists /** * recommend_albums * This produces recommended albums based on sets of artist|album filters allowed, this user is used unless different * alias is passed. Values are integrity checked to the best of my lazyness * $values should be ['id'][] = ARTISTID|ALBUMID, ['name'][] = ARTIST|ALBUM */ public function recommend_albums($values,$limit='',$offset='',$alias='') { if (!is_array($values['id'])) { $values['id'] = array(); } if (!is_array($values['name'])) { $values['name'] = array(); } // Build out the ids first foreach ($values['id'] as $id) { if (!preg_match("/\d+\|\d+/",$id)) { next; } $id_string .= '&id=' . intval($id); } // Now for z-names foreach ($values['name'] as $name) { // Only add stuff that's valid if (!preg_match("/.+\|.+/",$name)) { next; } $name_string .= '&name=' . urlencode($name); } // Clean up remaining stuff $filters = $this->filter; $offset = $offset ? intval($offset) : '0'; $limit = $limit ? intval($limit) : $this->limit; $alias = $alias ? urlencode($alias) : urlencode(self::$alias); $xml_doc = self::run_query("/recommend/albums?alias=$alias$id_string$name_string&num=$limit&skip=$offset$filters"); $this->_containerTag = 'SimpleAlbum'; $data = $this->run_parse($xml_doc); return $data; } // recommend_albums /** * recommend_tracks * This produces recommended tracks based on sets of artist|album|track filters allowed, this user is used unless different * alias is passed. Values are integrity checked to the best of my lazyness * $values should be ['id'][] = ARTISTID|ALBUMID|TRACKID, ['name'][] = ARTIST|ALBUM|TRACK */ public function recommend_tracks($values,$limit='',$offset='',$alias='') { if (!is_array($values['id'])) { $values['id'] = array(); } if (!is_array($values['name'])) { $values['name'] = array(); } // Build out the ids first foreach ($values['id'] as $id) { if (!preg_match("/\d+\|\d+\|\d+/",$id)) { next; } $id_string .= '&id=' . intval($id); } // Now for z-names foreach ($values['name'] as $name) { // Only add stuff that's valid if (!preg_match("/.+\|.+\|.+/",$name)) { next; } $name_string .= '&name=' . urlencode($name); } // Clean up remaining stuff $filters = $this->filter; $offset = $offset ? intval($offset) : '0'; $limit = $limit ? intval($limit) : $this->limit; $alias = $alias ? urlencode($alias) : urlencode(self::$alias); $xml_doc = self::run_query("/recommend/tracks?alias=$alias$id_string$name_string&num=$limit&skip=$offset$filters"); $this->_containerTag = 'SimpleTrack'; $data = $this->run_parse($xml_doc); return $data; } // recommend_tracks /** * set_filter * This builds out the filter for this object, it's a per instance filter */ public function set_filter($field,$fuzzy,$level,$values) { // Make sure they pick a sane field switch ($field) { case 'Artist': case 'Album': case 'Year': case 'Track': case 'Genre': case 'PersonalTag': case 'CommunityTag': case 'PersonalTrackTag': case 'CommunityTrackTag': case 'PersonalArtistTag': case 'CommunityArtistTag': case 'UserHistory': // We're good break; default: return false; break; } // end switch on passed filed $level = intval($level); // Default to very hard if ($level > 9 || $level < 0) { $level = 0; } // Clean up the fuzzyness $fuzzy = make_bool($fuzzy); if ($fuzzy) { $fuzzy = 'True'; } else { $fuzzy = 'False'; } if (is_array($values)) { foreach ($values as $value) { $value_string .= $value; } } else { $value_string = $values; } $filter_string = "&filter=$field,$fuzzy,$level|$value_string"; $this->filter .= $filter_string; } // set_filter /** * set_auth_token * This function should be called on load to set the auth_token, if you don't * just hardcode it, also allows realtime switching between auth tokens * so that users can use their own limits when querying */ public static function set_auth_token($token) { // Set it self::$auth_token = $token; //FIXME: We should log this event? } // set_auth_token /** * run_query * This builds a URL, runs it and then returns whatever we found */ private static function run_query($action) { // Stop them if they are not authenticated if (!self::$authenticated) { return false; } // Build the URL $url = self::$base_url . $action . '&subscriberId=' . self::$auth_token; $contents = file_get_contents($url); return $contents; } // run_query /** * run_parse * This will create the parser, de-fudge the doc * and set $this->results to the result data */ public function run_parse($xml_doc) { // Create the parser $this->create_parser(); $this->_key = -1; $success = xml_parse($this->_parser,$xml_doc); if (!$success) { return false; } xml_parser_free($this->_parser); $data = $this->results; $this->results = ''; if (!$data) { return array(); } return $data; } // run_parse /** * create_parser * this sets up an XML Parser */ public function create_parser() { $this->_parser = xml_parser_create(); xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false); xml_set_object($this->_parser, $this); xml_set_element_handler($this->_parser, 'start_element', 'end_element'); xml_set_character_data_handler($this->_parser, 'cdata'); } // create_parser /** * start_element * This is part of our internal XML parser */ function start_element($parser, $tag, $attributes) { // If it's our 'parent' object tag then bump the key if ($tag == $this->_containerTag) { $this->_key++; // If we find attributes if (count($attributes)) { // If it's not already an array, make it one so merge always works if (!isset($this->results[$this->_key][__attributes])) { $this->results[$this->_key][__attributes] = array(); } $this->results[$this->_key][__attributes] = array_merge($this->results[$this->_key][__attributes],$attributes); } // end if there are attributes } elseif ($this->_key >= '0') { $this->_currentTag = $tag; } // if key is at least 0 } // start_element function cdata($parser, $cdata) { $tag = $this->_currentTag; if (strlen($tag) AND $this->_key >= 0) { $this->results[$this->_key][$tag] .= trim($cdata); } } // cdata function end_element($parser, $tag) { /* Zero the tag */ $this->_currentTag = ''; } // end_element } // end openstrands ?>