diff --git a/src/Api/Module.php b/src/Api/Module.php index a78a826..7ffbba5 100644 --- a/src/Api/Module.php +++ b/src/Api/Module.php @@ -9,16 +9,24 @@ class Module protected $restClient; protected $moduleSchema; protected $params; + protected $uri; + protected $preSendHandler; - public function __construct($restClient, $moduleSchema, $options) + public function __construct($restClient, $moduleSchema, $options, $uri = null, $preSendHandler = null) { $this->restClient = $restClient; $this->moduleSchema = $moduleSchema; $this->params = $options; + $this->uri = $uri; + $this->preSendHandler = $preSendHandler; } public function apiFunction($data = []) { + if (!is_null($this->preSendHandler)) { + call_user_func_array($this->preSendHandler, [&$data, $this->uri, $this->params['method']]); + } + if ($this->moduleSchema) { $validationResult = Validator::validate($this->moduleSchema, $data); } diff --git a/src/Api/ModuleLoader.php b/src/Api/ModuleLoader.php index 6166d32..c93de2f 100644 --- a/src/Api/ModuleLoader.php +++ b/src/Api/ModuleLoader.php @@ -72,7 +72,7 @@ private function getFunctionInstance($options) 'method' => $options['definition']['method'] ]; - $module = new Module($restClient, $moduleSchema, $requestArgs); + $module = new Module($restClient, $moduleSchema, $requestArgs, $options['uri'], $options['sharedOptions']['preSendHandler']); $functionInstance = array($module, 'apiFunction'); return $functionInstance; } @@ -102,7 +102,10 @@ private function addModuleMapV1($versionFunctions, $moduleInfo, $version, $isSta 'url' => $apiUrl, 'definition' => $functionDefinition, 'sharedOptions' => $sharedOptions, - 'moduleSchema' => $moduleSchema + 'moduleSchema' => $moduleSchema, + 'uri' => implode('/', array_map(function($v) { + return rtrim($v, '/'); + }, $urlParts)), ]; $this->moduleMap->{$moduleName}->{$version}->{$functionName} = $this->getFunctionInstance($functionOptions); @@ -143,6 +146,9 @@ private function addModuleMapV4_0_0($functions, $moduleInfo, $version, $isStatic 'definition' => $functionDefinition, 'sharedOptions' => $sharedOptions, 'moduleSchema' => $this->getSchema($moduleInfo['schema'] ?? [], $version, $prop, $functionName), + 'uri' => implode('/', array_map(function($v) { + return rtrim($v, '/'); + }, $urlParts)), ]; diff --git a/src/GreenSMS.php b/src/GreenSMS.php index 86fac29..4dc23cd 100644 --- a/src/GreenSMS.php +++ b/src/GreenSMS.php @@ -2,6 +2,7 @@ namespace GreenSMS; +use BadFunctionCallException; use Exception; use GreenSMS\Api\MethodInvoker; use GreenSMS\Api\ModuleLoader; @@ -76,7 +77,8 @@ public function __construct($options = []) 'restClient' => $this->getHttpClient([ 'useCamelCase' => $this->camelCaseResponse ]), - 'version' => Version::getVersion($this->version) + 'version' => Version::getVersion($this->version), + 'preSendHandler' => $this->getPreSendHandler($options), ]; $this->addModules($sharedOptions); @@ -111,4 +113,17 @@ public function getHttpClient($args) $restClient = new RestClient($httpParams); return $restClient; } + + private function getPreSendHandler($options): ?callable + { + if (array_key_exists('preSendHandler', $options)) { + if (is_callable($options['preSendHandler'])) { + return $options['preSendHandler']; + } else { + throw new BadFunctionCallException('Key `preSendHandler` must be callable'); + } + } + + return null; + } } diff --git a/tests/PreSendHandlerTest.php b/tests/PreSendHandlerTest.php new file mode 100644 index 0000000..664e981 --- /dev/null +++ b/tests/PreSendHandlerTest.php @@ -0,0 +1,98 @@ +utility = new Utility(); + } + + public function testReplacement() + { + $client = new GreenSMS([ + 'user' => 'test', + 'pass' => 'test', + 'preSendHandler' => function(&$data, $uri, $method) { + $this->assertEquals('someVal', $data['someKey']); + $this->assertEquals('sms/send', $uri); + $this->assertEqualsIgnoringCase('post', $method); + $data['to'] = $this->utility->getRandomPhone(); + $data['txt'] = 'txt'; + } + ]); + + $response = $client->sms->send(['someKey' => 'someVal', 'to'=> 111]); + + $this->assertObjectHasProperty('request_id', $response); + } + + public function testEmptyData() + { + $client = new GreenSMS([ + 'user' => 'test', + 'pass' => 'test', + 'preSendHandler' => function($data, $uri, $method) { + $this->assertEquals('account/balance', $uri); + $this->assertEmpty($data); + $this->assertEqualsIgnoringCase('get', $method); + } + ]); + + $response = $client->account->balance(); + + $this->assertObjectHasProperty('balance', $response); + $this->assertEquals(4, $this->getCount()); + } + + public function testInvocable() + { + $invocable = new class extends TestCase{ + public function __invoke($data, $uri, $method) { + $this->assertEquals('account/balance', $uri); + $this->assertEmpty($data); + $this->assertEqualsIgnoringCase('get', $method); + } + }; + + (new GreenSMS([ + 'user' => 'test', + 'pass' => 'test', + 'preSendHandler' => $invocable, + ]))->account->balance(); + } + + public function testV4() + { + $client = new GreenSMS([ + 'user' => 'test', + 'pass' => 'test', + 'preSendHandler' => function($data, $uri, $method) { + $this->assertEmpty($data); + $this->assertEquals('account/webhook', $uri); + $this->assertEqualsIgnoringCase('get', $method); + } + ]); + + $response = $client->account->webhook->get(); + + $this->assertObjectHasProperty('webhook', $response); + $this->assertEquals(4, $this->getCount()); + } + + public function testNotCallable() + { + $this->expectException(BadFunctionCallException::class); + + new GreenSMS([ + 'user' => 'test', + 'pass' => 'test', + 'preSendHandler' => '', + ]); + } +}