GSoC2008

From MWWiki

Jump to: navigation, search

Contents

Google Summer of Code 2008

Adding OpenSocial Compliance to the Joomla! Content Management System

Overview

The purpose of this project is to make Joomla! an OpenSocial container by interfacing the content management system with Apache's OpenSocial implementation, Shindig.

Description

In order to make Joomla! a viable OpenSocial container utilizing Apache's Shindig project, there are only a few necessary steps in order to make that happen:

  • Alter database schema to store OpenSocial gadgets and their preferences
  • Override the database's concept of a User to allow them to interact in the context of gadgets
  • Allow gadgets to be added (URLs pointing to XML files and subsequent JavaScript)
  • Implement services for Joomla!-to-gadget server communication (Shindig handles the RESTful API)
  • Implement gadget preference storage

The example Shindig implementation named Partuza, created by brilliant Shindig developer Chris Chabot, shows exactly how this integration is to be done, particularly on the following points:

Check out partuza's code and how it uses shindig through the  
metadata service, how it builds iframe's (Views/gadget/gadget.php is  
the main file for this), what param's are required for this iframe and  
how to create a security token that the social data server uses to  
retrieve the owner, viewer, app id, etc. This should hopefully give  
you something of a clear picture how to reproduce this in Joomla

Check out the data handlers in partuza/Shindig/*.php, you'll have  
to make a Joomla implementation of these to connect the gadgets to  
your backend..

Shindig itself is extremely straightforward, and aside from adjusting a few configuration values, can be used without further modifications. The configuration values are stored in its config/container.php file, but in order to preserve configuration changes while constantly updating to the latest SVN release, creating a new file in the config/ directory called "local.php" and storing only the changed values will accomplish the same end. For example:

<?php
 
$shindigConfig = array(
 
  // Show debug backtrace's. Disable this on a production site
  'debug' => true,
  // Allow plain text security tokens, this is only here to allow the sample files to work. Disable on a production site
  'allow_plaintext_token' => true,
 
  // Ability to customize the style thats injected into the gadget document. 
  // Don't forget to put the link/etc colors in shindig/config/container.js too!
  'gadget_css' => 'body,td,div,span,p{font-family:arial,sans-serif;} a {color:#0000cc;}a:visited {color:#551a8b;}a:active {color:#ff0000;}body{margin: 0px;padding: 0px;background-color:white;}',
 
  // any custom J! javascript?
  'forcedJsLibs' => '',
 
  // security tokens - can Joomla! automatically generate tokens?
  // The encryption keys for encrypting the security token, and the expiration of it. 
  // Make sure these match the keys used in your container/site
  'token_cipher_key' => 'INSECURE_DEFAULT_KEY',
  'token_hmac_key' => 'INSECURE_DEFAULT_KEY',
  'private_key_phrase' => 'joomla', 
 
  // the URL at which shindig lives, relative to the J! path
  'web_prefix' => '',
 
  // custom data handlers for the J! environment
  'people_service' => 'JoomlaPeopleService',
  'activity_service' => 'JoomlaActivitiesService',
  'app_data_service' => 'JoomlaAppDataService',
  'messages_service' => 'JoomlaMessagesService',
 
  // other classes
  'extension_class_paths' => JPATH_LIBRARIES . DS . 'shindig' . DS . 'classes'
 
);
 
?>

Any identical keys in "container.php" will have their values replaced with the ones defined in "local.php".

As for the data handlers - each of the "x_service" values defined in the example configuration - each is an implementation of an abstract class with abstract methods that must be completed within the Joomla! context in order to properly bridge between Shindig and the gadget servers. To wit:

JoomlaAppDataService.php

JoomlaPeopleService.php

JoomlaActivityService.php

JoomlaMessagesService.php

As Chris mentioned in his emails, Activities and Messages aren't entirely pertinent within the Joomla! environment, though Activities may be implemented later in some fashion, so storing them would be prudent. The AppDataService and PeopleService are by far the most important. The AppDataService is missing only the database calls necessary to store and retrieve the corresponding gadget information from the Joomla! database.

Mimicking Partuza's method for communicating with Shindig from this point would be the most efficient development path. The only caveat is the caching. Partuza uses a very sophisticated method of caching its gadget calls, making debugging difficult. Specifically, when a new application is being added and an instance of the ApplicationModel invoked, the "get_application" method is called. For these purposes, the method name should either be deleted from the $cachable array, or the "load_" prefix of the actual method should be deleted. If neither action is taken, the "__call()" method is invoked from the superclass, which performs some very complex method caching, making tracing difficult.

(FirePHP is a must here)

Also, take care that Shindig is configured properly. Partuza - or, once the OpenSocial API is implemented, Joomla! itself - relies on a correct URL to the Shindig server. Since Shindig performs its own URL mappings by mapping specifically crafted postfixes to specific PHP classes or "servlets," the URL provided to the OpenSocial container must be precisely accurate. I encountered many problems by adding one too many trailing slashes or assuming mod_rewrite at the destination when it was not taking effect. Shindig returns a 404 if the URL accessed does not have a mapping in its servlet mappings array:

$servletMap = array(
                Config::get('web_prefix') . '/gadgets/files' => 'FilesServlet',
                Config::get('web_prefix') . '/gadgets/js' => 'JsServlet',
                Config::get('web_prefix') . '/gadgets/proxy' => 'ProxyServlet',
                Config::get('web_prefix') . '/gadgets/makeRequest' => 'ProxyServlet',
                Config::get('web_prefix') . '/gadgets/ifr' => 'GadgetRenderingServlet',
                Config::get('web_prefix') . '/gadgets/metadata' => 'JsonRpcServlet',
                Config::get('web_prefix') . '/social/data' => 'GadgetDataServlet',
                Config::get('web_prefix') . '/social/rest' => 'RestServlet',
                Config::get('web_prefix') . '/public.crt' => 'CertServlet'
                );

The majority of the requests from the OpenSocial container will be of the form "/gadgets/ifr", though provided the final of the five initial points listed is met regarding gadget preferences, requests to "/gadgets/metadata" will also be frequent as the user dynamically resets application preferences. The other URLs will be accessed implicitly. However, if the URL does not match any of these, Shindig returns a 404.

Below are links which detail out most of this information. Pay special attention to the Shindig/Partuza links, as anyone with dangerous knowledge of Joomla! will be able to piece this information together and turn the vaunted CMS into a veritable OpenSocial container by way of a simple component. At its most basic, the administrator component will add OpenSocial gadget URLs to the system, and users will then be able to add these applications to their "profiles" (this will require a unique view for this component). Perhaps Joomla! gurus will be able to come up with a better user interface, but this was the project as I had envisioned and proposed. A functioning metadata service will allow changes made to the applications - say, notes written on the Notes application - to persist. An implemented and integrated Activities service will let users interact with each other's applications, sharing information - say, users competing in scores on a game of Tetris.

By my best estimate, someone with intimate knowledge of Joomla!'s core could take this overview and turn out a functioning com_opensocial prototype in under a day. Should someone which to undertake this endeavor, they are most welcome. If not, take note that this project is listed as "open", implying that once the time is right, I will return to it of my own accord, intent on finishing what I began. :)

Internal Links

Abstract

Initial Proposal

Email 1

  • Differences between wire formats of Shindig; description of new RESTful API implementation
  • Instructions for overriding abstract []Service classes
  • Details regarding Shindig configuration variables that can be overridden (local.php)
  • Gadget metadata service to save application preferences
  • Gadget iframes

Email 2

  • Details regarding how Partuza performs caching for applications
  • Further Shindig blackbox implementation details
  • What services need to be implemented in an OpenSocial container like Joomla?

Email 3

  • Details on implementing Joomla!-specific functionality
  • Instructions for creating required RPC
  • More details on application preferences
  • Suggestions for database implementation

Shindig's URL mappings

  • How Shindig maps URLs to particular servlets

External Links

Personal tools