Skip to content

Commit

Permalink
Add Interface, Payment Gateway and Payment Gateway Manager
Browse files Browse the repository at this point in the history
  • Loading branch information
Brendan Abbott committed Jun 8, 2011
1 parent 5d72045 commit 20d9a6b
Show file tree
Hide file tree
Showing 6 changed files with 301 additions and 3 deletions.
12 changes: 12 additions & 0 deletions assets/pgi_loader.preferences.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.active .settings.pgi-picker {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 0;
}
.active .settings.pgi-pickable {
border-top: 0;
padding-top: 0;
}
.active .settings.pgi-pickable legend {
display: none;
}
8 changes: 8 additions & 0 deletions assets/pgi_loader.preferences.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
$(document).ready(function() {

// Pickers
$('.pgi-picker').symphonyPickable({
pickables: '.pgi-pickable'
});

});
67 changes: 64 additions & 3 deletions extension.driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public function about() {

public function getSubscribedDelegates() {
return array(
array(
'page' => '/backend/',
'delegate' => 'AdminPagePreGenerate',
'callback' => 'appendAssets'
),
array(
'page' => '/system/preferences/',
'delegate' => 'AddCustomPreferenceFieldsets',
Expand All @@ -40,16 +45,72 @@ public function getSubscribedDelegates() {
Delegate Callbacks:
-------------------------------------------------------------------------*/

/**
* @uses AdminPagePreGenerate
*/
public function appendAssets(&$context) {
if(class_exists('Administration')
&& Administration::instance() instanceof Administration
&& Administration::instance()->Page instanceof HTMLPage
) {
// System Preferences
if($context['oPage'] instanceof contentSystemPreferences) {
Administration::instance()->Page->addScriptToHead(URL . '/extensions/pgi_loader/assets/pgi_loader.preferences.js', 10001, false);
Administration::instance()->Page->addStylesheetToHead(URL . '/extensions/pgi_loader/assets/pgi_loader.preferences.css', 'screen', 45);
}
}
}

/**
* Allows a user to set their default Payment Gateway for extensions to use
*
* @uses AddCustomPreferenceFieldsets
*/
public function appendPreferences($context) {
$fieldset = new XMLElement('fieldset');
$fieldset->setAttribute('class', 'settings');
// Get available Payment Gateways
require_once EXTENSIONS . '/pgi_loader/lib/class.paymentgatewaymanager.php';

$payment_gateway_manager = new PaymentGatewayManager($this);
$payment_gateways = $payment_gateway_manager->listAll();
if(count($payment_gateways) >= 1){
$fieldset = new XMLElement('fieldset', NULL, array('class' => 'settings pgi-picker'));
$fieldset->appendChild(new XMLElement('legend', __('Payment Gateway')));
$label = Widget::Label(__('Gateway'));
$options = array();

ksort($payment_gateways);

// Get the default gateway
try {
$default_gateway = $payment_gateway_manager->getDefaultGateway();
}
catch (PaymentGatewayException $ex) {
$default_gateway = false;
}

foreach($payment_gateways as $handle => $details) {
$options[] = array(
$handle,
$handle == $default_gateway,
$details['name']
);
}

$select = Widget::Select('settings[pgi_loader][default_gateway]', $options);
$label->appendChild($select);
$fieldset->appendChild($label);

// Append payment gateway selection
$context['wrapper']->appendChild($fieldset);
}

foreach($payment_gateways as $gateway) {
$gateway_settings = $payment_gateway_manager->create($gateway['handle'])->getPreferencesPane();

$context['wrapper']->appendChild($fieldset);
if(is_a($gateway_settings, 'XMLElement')) {
$context['wrapper']->appendChild($gateway_settings);
}
}
}

/**
Expand Down
46 changes: 46 additions & 0 deletions lib/class.paymentgateway.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

require_once(EXTENSIONS . '/pgi_loader/lib/class.paymentgatewaymanager.php');
require_once(EXTENSIONS . '/pgi_loader/lib/interface.paymentgateway.php');

/**
* The Exception to be thrown by a Payment Gateway
*/
class PaymentGatewayException extends Exception {}

/**
* The PaymentGateway class is a factory class to interface with different
* payment gateways. Payment gateways can be provided by extensions that choose
* to implement the `PaymentGateway` interface
*/
abstract class PaymentGateway implements iPaymentGateway {

/**
* Returns the PaymentGateway to interact with
* Calling this function multiple times will return unique objects.
*
* @param string $gateway
* The name of the gateway to use. If no `$gateway` is provided this
* will return the Default Gateway set by Symphony.
* @return PaymentGateway
*/
public static function create($gateway = null){
$payment_gateway_manager = new PaymentGatewayManager;
if(!is_null($gateway)){
return $payment_gateway_manager->create($gateway);
}
else{
return $payment_gateway_manager->create($payment_gateway_manager->getDefaultGateway());
}
}

/**
* The preferences to add to the preferences pane in the admin area.
*
* @return XMLElement
*/
public function getPreferencesPane(){
return new XMLElement('fieldset');
}
}

160 changes: 160 additions & 0 deletions lib/class.paymentgatewaymanager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<?php

require_once(EXTENSIONS . '/pgi_loader/lib/class.paymentgateway.php');
require_once(TOOLKIT . '/class.manager.php');

/**
* A manager to standardize the finding and listing of installed gateways.
*/
Class PaymentGatewayManager extends Manager {

public function __construct() {}

/**
* Sets the default gateway.
* Will throw an exception if the gateway can not be found.
*
* @param string $name
* @return void
*/
public function setDefaultGateway($name){
if($this->__getClassPath($name)){
Symphony::Configuration()->set('default_gateway', $name, 'pgi_loader');
Administration::instance()->saveConfig();
}
else throw new PaymentGatewayException(
__('This gateway can not be found. Can not save as default.')
);
}

/**
* Returns the default gateway.
* Will throw an exception if the gateway can not be found.
*
* @return string
*/
public function getDefaultGateway(){
$gateway = Symphony::Configuration()->get('default_gateway', 'pgi_loader');
if($gateway) {
return $gateway;
}
else throw new PaymentGatewayException(
__('There is no default gateway found.')
);
}

/**
* Returns the classname from the gateway name.
* Does not check if the gateway exists.
*
* @param string $name
* @return string
*/
public function __getClassName($name){
return $name . 'PaymentGateway';
}

/**
* Finds the gateway by name
*
* @param string $name
* The gateway to look for
* @return string|boolean
* If the gateway is found, the path to the folder containing the
* gateway is returned.
* If the gateway is not found, false is returned.
*/
public function __getClassPath($name){
$extensions = Symphony::ExtensionManager()->listInstalledHandles();

if(is_array($extensions) && !empty($extensions)){
foreach($extensions as $e) {
if(is_file(EXTENSIONS . "/$e/payment-gateways/pgi.$name.php")) {
return EXTENSIONS . "/$e/payment-gateways";
}
}
}

return false;
}

/**
* Returns the path to the gateway file.
*
* @param string $name
* The gateway to look for
* @return string|boolean
* @todo fix return if gateway does not exist.
*/
public function __getDriverPath($name){
return $this->__getClassPath($name) . "/pgi.$name.php";
}

/**
* Finds the name from the filename.
* Does not check if the gateway exists.
*
* @param string $filename
* @return string|boolean
*/
public function __getHandleFromFilename($filename){
return preg_replace(array('/^pgi./i', '/.php$/i'), '', $filename);
}

/**
* Returns an array of all gateways.
* Each item in the array will contain the return value of the about()
* function of each gateway.
*
* @return array
*/
public function listAll(){
$result = array();

$extensions = Symphony::ExtensionManager()->listInstalledHandles();

if(is_array($extensions) && !empty($extensions)){
foreach($extensions as $e){
if(!is_dir(EXTENSIONS . "/$e/payment-gateways")) continue;

$tmp = General::listStructure(EXTENSIONS . "/$e/payment-gateways", '/pgi.[\\w-]+.php/', false, 'ASC', EXTENSIONS . "/$e/payment-gateways");

if(is_array($tmp['filelist']) && !empty($tmp['filelist'])){
foreach($tmp['filelist'] as $f){
$f = preg_replace(array('/^pgi./i', '/.php$/i'), '', $f);
$result[$f] = $this->about($f);
}
}
}
}

ksort($result);
return $result;
}

/**
* Creates a new object from a gateway name.
*
* @param string $name
* The gateway to look for
* @return PaymentGateway
* If the gateway is found, an instantiated object is returned.
* If the gateway is not found, an error is triggered.
*/
public function &create($name) {
$classname = $this->__getClassName($name);
$path = $this->__getDriverPath($name);

if(!is_file($path)){
trigger_error(__('Could not find Payment Gateway <code>%s</code>. Ensure that it is installed, and enabled.', array($name)), E_USER_ERROR);
return false;
}

if(!class_exists($classname)) {
require_once($path);
}

return new $classname;
}

}
11 changes: 11 additions & 0 deletions lib/interface.paymentgateway.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

/**
* Provides an interface that extensions can utilise so that developers
* have a consistent API to interface with.
*/
interface iPaymentGateway {

public static function processTransaction(array $values);

}

0 comments on commit 20d9a6b

Please sign in to comment.