Developing Plugins for SwiftRiver Applications
Ahmed Maawy, the newest hire to the SwiftRiver project, recently compiled this great ‘how-to’ guide on writing plugins for SwiftRiver applications like Sweeper and SwiftMeme. These plugins can mostly be found at http://plugins.swiftly.org while the wishlist for things we’d like to see built can be found here.
For a great example of how Swift plugins work, check out the Ushahidi Report Push plugin, which allows content verified in Sweeper to be passed along to Ushahidi. Coupled with the Yahoo Placemaker plugin, this is really powerful as it allows all content to pass from Sweeper to Ushahidi, auto-geolocated.
You can view a fully formated version of this guide on Google Docs
Before we begin it is worth noting that all SwiftRiver applications have 3 major components:
- SwiftRiver Core - the engine behind content retrieval, processing and storage.
- Installer - in charge of initial setup of the SwiftRiver platform.
- Sweeper - Sweeper is the application built on top of the Kohana PHP framework that acts as a web application that renders or provides a UI on behalf of the operations performed by the SwiftRiver core.
There are 3 very important elements to understand for SwiftRiver applications when developing and extending the platform for customized functionality (These 3 elements can be considered as “plugins” for SwiftRiver).
- Impulse Turbines - Are elements that process and add value to content received from external sources.
- Reactor Turbines - Are event handlers, and are not necessarily meant to add value to content but to react to specific events within SwiftRiver.
- Sources - Are parsers for different types of content. They are responsible for retrieving content from the Internet or other relevant sources, and translating this content to SwiftRiver content items, so that content from different sources can all have a uniform format within SwiftRiver.
Its is important to note that the SwiftRiver /Modules folder contains a number of these event handlers (Reactor turbines and Impulse turbines). However, Sources (Also known as Parsers) are developed within the /Modules/SiSPS/Parsers folder.
This is a step by step approach regarding how content is received and processed within the core:
- Parsers take the content from the various external sources, and convert it to the Swift object model.
- Impulse Turbines may act on the SwiftRiver content items and add value to these content items.
- Reactor Turbines may be used to work on the end result of the content either before they are processed by Impulse Turbines, or during their processing cycle, or anytime within the lifetime of the content after specific user actions (such as mark content as accurate).
Parsers / Sources
Parsers are located within the /Modules/SiSPS/Parsers folder and follow the following important rules:
- Have to have a <Parser_Name>Parser.php file name format
- The class name has to be the same as the file name
- The class name must implement the IParser class
- It must be within the namespace SwiftRiver\Core\SiSPS\Parsers
- Must contain the following functions:
- GetAndParse($channel): returns an array of Content Items
- ListSubTypes(): Returns the sub types of the Parser
- ReturnType(): Returns the type of the parser (Which has to have the same name as the parser you specified in <Parser_Name>
- ReturnRequiredParameters(): Returns an array of the parameters required to initiate a single source entry for this parser.
You may take a look at how content items for Twitter are generated to get an example on how parsers work. Content Items are also passed back together with Source data where available. You may also need to know how the object model for a Channel, Source, and Content are structured. These classes are located within the /ObjectModel/ folder.
Impulse Turbines
Located in the /Modules/ folder. Use the following important rules:
- Have a <Module_Name>PreProcessingStep.php file name format.
- The class name has to be the same as the file name.
- The class must implement the \Swiftriver\Core\PreProcessing\IPreProcessingStep class.
- Must be in the namespace Swiftriver\PreProcessingSteps
- Contain the following functions:
- Process($contentItems, $configuration, $logger): Which does processing on the content items.
- Name(): Returns the impulse turbine name.
- Description(): Returns the description of this pre-processing step.
- ReturnRequiredParameters(): Returns an array of required parameters for the pre-processing step.
You may refer to the file GoogleLanguageServicePreProcessingStep.php in /Modules/GoogleLanguageServiceInterface/ folder for an example.
Reactor Turbines
Are located in the /Modules/ folder with the following important rules:
- Have a <Module_Name>EventHandler.php file name format.
- The class name has to be the same as the file name.
- The class must implement the \Swiftriver\Core\EventDistribution\IEventHandler class.
- Must be in the namespace Swiftriver\EventHandlers
- Contain the following functions:
- HandleEvent($event, $configuration, $logger): Contains the event code.
- Name(): Returns the impulse event.
- Description(): Returns the description of this event.
- ReturnRequiredParameters(): Returns an array of required parameters for the event.
- ReturnEventNamesToHandle(): Returns an array of the event enumerations the turbine tends to handle.
You may refer to the file UshahidiAPIEventHandler.php in /Modules/UshahidiAPIInterface/ folder for an example.
Important notes to consider during the EventDistribution phase
- The ReturnEventNamesToHandle() function points to an enumeration from the /EventDistribution/EventEnumeration.php file. This is where you can design your own custom enumeration.
- It is most appropriate to place event handlers within the application’s workflow. Application workflows are placed within the /Workflows/ folder. For example, all workflows related to channel activities are placed within the /Workflows/ChannelServices/ folder.
- The example below demonstrates how you would invoke an event within a specific place within the workflow:
$event = new \Swiftriver\Core\EventDistribution\GenericEvent(
\Swiftriver\Core\EventDistribution\EventEnumeration:: $ContentPostProcessing,
$processedContent);
$eventDistributor = new \Swiftriver\Core\EventDistribution\EventDistributor();
$eventDistributor->RaiseAndDistributeEvent($event);
Please feel free to contact the SwiftRiver team for any further assistance and help. You can contact us by emailing support@swiftly.org