Skip to content

Commit

Permalink
Merge pull request #2 from adelowo/develop
Browse files Browse the repository at this point in the history
Improvements in the Factory class
  • Loading branch information
adelowo committed Dec 30, 2016
2 parents 9c694bf + a786f1c commit de5cf81
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 32 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.MD
Expand Up @@ -10,7 +10,7 @@

## 1.0.1

* Marked `AmplifyPayAdapter::baseUrl` as a constant to allow it's access from plugins not in the core.
* Marked `AmplifyPayAdapter::BASE_URL` as a constant to allow it's access from plugins not in the core.

## 1.1.0

Expand All @@ -28,3 +28,7 @@
## 1.1.2
* BugFix - prevented an internal adapter from being overriden when adding a custom adapter with the same key as one defined in \Gbowo\GbowoFactory

## 1.2.0
* Added `Gbowo\Exception\UnknownAdapterException`. This is thrown only by the `Gbowo\GbowoFactory`
* Improvement/BugFix - Return the instance attached to `Gbowo\GbowoFactory` ___as is___ rather than re-instantiating it - `new`ing it up .
This is to prevent running into dependency issues, as a custom adapter might require some certain class/config value in it's constructor. If that happens, `Gbowo\GbowoFactory` cannot figure that out as it is not a `Container`.
34 changes: 23 additions & 11 deletions README.md
Expand Up @@ -125,6 +125,7 @@ var_dump($adapter->getPaymentData($_GET['tran_response'])); // clean up

[Paystack](https://paystack.co) :

* `charge(array $data = [])`
* `getCustomer(int $id)`
* `getAllCustomers()`
* `chargeWithToken(array $userToken)` // a token plus email address (or custom stuff)
Expand All @@ -134,12 +135,14 @@ var_dump($adapter->getPaymentData($_GET['tran_response'])); // clean up

[Amplifypay](https://amplifypay.com) :

* `charge(array $data = [])`
* `unsubcribeCustomerFromPlan(array $data)`
* `chargeWithToken(array $userToken)` //a token in amplifypay is a key pair of values.
* `getPaymentData(string $transRef)`
* `fetchPlan($planIdentifier)`
* `fetchAllPlans()`

> The `charge` method parameter (`array $data = []`) should contain stuffs like amount, email, x, y, z). Those would be handed over to the payment gateway
<h2 id="extend">Custom Adapters</h2>

Expand All @@ -164,9 +167,11 @@ $interswitch = new class implements \Gbowo\Contract\Adapter\AdapterInterface
}
};

$adapter = (new \Gbowo\GbowoFactory(["interswitch" => $interswitch]))->createAdapter("interswitch")
$adapter = new \Gbowo\GbowoFactory(["interswitch" => $interswitch]); //add the interswith adapter as a custom one.

var_dump($adapter instanceof \Gbowo\Contract\Adapter\AdapterInterface);
$interswitchAdapter = $adapter->createAdapter("interswitch");

$interswitchAdapter->charge(['a' => 'b', 'c' => 'd']);
```

<h2 id="plugins">Extending Adapters via Plugins</h2>
Expand All @@ -182,7 +187,7 @@ To prevent this, _Gbowo_ implements a plugin architecture that eases extension o
A look at the [paystack adapter](src/Gbowo/Adapter/Paystack/PaystackAdapter.php) and [amplifypay](src/Gbowo/Adapter/Amplifypay/AmplifypayAdapter.php) would reveal that they do not have the methods described above in their public api. In fact they expose only 3 methods :
* `__construct(Client $client = null)` // if it counts as one
* `getHttpClient()`
* `charge(array $data = null)` //This is gotten from the `AdapterInterface` implemented.
* `charge(array $data = [])` //This is gotten from the `AdapterInterface` implemented.

But a look at their `registerPlugins` method - which is gotten from the __Pluggable__ trait - tells how the methods described in the `Adapters method` section above come about.

Expand All @@ -192,7 +197,7 @@ A plugin is a plain PHP class that **MUST** implement the `PluginInterface`. Thi

```php

namespace Vendor/AdapterName/Plugin;
namespace Vendor\AdapterName\Plugin;

use Gbowo/Contract/Plugin/PluginInterface;

Expand All @@ -209,7 +214,8 @@ class ApiPinger implements PluginInterface
*/
public function setAdapter(AdapterInterface $adapter)
{
$this->adapter = $adapter ; //useful for helpers like getting the already configured Client object
//useful for helpers like getting stuffs from "accessors" on the adapter instance like the already configured HttpClient object
$this->adapter = $adapter ;
return $this;
}
}
Expand Down Expand Up @@ -294,11 +300,17 @@ artisan vendor:publish

```php

$paystackAdapter = app("gbowo")->adapter("paystack"); //or "amplifypay"

$authorization_uri = $paystackAdapter->charge(["email" => "root@app.com" , "amount" => 8000]); //can add some other key pair to the array

return redirect($authorization_uri);
class SomeController extends Controller
{
public function chargeCustomer(Request $request)
{
$paystackAdapter = app("gbowo")->adapter("paystack"); //or "amplifypay"

$data = ["email" => $request->get('email') , "amount" => $request->get('amount')];

return redirect($paystackAdapter->charge($data));
}
}

```

Expand All @@ -322,7 +334,7 @@ And you can access this new adapter anywhere in your code via

```php

$voguePay = $this->app["gbowo"]->adapter("voguePay");
$voguePay = app("gbowo")->adapter("voguePay");

$voguePay->charge(['c' => 'd']);

Expand Down
9 changes: 9 additions & 0 deletions src/Gbowo/Exception/UnknownAdapterException.php
@@ -0,0 +1,9 @@
<?php

namespace Gbowo\Exception;

use Exception;

class UnknownAdapterException extends Exception
{
}
48 changes: 30 additions & 18 deletions src/Gbowo/GbowoFactory.php
Expand Up @@ -3,7 +3,7 @@

namespace Gbowo;

use InvalidArgumentException;
use Gbowo\Exception\UnknownAdapterException;
use Gbowo\Adapter\Paystack\PaystackAdapter;
use Gbowo\Contract\Adapter\AdapterInterface;
use Gbowo\Adapter\Amplifypay\AmplifypayAdapter;
Expand All @@ -15,45 +15,57 @@ class GbowoFactory

const AMPLIFY_PAY = "amplifypay";

/**
* @var AdapterInterface[]
*/
protected $availableAdapters = [];

public function __construct(array $types = [])
{
$this->setDefaultAdapters();

if (!empty($types)) {
foreach ($types as $type => $value) {
if (array_key_exists($type, $this->availableAdapters)) {
throw $this->throwException(
"You cannot override an internal adapter"
);
}

if (!$value instanceof AdapterInterface) {
throw $this->throwException("This is not a valid adapter");
}
}
$this->validateCustomAdapters($types);
$this->availableAdapters = array_merge($this->availableAdapters, $types);
}
}

protected function setDefaultAdapters()
{
$this->availableAdapters = [
self::PAYSTACK => PaystackAdapter::class,
self::AMPLIFY_PAY => AmplifypayAdapter::class
self::PAYSTACK => new PaystackAdapter(),
self::AMPLIFY_PAY => new AmplifypayAdapter()
];
}

/**
* @param array $types
* @throws \Gbowo\Exception\UnknownAdapterException
*/
protected function validateCustomAdapters(array $types)
{
foreach ($types as $type => $value) {
if (array_key_exists($type, $this->availableAdapters)) {
throw $this->throwException(
"You cannot override an internal adapter"
);
}

if (!$value instanceof AdapterInterface) {
throw $this->throwException("This is not a valid adapter");
}
}
}

protected function throwException(string $message)
{
return new InvalidArgumentException($message);
return new UnknownAdapterException($message);
}

/**
* @param string $adapterIdentifier
* @return AdapterInterface
* @throws InvalidArgumentException
* @return \Gbowo\Contract\Adapter\AdapterInterface
* @throws \Gbowo\Exception\UnknownAdapterException
*/
public function createAdapter(string $adapterIdentifier)
{
Expand All @@ -63,6 +75,6 @@ public function createAdapter(string $adapterIdentifier)
);
}

return new $this->availableAdapters[$adapterIdentifier];
return $this->availableAdapters[$adapterIdentifier];
}
}
4 changes: 2 additions & 2 deletions tests/GbowoFactoryTest.php
Expand Up @@ -90,15 +90,15 @@ public function testAddedAdaptersAtRunTime($adapter)
}

/**
* @expectedException \InvalidArgumentException
* @expectedException \Gbowo\Exception\UnknownAdapterException
*/
public function testUnknownAdapterIsRequested()
{
$this->factory()->createAdapter("stripe");
}

/**
* @expectedException \InvalidArgumentException
* @expectedException \Gbowo\Exception\UnknownAdapterException
*/
public function testInvalidCustomAdapterIsMountedAtRuntime()
{
Expand Down

0 comments on commit de5cf81

Please sign in to comment.