array('disk', '%d'), 'length' => array('time', '%d'), 'comments' => array('comment', '%s'), 'bitrate' => array('bitrate', '%d') ); public function __construct($uri) { $this->uri = $uri; } /** * Starts a command * @param string $command */ public function start($command) { $handle = fopen($this->assembleUri($command), 'r'); if ($handle) { $this->iterateItems($handle); } } /** * Iterate over the input and create a song if one is found * @param resource $handle */ public function iterateItems($handle) { $item = ''; while (!feof($handle)) { $item .= $char = fgetc($handle); // Check for the brace prevents unneded call of itemIsComlete() which saves a whole lot of time if ($char === '}' && $this->itemIsComlete($item)) { $song = $this->parse($item); $this->dispatch($song); $item = ''; fgetc($handle); // Skip comma between two objects } } } /** * Assemble the URI from the different parts * @param string $command * @return string */ protected function assembleUri($command) { $uriParts = array( $this->uri, $command ); return implode('/', $uriParts); } /** * Check if the Json is complete to get a song * @param string $item * @return boolean */ public function itemIsComlete($item) { $item = $this->removeUnwantedStrings($item); return $this->compareBraces($item); } /** * Remove the beginning and the end of the json string so we can access the object in it. * @param string $item * @return string */ public function removeUnwantedStrings($item) { $toRemove = array( '{"items":[', '{"results":[', ']}' ); return str_replace($toRemove, '', $item); } /** * Compare the braces to ensure that we have a complete song object * @param string $item * @return boolean */ public function compareBraces($item) { $start = $this->countChar('{', $item); $end = $this->countChar('}', $item); return $start !== 0 && $start === $end; } /** * * @param string $char * @param string $string * @return type */ public function countChar($char, $string) { return substr_count($string, $char); } /** * convert the json string into a song array * @param string $item * @return array */ public function parse($item) { $item = $this->removeUnwantedStrings($item); $song = json_decode($item, true); $song['file'] = $this->createFileUrl($song); return $this->mapFields($song); } /** * Create the Url to access the file * Have to do some magic with the file ending so ampache can detect the type * @param array $song * @return string */ public function createFileUrl($song) { $parts = array( $this->uri, 'item', $song['id'], 'file' . '#.' . strtolower($song['format']) ); return implode('/', $parts); } }