SoundCloud App for PHPfox V4 – Developers Example

As we get closer to launching our App system, we wanted to provide several working examples so developers can get an idea of how apps will work with our products.

We released Notes, which shows developers how to create an app using PHP. Shortly after we released Chatterbox, a small NodeJS chat room that utilizes web sockets.

With our next example App we wanted to integrate an app with a 3rd party service. We went with SoundCloud, which allows their users to easily share music with their friends on blogs, sites and social networks.

What does this app include?

We dive into the common tasks an app would need, such as adding an icon to the apps main link and integrating it into the activity feed.

The app guides developers on attaching an icon to the main menu.

It shows how to integrate it to the activity feed.

The app also shows how to create custom feeds by using JavaScript to alter the feed as well as PHP to connect to the API in order to add it to the feed. This demonstrates how apps do not need to store data locally and everything can be added to the activity feed, which we explain in this article.

The Source Code

You can access the source code on GitHub.

This app utilizes primarily 2 files.

// Change app343 with your APP ID var APP_ID = ‘app343’; // Function to post an AJAX request to our app soundcloud_post = function(obj) { $(‘#soundcloud_form’).find(‘.button’).addClass(‘button_off’).attr(‘disabled’, true); $(‘#soundcloud_form’).find(‘.table_clear_ajax’).show(); // POST to our app based on the APP_ID URL Core.post(getParam(‘sJsHome’) + ‘index.php?do=/’ + APP_ID + ‘/’, $(obj).parents(‘form:first’), function() { $(‘#soundcloud_form’).find(‘.button’).removeClass(‘button_off’).attr(‘disabled’, false); $(‘#soundcloud_form’).find(‘.table_clear_ajax’).hide(); }); }; // Load routine when the document is ready Core.action.soundcloud = function() { if ($(‘.activity_feed_form_share’).length && !$(‘.soundcloud_link’).length) { // Find SoundCloud menu and add an icon $(‘.menu_’ + APP_ID).find(‘span.icon’).css({ border: ‘0px’, background: ‘url(\’//da1a3suzxtd3z.cloudfront.net/assets/apps/soundcloud/menu.png\’) no-repeat’ }); // Add SoundCloud phrase to the activity feed form $(‘.activity_feed_form_attach’).append(‘<li class=”soundcloud_link”><a href=”#” rel=”view_more_link”><div>SoundCloud</div></a></li>’); // Build the form to add SoundCloud URLs var html = ; html += ‘<div class=”table_clear”><span class=”js_attach_holder”><input type=”text” class=”global_link_input” placeholder=”http://” name=”val[soundcloud_url]”></span>’ + ‘<ul class=”table_clear_button”><li><input type=”button” value=”Share” class=”button” onclick=”soundcloud_post(this)” /></li><li class=”table_clear_ajax”></li></ul><div class=”clear”></div>’ + ‘</div><div class=”extra_info”>Paste the URL to the SoundCloud playlist</div>’; $(‘.activity_feed_form_holder’).append(‘<div id=”soundcloud_form” class=”global_attachment_holder_section” style=”display:none;”>’ + html + ‘</div>’); } // Click event to show the SoundCloud form we built earlier $(‘.soundcloud_link a’).click(function() { $(‘.activity_feed_form_attach a.active’).removeClass(‘active’); $(‘.global_attachment_holder_section’).hide(); $(‘.activity_feed_form_button’).hide(); $(‘#soundcloud_form’).show(); $(this).addClass(‘active’); return false; }); if ($(‘#page_core_index_member’).length) { // Loop thru only our apps feed $(‘.stream_type_’ + APP_ID + ‘ .activity_feed_json:not(.is_data_build)’).each(function() { var this_obj = $(this).parents(‘.row_feed_loop:first’); var html = this_obj.find(‘.activity_feed_json:first’).html(); $(this).addClass(‘is_data_build’); if (html.substr(0, 1) == ‘{‘) { html = $.parseJSON(html); // Make sure its a SoundCloud object we added if (isset(html.soundcloud)) { var feed_status = this_obj.find(‘.activity_feed_content_status’); this_obj.find(‘.activity_feed_content_status’).before(‘<div class=”activity_feed_content_no_image”><a href=”#” class=”activity_feed_content_link_title” onclick=”return false;” style=”cursor:default;”>’ + html.soundcloud.title + ‘</a><div class=”activity_feed_content_display”>’ + feed_status.html() + ‘</div></div>’); var image = new Image(); image.onload = function() { feed_status.html(‘<div style=”background:url(\” + html.soundcloud.thumbnail_url + ‘\’); width:’ + image.width + ‘px; height:’ + image.height + ‘px; margin:10px auto;”></div>’); }; image.src = html.soundcloud.thumbnail_url; } } // Scroll even to only load the song if its in view $(window).scroll(function() { if ($Core.isInView(this_obj.find(‘.activity_feed_content_status’)) && !$(this_obj).hasClass(‘is_build’)) { $(this_obj).addClass(‘is_build’); var html = this_obj.find(‘.activity_feed_json:first’).html(); if (html.substr(0, 1) == ‘{‘) { html = $.parseJSON(html); if (isset(html.soundcloud)) { var iframe = html.soundcloud.html.replace(‘[IFRAME’, ‘<iframe’).replace(‘][/IFRAME]’, ‘></iframe>’); this_obj.find(‘.activity_feed_content_status’).html(‘<div style=”margin:10px auto;”>’ + iframe + ‘</div>’); } } } }); }); } };
actions.js brought to you by GitIT view raw
<?php // Check if our local config file exists if (!file_exists(‘./config.php’)) { exit(‘Rename config.php.new to config.php’); } // Load the config file require_once(‘./config.php’); // Make sure it is a valid M9 request if (empty($_REQUEST[‘json’])) { exit(‘Not a valid M9 call.’); } // Decode the request and convert it into an object $json = json_decode(urldecode($_REQUEST[‘json’])); // Make sure the public and private keys match if ($json->public_key != MOXI9_PUBLIC_KEY || $json->private_key != MOXI9_PRIVATE_KEY) { exit(‘Keys do not match.’); } // Define the client ID, based on what M9 sends us define(‘MOXI9_CLIENT_ID’, $json->client_site_id); /** * Small function to output an error when a SoundCloud URL is invalid * * @param $error Error to output */ function _show_error($error) { echo ‘alert(“‘ . $error . ‘”);’; exit; } /** * API call to M9 servers * We use this here to add/get feeds * @see http://unity.moxi9.com/docs/command/stream * * @param $action Command * @param $params ARRAY of anything you want to pass to M9 * @param string $method * @return mixed */ function _call($action, $params, $method = ‘GET’) { $params[‘app_id’] = MOXI9_APP_ID; $params = http_build_query($params); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, ‘https://api.moxi9.com/’ . $action . ‘/’ . ($method == ‘GET’ ? ‘&’ . $params : )); if ($method == ‘POST’) { curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $params); } curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_USERPWD, . MOXI9_PUBLIC_KEY . ‘:’ . MOXI9_PRIVATE_KEY . ); curl_setopt($curl, CURLOPT_HTTPHEADER, array(‘MOXI9-CLIENT: ‘ . MOXI9_CLIENT_ID)); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $data = curl_exec($curl); curl_close($curl); if (substr($data, 0, 1) == ‘{‘ || substr($data, 0, 1) == ‘[‘ || substr($data, 0, 1) == ‘”‘) { $data = json_decode($data); } return $data; } // Check if this is a $_POST from a form if (isset($json->post) && isset($json->post->val)) { // Make sure the user provided a SoundCloud URL if (!empty($json->post->val->soundcloud_url)) { // Encode the URL to pass along to SoundCloud $url = urlencode($json->post->val->soundcloud_url); $data = @file_get_contents(‘http://soundcloud.com/oembed?url=’ . $url . ‘&format=json’); // Quick check to see if we returned a JSON object if (substr($data, 0, 1) == ‘{‘) { $data = json_decode($data); $iframe = $data->html; $data->html = str_replace(array(‘<iframe’, ‘></iframe>’), array(‘[IFRAME’, ‘][/IFRAME]’), $data->html); // Add this post to the activity feed $stream_id = _call(‘stream/add’, array(‘user_id’ => $json->user->id, ‘type’ => MOXI9_APP_ID, ‘content’ => (!empty($data->description) ? $data->description : ‘  ‘), ‘soundcloud’ => (array) $data), ‘POST’); // Get the feed from what we just added $stream = _call(‘stream/get’, array(‘user_id’ => $json->user->id, ‘id’ => $stream_id)); // Build the HTML for the feed, until PHPfox has support for this. // This HTML is only used when posting to the feed. It is not saved or cached anywhere $new_feed = ‘ <div class=”js_feed_view_more_entry_holder”> <div class=”row_feed_loop row2″> <div class=”activity_feed_image”> <a href=”#”><img src=”‘ . $json->user->thumbnail_url . ‘” width=”50″ height=”50″ /></a> </div> <div class=”activity_feed_content_holder”> <div class=”activity_feed_content”> <div class=”activity_feed_content_text”> <div class=”activity_feed_content_info”> <span class=”user_profile_link_span”><a href=”#”>’ . $json->user->name . ‘</a></span> </div> <div class=”activity_feed_content_no_image”> <a href=”#” class=”activity_feed_content_link_title” onclick=”return false;” style=”cursor:default;”>’ . $data->title . ‘</a> <div class=”activity_feed_content_display”>’ . $stream->content_parsed . ‘</div> </div> <div class=”activity_feed_content_status”> <div style=”margin-top:10px;”> ‘ . $iframe . ‘ </div> </div> </div> <div class=”activity_feed_time”> Just now </div> </div> </div> </div> </div> ‘; // Add this to the activity feed echo ‘var soundcloud_html = ‘ . json_encode(array(‘html’ => $new_feed)) . ‘;’; echo ‘$(\’#js_feed_content\’).prepend(soundcloud_html.html);’; echo ‘$Core.resetActivityFeedForm();’; exit; } _show_error(‘Not a valid SoundCloud URL.’); } _show_error(‘Missing SoundCloud URL.’); } // If nothing is posted to the feed lets just display the feed and only load SoundCloud entries // Learn more at: http://unity.moxi9.com/docs/apps/using-streams echo ‘stream:’ . MOXI9_APP_ID; ?>
index.php brought to you by GitIT view raw

Questions?

If you have any questions, make sure to stop on over at our Techie Forum.

If you don’t have a Techie account, take a moment to sign up.