-
Notifications
You must be signed in to change notification settings - Fork 71
Introducing the SBT PHP Core
This page serves as a guide to developers who want to gain a general overview over the PHP core. Note that the PHP Core is currently experimental and may change in future.
In order to allow the same level of extensibility that we have in the Java API, the project uses OO PHP. The project structure follows the standard PHP MVC pattern, and therefore consists of 5 core components:
-
index.php – The front controller. This is the only file that should be exposed to the user. Access to all other files should be restricted.
-
src/controllers – Contains application controllers, such as Proxy.php and the various controllers for generating plugin code.
-
src/views – Contains HTML and JavaScript (i.e. views, also known as templates)
-
src/models – Contains data models. For example, SBTKSettings.php
-
system/ - Contains the core system components, such as the Guzzle and OAuth libraries and default configuration.
-
autoload.php – Automatically determines the project's root directory (by searching for the root ID file ibm-sbt-sdk-root-id.php) and is responsible for loading required classes / dependencies.
The essential concept behind MVC is to allow programmers to separate data from application logic and visual presentation. That is, the MVC pattern is based on the separation of objects into one of three categories — models for maintaining data, views for displaying all or a portion of the data, and controllers for handling events that affect the model or view(s).
Because of this separation, multiple views and controllers can interface with the same model. Even new types of views and controllers that never existed before can interface with a model without forcing a change in the model design.
At the core of the MVC pattern lies the model, which essentially is a programmatic representation of the data that drives the application and actions that the user can apply to this data. Above the model lies what is called a “view”. Views are the application’s front end. That is,they receive data or events from the controller, consequently displaying HTML code which is sent to the client and rendered by their browser.
For example the sbtk-wp.php calls the SBTKPlugin controller. This controller extends the BasePluginController (which in turn is based on the BaseController) SBTKPlugin controller handles the plugin creation - it creates the header and communityGrid (we can add other methods for bookmarksGrid etc). Such a grid is created as follows:
- load settings
- generate config data
- load view
The view handles the HTML generation. The config data is passed to the view (views should never have access to anything but the config data and html/js) by the controllers.
Events typically cause a controller to access or change a model, or view, or both. Whenever a controller changes a model’s data or properties, all dependent views are automatically updated. Similarly, whenever a controller changes a view, for example, by revealing areas that were previously hidden, the view gets data from the underlying model to refresh itself.
The project currently handles basic authentication, OAuth 1.0 and OAuth 2.0 using Guzzle (which in turn relies on cURL).
Note: SmartCloud only supports PLAINTEXT for OAuth 1.0 – consequently the protocol will fail if other signanure methods, such as HMAC-SHA1 are used. Further more, SmartCloud does not support the x-oauth-body-signature field.
To support callback within an object oriented setting, a frontpage controller was developed, allowing users to specify the method (and class in which this method resides) that is to be called:
http://www.example.com/index.php?plugin=guzzle&class=OAuth1Endpoint&method=callback
A PHP SBTK plugin for a content management system (in our case, Wordpress or Moodle) consists of two separate projects: the PHP core and the CMS plugin project. The PHP core is designed in such a way that it can run as a standalone – the CMS plugin is merely a layer on top of the core that interfaces with the CMS API. Consequently the problem arises as to how to load configuration settings. We have identified three approaches – each of which is discussed below.
Details: Both the plugin and the PHP core will be delivered with a default configuration file (private/conf.php) that reflects best PHP practices: i.e. an associative array, $conf, in which each entry represents an endpoint configuration setting. i.e.
...
$config['smartcloud.url'] = 'https://apps.na.collabserv.com';
$config['smartcloud.consumerKey'] = 'b43c48f51c498717c8547aee0590abc2';
$config['smartcloud.consumerSecret'] = 'd46e0237d5de41feb4b446089a0575f3';
...
When receiving a request from the client, the application needs to determine which settings to load. Calls will not be made directly to conf.php (as direct array access is bad practice and will be messy). Instead a separate layer, the SBTKSetting object, will be employed. Upon receiving a request, the SBTKSetting object will need to decide from where to load the configuration settings: if no custom configuration settings exist, the default configuration set out in private/conf.php will be loaded. The problem arises when deciding from where to load the custom configuration information, as this will differ for each deployment (i.e. a standalone core deployment will load this information from a separate settings file specified by the programmer; the wordpress plugin will store custom information in the wp_options table, whilst say a Drupal plugin will need to reference the Drupal storage framework). So how do we best load configuration settings? The first option would be to include the SBTKSetting implementation as part of the core and have it check independently the type of deployment and then take the necessary steps for loading the configuration information. This approach will become messy very quickly: For one, a lot of uneccessary code will be contained with each different CMS plugin or core distribution. Furthermore, every time a new plugin is developed, the core PHP distribution of the SBTK will need to be modified.
The second option is to have the client decide what to load: To this end, we will have one public interface for SBTKSetting and separate implementations of it for each SBTK deployment. A SBTKSettings controller would be deployed as part of the core which decides, based on the request, what implementation of the SBTKSetting interface to load. Again, this is messy as unnecessary checks will need to be performed within the controller and JavaScript code snippets will need to be adjusted based on what deployment of the SBTK is to be used.
The third, and preferred option is to employ a separate build process for each SBTK deployment. That is, the build process for the core will differ slightly to that the Wordpress plugin as each deployment will contain only the relevant implementation of the SBTKSetting interface. This is the approach currently used.