Skip to content

Creating a third party connection

jessevondoom edited this page Dec 6, 2012 · 3 revisions

The platform is built to connect to as many third party services as possible — basically everything has been abstracted so functionality can be handed over to multiple connections when needed. In theory, any connection of one type can work identically to another connection of the same type. (So assets can be stored on S3 or Google Drive, payments with Paypal or Dwolla, etc.)

##The shape of a connection Connections are built with just two files and any additional libraries. The connection is defined in a JSON definition file, accompanied by a seed class — basically a driver/wrapper class. The JSON sets up data that needs to be stored with the connection like api key types, etc. That definition builds the form for single-user connections, and also sets whether the connection is OAuth enabled for multi-user instances, which are standardized.

##The json definition file The definition file lives in /framework/settings/connections/ and should be named after it's unique type identifier. (com.mailchimp.json, org.cashmusic.json, etc.) An example would look like:

{
	"name":"CASH Music",
	"description":"Some brief instructions to display for single-user instances.",
	"type":"org.cashmusic",
	"seed":"CASHMusicSeed",
	"scope":["system","assets"],
	"compatibility":["single","multi"],
	"interface":{
		"single":"generate",
		"multi":"docallback"
	},
	"dataTypes": {
		"single": {
			"key":"string",
			"secret":"string"
		},
		"multi": {
			"redirect_uri":"string",
			"client_id":"string",
			"client_secret":"string"
		}
	}
}
  • name: a common name that everyone will see
  • description: general description and instructions for users
  • type: unique identifier to the system, using that silly reverse domain junk
  • seed: the name of the seed class
  • scope: an array of strings used to narrow scope in the platform
  • compatibility: an array of at least one string, 'single' and/or 'multi'
  • interface: an object with properties for each compatibility scope — not used currently but will be
  • dataTypes: an object with objects for each compatibility scope - the 'single' property object will be used to generate the forms in single-user instances. The 'multi' property object defines the settings that should be stored in the default connections settings file / environment variable

##The Seed class The Seed class is a standardized interface for API interactions. OAuth interface is standardized via two static methods: 'getRedirectMarkup' and 'handleRedirectReturn.' These are called in the admin so a connection can properly store the token or api data needed for the connection to work in OAuth mode. All other functions are currently in the "hey there, let's make this work" world. Going forward we need to define abstractions so seeds of the same types can be interchangeable. We'll do this as we work...messy will get it right.

<?php
class CASHMusicSeed extends SeedBase {
	public $some_property_we_need;

	// all seeds should have an option for a user_id and connection_id
	// they can be passed as null, but they should exist
	public function __construct($user_id, $connection_id) {
		$this->settings_type = 'org.cashmusic';
		$this->user_id = $user_id;
		$this->connection_id = $connection_id;
		// get the connection with the id given
		if ($this->getCASHConnection()) {
			// the setup logic...
		} else {
			$this->error_message = 'could not get connection';
		}
	}

	public static function getRedirectMarkup($data=false) {
		// $data is the return URL computed based on the admin URL
		// get connection details:
		$connections = CASHSystem::getSystemSettings('system_connections');
		
		if (isset($connections['org.cashmusic'])) {
			// use the connections and return markup to be output in the admin.
		} else {
			// return 'A simple error message.';
		}
	}

	public static function handleRedirectReturn($data=false) {
		// $data is the full $_REQUEST array passed in, plus an extra parameter 
		// called 'connections_base_uri' which is the full admin URL for the connections page

		// return markup
	}
} // END class
?>

#Default connection settings (multi-user instances) In multi-user instances, default settings need to be stored in a JSON file or environment variable. The JSON is aptly named 'connections.json' and lives in the /framework/settings directory. As an environment variable it should be stored as 'cashmusic_connection_settings' in the same format. The JSON should mirror the definition file, a la:

{
	"org.cashmusic": {
		"redirect_uri":"https://127.0.0.1/admin/settings/connections/add/org.cashmusic/finalize",
		"client_id":"123456789000",
		"client_secret":"1f1f1ffsdfr019111553008199ccc0w8989"
	}
}