sfOpenSocialPlugin - 1.0.2

OpenSocial API for symfony

You are currently browsing
the website for symfony 1

Visit the Symfony2 website


« Back to the Plugins Home

Signin


Forgot your password?
Create an account

Tools

Stats

advanced search
Information Readme Releases Changelog Contribute
Show source | Show as Markdown

sfOpenSocialPlugin

Overview

The symfony OpenSocial plugin enables you to create a full-feature OpenSocial Application using Symfony framework. This plugin gives you a complete PHP5 OO implementation of OpenSocial JavaScript API( including Gadgets core and feature-specific Gadgets), which makes you're applications robust, scalable and immune to future OpenSocial versions. This plugin is very flexible taking advantage of both PHP5 ( all the marvelous of object-oriented programming) and the MVC provided by the Symfony framework.

Some of the features provided by this plugin are: * Accessing to People and relationships, Persistence and Activities. * Setup application using the "app.yml" * Making transparent DataRequests to container withing the actions and accessing to container's response inside the view. * Accessing to containers environment variables both from the action and view. * Create/access activities and Activities stream from container. * The ability to send Messages(Email/Notifications/PrivateMessages/PublicMessages) to the Owner, Viewer or Friends in the container. * Taking advantages of the Persistence available the OpenSocial containers. * Having feature specific gadgets automatically imported to your application only when used in the application.

Implementation rules

At start it's important to understand that an OpenSocial application extends the Gadget specification, that specifically corresponds to one static XML file that's imported to some container. This plugin uses one Action (that's the entry point to the application) and in "indexSucces" we import the components as we need them.

Code tree

The sfOpenSocialPlugin implements the OpenSocial API and it has more than 70 classes, so it's important to know how the plugin is structured.

  • sfOpenSocialPlugin
    • data - This is where it's located the PakeTask to create projects
    • lib - This is where the OpenSocial API is implemented.
      • gadgets - This is where it's implemented Gadgets classes.
      • helpers - This is where OpenSocial helpers are implemented.
      • opensocial - This is where OpenSocial API is implemented.
    • misc - This package include files used to initialize the application
    • modules - This section has the sample modules with examples of how to use this plugin
      • application - This is a sample application

Installation

  • Install the plugin:

    symfony plugin-install http://plugins.symfony-project.com/sfOpenSocialPlugin

  • Create an OpenSocial? application:

    symfony init-opensocial-app

Usage

Configure

Note: This tutorial assumes that you have create an application called "opensocial" and an application module called "app".

The first part to create an OpenSocial application is to configure it. Because an OpenSocial application is a gadget you need to say to symfony that it should render the "indexSuccess.php" as a gadget. In this plugin you can find an gadget-layout under "sfOpenSocialPlugin/misc/app/templates/" and you need to set the "indexSuccess.php" layout as a gadget-layout. This is done by setting your "apps/opensocial/modules/application/config/view.yml" like this:

indexSuccess:
  http_metas:
    content-type: application/xml

  layout: gadget_layout

If you've used "init-opensocial-app"( look at HowToConfigure ) task you already have this configured and you don't need to do it again.

After you had configured the gadget you need to configure the OpenSocial application and in this plugin you can choose two ways of doing it: * You can configure it, using the file "app.yml"; * Or using the ModulePrefs class to configure it in the Action.

Configuring the application means to set key-values pairs like: * title : Optional string that provides the title of the gadget * description : Optional string that describes the gadget. * etc... Most of this values are optional but some containers use them. For more information about those values look at Gadget Preferences. Here it's an example of how an "app.yml" file should be configured:

# default values
all:
  opensocial:
    base_url: http://www.palcoprincipal.com
    api_version: 0.7

    module_prefs: #ref: http://code.google.com/apis/gadgets/docs/reference.html#Moduleprefs_Ref
      title: My First OpenSocial Application
#      directory_title
#      title_url
      description: This application was created by sfOpenSocialPlugin
      author: Daniel Botelho
      author_email: botelho.daniel@gmail.com
#      author_affiliation
#      author_location
#      screenshot
      thumbnail: http://www.palcoprincipal.com/images/logos/logo_palco_3.jpg
#      height
#      width
#      scaling
#      scrolling
#      singleton
#      author_photo
#      author_aboutme
#      author_link
#      author_quote

    locale:

      * lang: en
        country: us
#        messages
#        language_direction

    requires: 

      * feature: opensocial-0.7 
#      - feature: dynamic-height
#      - feature: setprefs
#      - feature: settitle
#      - feature: tabs
#      - feature: drag
#      - feature: grid
#      - feature: minimessage
#      - feature: analytics
#      - feature: flash
#      - feature: finance


    user_prefs: # ref: http://code.google.com/apis/gadgets/docs/reference.html#Userprefs_Ref
#      - name: difficulty # the name of the User Preference
#        display_name: asd
#        urlparam: asd
#        datatype: asd
#        required: asd
#        default_value: asd
#        enum_value:
#          - {value: enum1, display_value: xx }
#          - {value: enum2, display_value: xx}

    content:  # ref: http://code.google.com/apis/gadgets/docs/reference.html#Content_Ref
      type: html
#      href
#      cdata

But for this application to work properly should put in 'all_opensocial_base_url' your symfony project base url. This base_url is used to allow to automatically include stylesheet and Javascript files (look at OpenSocialHelper for more information)

Now that you have configured the application you can start coding it! You can find several examples under the directory our module "application" and you can test them. Also the API is well documented(in progress;) ). Here I'm going to give some simple examples and try to show all the advantages of using this plugin.

How to use PeopleRequest to get Viewer Friends ?

As you've seen it's straight forward to configure the OpenSocial application using the "app.yml", but here I'm going to use the class ModulePrefs to do this.

Since we are going to configure the application from the code we should start by doing that. So in the "executeIndex" function in the "/apps/opensocial/modules/application/actions/actions.class.php" you should do this:

  public function executeIndex()
  {
    ModulePrefs::setTitle('My First OpenSocial Application');
    ModulePrefs::setDescription('This application was created by sfOpenSocialPlugin');
    ModulePrefs::setAuthor('Daniel Botelho');
    ModulePrefs::setAuthorEmail('botelho.daniel@gmail.com');
    ModulePrefs::setThumbnail('http://palcoprincipal.clix.pt/images/logos/logo_palco_3.jpg');
  }

By doing this you'll be setting the Title, Description, Author, Author Email and Thumbnail of the application. After doing this, go to the file "apps/opensocial/modules/application/templates/indexSuccess.php" and this should be it's content:

<?php include_component('application','dataRequest') ?>

Here we are saying that the indexSuccess is going to include the Component "dataRequest" that is located in the "application"( to understand how Components work you should look at Chapter 7 from "The Definite Guide to symfony").

Now we should go to the "/apps/opensocial/modules/application/actions/components.class.php" and configure this component like this:

public function executeDataRequest()
  {
    $this->viewer_friends = new OSViewerFriends('viewer_friends');

    $this->people_request = new OSPeopleRequest($this->viewer_friends);
    $this->people_request->addProfileDetails(OSPersonField::PROFILE_URL);

    $data_request = new OSDataRequest('requestInfo');
    $data_request->addRequest($this->people_request);

    $this->data_response = $data_request->send(true);
    echo JSFunction::addJSTags(GadgetsUtil::registerOnLoadHandler($data_request->getDataRequestFunction()));
  }

Then go to "apps/opensocial/modules/application/templates/_dataRequest"

 <div id="viewer_friends"> </div>
<script type="text/javascript">

function <? echo $data_response->getJSFunction()->getName() ?>(<? echo $data_response->getJSFunction()->getArgs() ?>) 
{
  var html = *;
  <?php echo $data_response->getData($people_request); ?>

  <?php $person = new OSFriend('person'); ?>
  <?php echo $viewer_friends->getVarName() ?>.each(function(<?php echo $person->getVarName() ?>) {
    var thumb = <?php echo $person->getField(OSPersonField::THUMBNAIL_URL); ?>
    var profile = <?php echo $person->getField(OSPersonField::PROFILE_URL); ?>
    html += '<a href="' + profile + '" target="_top" style="float:left">' +'<img src="' + thumb + '"/></a>'; 
    document.getElementById('viewer_friends').innerHTML = html;
  });
}
</script>

After doing this, go to "http:///index.php/application" and this code should be generated:

<?xml version="1.0" encoding="utf-8" ?><Module>
<ModulePrefs title="My First OpenSocial Application" description="This application was created by sfOpenSocialPlugin" author="Daniel Botelho" author_email="botelho.daniel@gmail.com" thumbnail="http://palcoprincipal.clix.pt/images/logos/logo_palco_3.jpg" icon="http://palcoprincipal.clix.pt/favicon.ico"><Local lang="en" country="us" /><Require feature="opensocial-0.7" /></ModulePrefs>

  <Content type="html"><![CDATA[
<script type="text/javascript">function requestInfo_request() {
var requestInfo = opensocial.newDataRequest();
var viewer_friends_profileDetailsRequestParams = new Array();
viewer_friends_profileDetailsRequestParams.push(opensocial.Person.Field.PROFILE_URL);
var viewer_friends_peopleRequestParams = { };
viewer_friends_peopleRequestParams[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = viewer_friends_profileDetailsRequestParams;
requestInfo.add(requestInfo.newFetchPeopleRequest(opensocial.DataRequest.Group.VIEWER_FRIENDS),"viewer_friends");
requestInfo.send(requestInfo_response);

}
</script><script type="text/javascript">gadgets.util.registerOnLoadHandler(requestInfo_request);
</script><div id="viewer_friends"> </div>
<script type="text/javascript">

function requestInfo_response(data) 
{
  var html = *;
  var viewer_friends = data.get("viewer_friends").getData();

    viewer_friends.each(function(person) {
    var thumb = person.getField(opensocial.Person.Field.THUMBNAIL_URL);
    var profile = person.getField(opensocial.Person.Field.PROFILE_URL);
    html += '<a href="' + profile + '" target="_top" style="float:left">' +'<img src="' + thumb + '"/></a>'; 
    document.getElementById('viewer_friends').innerHTML = html;
  });
}
</script>
]></Content>
</Module>

If everything went fine, now you can go to any website that supports OpenSocial applications and install this application there to see your friends in that container.

How to use PersonRequest to get the Viewer and Owner ?

In the other example we have covered the application setup so this will not be covered again in this part. So first we need to go to "apps/opensocial/modules/application/templates/indexSuccess.php" and set the Component that is going to handle this request:

<?php include_component('application','personRequest') ?>

Next thing is to configure the component action in the "/apps/opensocial/modules/application/actions/components.class.php":

public function executePersonRequest()
  {
    $this->viewer = new OSViewer('viewer');
    $this->owner = new OSOwner('owner');

    $this->viewer_request = new OSPersonRequest($this->viewer);
    $this->viewer_request->addProfileDetails(OSPersonField::PROFILE_URL);

    $this->owner_request = new OSPersonRequest($this->owner);
    $this->owner_request->addProfileDetails(OSPersonField::PROFILE_URL);

    $data_request = new OSDataRequest('requestPerson');
    $data_request->addRequest($this->viewer_request);
    $data_request->addRequest($this->owner_request);

    $this->data_response = $data_request->send(true);
    echo JSFunction::addJSTags(GadgetsUtil::registerOnLoadHandler($data_request->getDataRequestFunction()));
  }

Now lets take some time to understand this code. Here we have created two variables:

...
$this->viewer = new OSViewer('viewer');
$this->owner = new OSOwner('owner');
...

This variables are going to be used in the "view". Next we've created to OSPersonRequest objects, one for the "viewer" and other for the "owner":

...
$this->viewer_request = new OSPersonRequest($this->viewer);
...
$this->owner_request = new OSPersonRequest($this->owner);
...

After doing this we have to create an instance of the OSDataRequest and add to it those two request's that we want to make to the container:

...
$data_request = new OSDataRequest('requestPerson');
$data_request->addRequest($this->viewer_request);
$data_request->addRequest($this->owner_request);
...

Now that we have the OSDataRequest created we need to send it to the container like this:

...
$this->data_response = $data_request->send(true);
echo JSFunction::addJSTags(GadgetsUtil::registerOnLoadHandler($data_request->getDataRequestFunction()));

The last line just says to the container that the OSDataRequest created is going to be executed when the appliction is loaded.

Now we are going to see the "view" that is located at "apps/opensocial/modules/application/templates/_personRequest":

<div id="viewer"></div>
<div id="owner"></div>

<script type="text/javascript">
function <? echo $data_response->getJSFunction()->getName() ?>(<? echo $data_response->getJSFunction()->getArgs() ?>) 
{
  var html = '';
  <?php echo $data_response->getData($owner_request); ?>
  var owner_name = <?php echo $owner->getName(); ?>
  var owner_thumb = <?php echo $owner->getField(OSPersonField::THUMBNAIL_URL); ?>
  var owner_profile = <?php echo $owner->getField(OSPersonField::PROFILE_URL); ?>
  var owner_nick = <?php echo $owner->getField(OSPersonField::NICKNAME); ?>
  html = '<a href="' + owner_profile + '" target="_top" style="float:left">' +'<img src="' + owner_thumb + '"/></a>' +
    owner_name + ' - '+owner_nick+'</a>'; 
  document.getElementById("owner").innerHTML = html;

  <?php echo $data_response->getData($viewer_request); ?>
  var viewer_name = <?php echo $viewer->getName(); ?>
  var viewer_thumb = <?php echo $viewer->getField(OSPersonField::THUMBNAIL_URL); ?>
  var viewer_profile = <?php echo $viewer->getField(OSPersonField::PROFILE_URL); ?>
  var viewer_nick = <?php echo $viewer->getField(OSPersonField::NICKNAME); ?>
  html = '<a href="' + viewer_profile + '" target="_top" style="float:left">' +'<img src="' + viewer_thumb + '"/></a>' +
    viewer_name + ' - '+viewer_nick+'</a>'; 
  document.getElementById("viewer").innerHTML = html
  <?php echo GadgetsWindow::adjustHeight(); ?>

}
</script>

Let's look at this line:

function <? echo $data_response->getJSFunction()->getName() ?>(<? echo $data_response->getJSFunction()->getArgs() ?>)

Here we use the $data_response object that was generated when we've sent the OSDataRequest to the container. The $data_response is an instance of the OSDataResponse class, and this class can be handled as an JSFunction. This means that we could setup the OSDataResponse all in the Action and didn't need to even use it in the "view", but using it in the "view" gives more flexibility.

Another important part in this example is the:

  <?php echo $data_response->getData($owner_request); ?>

For us to be able to use the "$owner" or "$viewer" object, first we need to fetch that Data from the response. After doing this we can use access directly to the objects that we've created in the Action.

The last thing from this example is this line:

<?php echo GadgetsWindow::adjustHeight(); ?> 

Here we are calling one function that is from the class [gadgets.window] that's in the http://code.google.com/apis/gadgets/docs/reference.html#Feature_Libs Feature-Specific JavaScript Libraries. Calling that function generates this javascript code:

gadgets.window.adjustHeight(); 

and there's nothing restricting you to choose to write that code instead of calling or specific static function from "GadgetsWindow::adjustHeight()". The main difference between using our object or just writing the code your self is that, if you write that code you would need to manually import " " to you're gadget( either, by setting in the "app.yml" or by calling the function OSConfig::importFeatureDynamicHeight()), and if you use "GadgetsWindow" instead you don't need to worry about that because it will be imported automatically for you.

How to create an Activity ?

Using activities are very simple and to create an OSActivity in the Action is as simple as:

  public function executeActivity(){
    $this->activity = new OSActivity('update_musics');

    $this->mediaItem = new OSActivityMediaItem('logo');
    $this->mediaItem->setImageItem();
    $this->mediaItem->setURL('http://palcoprincipal.clix.pt/images/logos/logo_palco_01.jpg');

    $this->activity->addMediaItem($this->mediaItem);
    $this->activity->setTitle('New Music Added!');
    $this->activity->createActivity(true);
  }

References

This project is being developed at [http://sfopensocialplugin.googlecode.com/]. There you can find complete documentation and latest SVN releases.

Changelog

1.0.2 * Support Multiple-Content Sections (#13) 1.0.1 * Fixed tabs issue (#10) 1.0.0 * Simplified the sfOpenSocialPlugin installation (#1) * Added Documentation for GadgetRequest (#2) * Created documentation for OpenSocialHelper (#3) * Implemented Skins (#4) * Implemented MiniMessages (#5) * Fixed the "Locale" (#6) * Implemented Views (#7) * Implemented Tabs (#8) * Complete documentation 0.0.1 * First release

License

Copyright (c) 2008 Daniel Botelho @ PalcoPrincipal.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.