Skip to content

Commit 45279d6

Browse files
committed
change parser to ussd.
1 parent ff3cdec commit 45279d6

File tree

4 files changed

+92
-60
lines changed

4 files changed

+92
-60
lines changed

readme.md

+52-24
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
- [Cache](#cache)
2929
- [Parser](#parser)
3030
- [Simulator](#simulator)
31+
- [JSON](#json)
3132
- [Testing](#testing)
3233
- [Security](#security)
3334
- [Contribution](#contribution)
@@ -120,10 +121,9 @@ php artisan vendor:publish --provider="Bmatovu\Ussd\UssdServiceProvider" --tag="
120121
```
121122

122123
```php
123-
use Bmatovu\Ussd\Parser;
124+
use Bmatovu\Ussd\Ussd;
124125
use Illuminate\Http\Request;
125126
use Illuminate\Http\Response;
126-
use Illuminate\Support\Facades\Storage;
127127

128128
/**
129129
* @see https://developers.africastalking.com/docs/ussd/overview
@@ -133,11 +133,9 @@ class UssdController extends Controller
133133
public function __invoke(Request $request): Response
134134
{
135135
try {
136-
$menu = menus_path('menu.xml');
136+
$ussd = new Ussd('menu.xml', $request->session_id);
137137

138-
$parser = new Parser($menu, $request->session_id);
139-
140-
$output = $parser->parse($request->text);
138+
$output = $ussd->handle($request->text);
141139
} catch(\Exception $ex) {
142140
return response('END ' . $ex->getMessage());
143141
}
@@ -166,7 +164,7 @@ php artisan ussd:validate
166164

167165
The package comes with a CLI USSD simulator supporting a handful of populator aggregators.
168166

169-
Public the simulator config file to get started. Update the aggregator and the USSD service endpoint in the config file.
167+
Publish the simulator config file to get started. Update the aggregator and the USSD service endpoint in the config file.
170168

171169
```bash
172170
php artisan vendor:publish --provider="Bmatovu\Ussd\UssdServiceProvider" --tag="simulator"
@@ -175,7 +173,7 @@ Usage:
175173

176174
```bash
177175
./vendor/bin/ussd --help
178-
./vendor/bin/ussd 0790123123
176+
./vendor/bin/ussd 256772100103
179177
```
180178

181179
__If you're an aggregator missing from the current list reachout to have you added. Or simply send a pull request__
@@ -377,12 +375,12 @@ Provider is the class providing the list of items. Each item must container an `
377375
```php
378376
$listItems = (new \App\Ussd\Providers\SavingAccountsProvider)->load();
379377

380-
// [
381-
// [
382-
// 'id' => 4364852, // account_id
383-
// 'label' => '01085475262', // account_number
384-
// ],
385-
// ]
378+
[
379+
[
380+
'id' => 4364852, // account_id
381+
'label' => '01085475262', // account_number
382+
],
383+
];
386384
```
387385

388386
```xml
@@ -426,7 +424,7 @@ $this->store->put('color', 'pink');
426424
Example for saving any variable from the incoming USSD request.
427425

428426
```php
429-
(new Parser($xpath, $request->session_id))
427+
(new Ussd($menu, $request->session_id))
430428
// ->save($request->all())
431429
->save([
432430
'phone_number' => $request->phone_number,
@@ -441,7 +439,7 @@ By default the parsing starts at the 1st element in you menu file, i.e `/menu/*[
441439
If you wish to start from a different point or using a custom menu file structure. Here's how to go about it...
442440

443441
```php
444-
(new Parser($xpath, $request->session_id))
442+
(new Ussd($menu, $request->session_id))
445443
->entry("/menus/menu[@name='sacco']/*[1]");
446444
```
447445

@@ -457,17 +455,47 @@ The provider class should implement `Bmatovu\Ussd\Contracts\Aggregator`.
457455
458456
```diff
459457
{
460-
+ "aggregator": "generic",
461-
"aggregators": {
462-
+ "generic": {
463-
+ "provider": "App\\Ussd\\Simulator\\Hubtel",
464-
+ "uri": "http://localhost:8000/api/ussd/hubtel",
465-
+ "service_code": "*123#"
466-
+ }
467-
}
458+
+ "aggregator": "hubtel",
459+
"aggregators": {
460+
+ "hubtel": {
461+
+ "provider": "App\\Ussd\\Simulator\\Hubtel",
462+
+ "uri": "http://localhost:8000/api/ussd/hubtel",
463+
+ "service_code": "*123#"
464+
+ }
465+
}
468466
}
469467
```
470468

469+
### JSON
470+
471+
Why use XML 🥴 and not JSON ☺️?
472+
473+
Compare the snippets below...
474+
475+
```xml
476+
<menu name="demo">
477+
<question name="guest" text="Enter Name: "/>
478+
<response text="Hello {{guest}}."/>
479+
</menu>
480+
```
481+
482+
```json
483+
{
484+
"@name": "demo",
485+
"question": {
486+
"@name": "guest",
487+
"@text": "Enter Name:"
488+
},
489+
"response": {
490+
"@text": "Hello {{guest}}."
491+
}
492+
}
493+
```
494+
495+
XML is more suited for writing programming language like constructs.
496+
It's very easy to validate XML schemas.
497+
XML is also more compact and readable 🥰.
498+
471499
## Testing
472500

473501
To run the package's unit tests, run the following command:

src/Traits/ParserUtils.php src/Traits/Utilities.php

+7-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
use Illuminate\Contracts\Config\Repository as ConfigRepository;
88
use Illuminate\Support\Str;
99

10-
trait ParserUtils
10+
trait Utilities
1111
{
1212
public function __get(string $key)
1313
{
@@ -19,11 +19,15 @@ public function __set(string $key, $value)
1919
$this->{$key} = $value;
2020
}
2121

22-
protected function xpathFromStr(string $file): \DOMXPath
22+
protected function fileToXpath(string $menuFile): \DOMXPath
2323
{
24+
if (! file_exists($menuFile)) {
25+
$menuFile = menus_path($menuFile);
26+
}
27+
2428
$doc = new \DOMDocument();
2529

26-
$doc->load($file);
30+
$doc->load($menuFile);
2731

2832
return new \DOMXPath($doc);
2933
}

src/Parser.php src/Ussd.php

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,25 @@
33
namespace Bmatovu\Ussd;
44

55
use Bmatovu\Ussd\Contracts\AnswerableTag;
6-
use Bmatovu\Ussd\Traits\ParserUtils;
6+
use Bmatovu\Ussd\Traits\Utilities;
77
use Illuminate\Container\Container;
88
use Illuminate\Contracts\Config\Repository as ConfigRepository;
99

10-
class Parser
10+
class Ussd
1111
{
12-
use ParserUtils;
12+
use Utilities;
1313

1414
protected \DOMXPath $xpath;
1515
protected string $sessionId;
1616
protected Store $store;
1717
protected bool $newSession = false;
1818

1919
/**
20-
* @param \DOMXPath|string $xpath
20+
* @param \DOMXPath|string $menu
2121
*/
22-
public function __construct($xpath, string $sessionId)
22+
public function __construct($menu, string $sessionId)
2323
{
24-
$this->xpath = $xpath instanceof \DOMXPath ? $xpath : $this->xpathFromStr($xpath);
24+
$this->xpath = $menu instanceof \DOMXPath ? $menu : $this->fileToXpath($menu);
2525

2626
$config = Container::getInstance()->make(ConfigRepository::class);
2727
$store = $config->get('ussd.cache.store', 'file');
@@ -58,7 +58,7 @@ public function save(array $options): self
5858
return $this;
5959
}
6060

61-
public function parse(?string $userInput = ''): string
61+
public function handle(?string $userInput = ''): string
6262
{
6363
$answer = $this->getAnswer($userInput);
6464

tests/ParserTest.php tests/UssdTest.php

+26-26
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
namespace Bmatovu\Ussd\Tests;
44

5-
use Bmatovu\Ussd\Parser;
5+
use Bmatovu\Ussd\Ussd;
66

7-
class ParserTest extends TestCase
7+
class UssdTest extends TestCase
88
{
99
public function testMissingTag()
1010
{
@@ -14,9 +14,9 @@ public function testMissingTag()
1414

1515
$xpath = $this->xmlToXpath('<dummy/>');
1616

17-
$parser = (new Parser($xpath, 'ussd_wScXk'))->entry('/*[1]');
17+
$ussd = (new Ussd($xpath, 'ussd_wScXk'))->entry('/*[1]');
1818

19-
$parser->parse();
19+
$ussd->handle();
2020
}
2121

2222
public function testExceptionExit()
@@ -27,9 +27,9 @@ public function testExceptionExit()
2727

2828
$xpath = $this->xmlToXpath('<response text="Bye bye."/>');
2929

30-
$parser = (new Parser($xpath, 'ussd_wScXk'))->entry('/*[1]');
30+
$ussd = (new Ussd($xpath, 'ussd_wScXk'))->entry('/*[1]');
3131

32-
$parser->parse();
32+
$ussd->handle();
3333
}
3434

3535
public function testProceedQuietly()
@@ -43,14 +43,14 @@ public function testProceedQuietly()
4343

4444
$xpath = $this->xmlToXpath($xml);
4545

46-
$parser = new Parser($xpath, 'ussd_wScXk');
46+
$ussd = new Ussd($xpath, 'ussd_wScXk');
4747

48-
$parser->store = $this->store; // ->set('name', 'John Doe');
48+
$ussd->store = $this->store; // ->set('name', 'John Doe');
4949

50-
$output = $parser->parse();
50+
$output = $ussd->handle();
5151

5252
static::assertSame('Enter username: ', $output);
53-
static::assertSame('John Doe', $parser->store->get('name'));
53+
static::assertSame('John Doe', $ussd->store->get('name'));
5454
}
5555

5656
public function testReuseSession()
@@ -67,9 +67,9 @@ public function testReuseSession()
6767

6868
$xpath = $this->xmlToXpath($xml);
6969

70-
$parser = new Parser($xpath, 'ussd_wScXk');
70+
$ussd = new Ussd($xpath, 'ussd_wScXk');
7171

72-
$output = $parser->parse();
72+
$output = $ussd->handle();
7373

7474
static::assertSame('Enter username: ', $output);
7575
static::assertSame('ussd_wScXk', $this->store->get('_session_id'));
@@ -95,9 +95,9 @@ public function testBreakpoints()
9595

9696
$xpath = $this->xmlToXpath($xml);
9797

98-
$parser = new Parser($xpath, 'ussd_wScXk');
98+
$ussd = new Ussd($xpath, 'ussd_wScXk');
9999

100-
$output = $parser->parse();
100+
$output = $ussd->handle();
101101

102102
static::assertSame('Say hi: ', $output);
103103
}
@@ -114,9 +114,9 @@ public function testParseLongCode()
114114

115115
$xpath = $this->xmlToXpath($xml);
116116

117-
$parser = (new Parser($xpath, 'ussd_wScXk'));
117+
$ussd = (new Ussd($xpath, 'ussd_wScXk'));
118118

119-
$output = $parser->parse('Mr*John');
119+
$output = $ussd->handle('Mr*John');
120120

121121
static::assertSame('Enter last name: ', $output);
122122
}
@@ -138,14 +138,14 @@ public function testTracksAnswers()
138138

139139
$xpath = $this->xmlToXpath($xml);
140140

141-
$parser = (new Parser($xpath, 'ussd_wScXk'));
141+
$ussd = (new Ussd($xpath, 'ussd_wScXk'));
142142

143-
$parser->store->put('title', 'Mr.');
144-
$parser->store->put('_answer', 'Mr.');
143+
$ussd->store->put('title', 'Mr.');
144+
$ussd->store->put('_answer', 'Mr.');
145145

146-
$parser->parse('John*Doe');
146+
$ussd->handle('John*Doe');
147147

148-
static::assertSame('Mr.*John*Doe', $parser->store->get('_answer'));
148+
static::assertSame('Mr.*John*Doe', $ussd->store->get('_answer'));
149149
}
150150

151151
public function testPathFromFile()
@@ -160,9 +160,9 @@ public function testPathFromFile()
160160

161161
file_put_contents($menuFile, $xml);
162162

163-
$parser = (new Parser($menuFile, 'ussd_wScXk'));
163+
$ussd = (new Ussd($menuFile, 'ussd_wScXk'));
164164

165-
$output = $parser->parse('');
165+
$output = $ussd->handle('');
166166

167167
static::assertSame('Enter username: ', $output);
168168

@@ -177,13 +177,13 @@ public function testSaveOptions()
177177

178178
$rand = rand(100, 1000);
179179

180-
$parser = (new Parser($xpath, 'ussd_wScXk'))
180+
$ussd = (new Ussd($xpath, 'ussd_wScXk'))
181181
->entry('/*[1]')
182182
->save(['rand' => $rand])
183183
;
184184

185-
$parser->parse();
185+
$ussd->handle();
186186

187-
static::assertSame($rand, $parser->store->get('rand'));
187+
static::assertSame($rand, $ussd->store->get('rand'));
188188
}
189189
}

0 commit comments

Comments
 (0)