Skip to content

Commit 5fd4d7a

Browse files
committed
Refactoring
* Support DSN in client library (fromDsn) * Use arguments vs options in CLI for required input * Use common `BaseCommand` for all CLI commands * Support .env in CLI * Update README.md
1 parent 526d1a8 commit 5fd4d7a

24 files changed

Lines changed: 345 additions & 353 deletions

.env.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
HERALD_DSN=https://username:password@herald.dev/my-account/my-library/my-transport

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
vendor/*
22
config.ini
33
composer.phar
4+
.env
45
example/*

README.md

Lines changed: 68 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,21 @@ composer require herald-project/client-php
1313
use Herald\Client\Client as HeraldClient;
1414
use Herald\Client\Message as HeraldMessage;
1515

16-
// get the client
16+
// get the client with explicit parameters
1717
$herald = new HeraldClient(
1818
'[herald api username]',
1919
'[herald api password]',
2020
'[herald server uri]',
21-
'[herald transport, e.g. smtp]')
21+
'[herald transport, e.g. smtp]'),
22+
'[herald account]',
23+
'[herald library]',
2224
);
2325

26+
// get the client by DSN
27+
28+
$herald = HeraldClient::fromDsn('https://username:password@herald.dev/myAccount/myLibrary/myTransport');
29+
30+
2431
// check template existance.
2532
if ($herald->templateExists('signup')) {
2633
// get the message
@@ -37,43 +44,74 @@ if ($herald->templateExists('signup')) {
3744
}
3845
```
3946
## CLI usage
40-
```sh
41-
#!/bin/sh
4247

43-
common_param="\
44-
--username=api_username \
45-
--password=api_password \
46-
--apiurl=http://localhost:8787/api/v2 \
47-
--account=test \
48-
--library=test"
48+
You can use the `bin/herald-client` CLI application to run commands against your herald server.
49+
50+
The application needs a couple of configuration directives to work:
51+
52+
* username + password: The account you use to connect. Either a user account, or an API key+secret pair
53+
* apiurl: the base url of herald, (i.e. https://herald.dev) with postfix `/api/v2`
54+
* account + library: This is the library identifier you use to create your templates, layouts and transports
55+
56+
You can pass this data in 3 ways:
57+
58+
### Individual options:
59+
60+
For example:
61+
62+
./bin/herald-client --username=x --password=y --apiurl=https://herald.dev/api/v2 --account=test --library=test template:exists welcome
63+
64+
### A single DSN
65+
66+
For example:
67+
68+
./bin/herald-client --dsn=https://x:y@herald.dev/test/test/mandrill
69+
70+
### By environment variables
71+
72+
You can define the environment variable `HERALD_DSN` with a valid URL, this way you don't
73+
need to pass any options to the CLI application
74+
75+
### By .env
76+
77+
The Herald CLI application loads `.env` before running any commands, allowing you to create a `.env` file
78+
like this:
79+
80+
```ini
81+
HERALD_DSN=https://x:y@herald.dev/test/test/mandrill
82+
```
83+
84+
This way you also don't need to pass any options for each command
85+
86+
### Example commands
4987

50-
# get list of all contact lists
51-
bin/herald-client list:list ${common_param}
88+
# get list of all contact lists
89+
bin/herald-client list:list
5290

53-
# get list of contacts in contact list #1
54-
bin/herald-client list:contacts ${common_param} --listId=1
91+
# get list of contacts in contact list #1
92+
bin/herald-client list:contacts 1
5593

56-
# get list of segments for list #1
57-
bin/herald-client list:segments ${common_param} --listId=1
94+
# get list of segments for list #1
95+
bin/herald-client list:segments 1
5896

59-
# get available list_fields for list #1
60-
bin/herald-client list:fields ${common_param} --listId=1
97+
# get available list_fields for list #1
98+
bin/herald-client list:fields 1
6199

62-
# delete contact #42
63-
#bin/herald-client contact:delete ${common_param} --contactId=42
100+
# delete contact #42
101+
#bin/herald-client contact:delete 42
64102

65-
# get properties of contact #6
66-
bin/herald-client contact:properties ${common_param} --contactId=6
103+
# get properties of contact #6
104+
bin/herald-client contact:properties 6
67105

68-
# add new contact with address 'new.contact@example.com' to list #1
69-
bin/herald-client contact:add ${common_param} --listId=1 --address=new.contact@example.com
106+
# add new contact with address 'new.contact@example.com' to list #1
107+
bin/herald-client contact:add 1 new.contact@example.com
70108

71-
# add new property to contact #36
72-
bin/herald-client property:add ${common_param} --contactId=36 --listFieldId=4 --value="some value"
109+
# add new property to contact #36 for list field id #4
110+
bin/herald-client property:add 36 4 "some value"
73111

74-
# send message based on tamplate #1 to all contacts in list #1
75-
bin/herald-client list:send ${common_param} --listId=1 --templateId=1
112+
# send message based on template #7 to all contacts in list #1
113+
bin/herald-client list:send 1 7
76114

77-
# send message based on tamplate #1 to contacts in list #1 that meet the conditions for segment #6
78-
bin/herald-client list:send ${common_param} --listId=1 --templateId=1 --segmentId=6
115+
# send message based on template #1 to contacts in list #1 that meet the conditions for segment #6
116+
bin/herald-client list:send 1 7 6
79117

bin/herald-client

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
<?php
33

44
use Symfony\Component\Console\Application;
5+
use Symfony\Component\Dotenv\Dotenv;
56

67
$loader = __DIR__ . '/../vendor/autoload.php';
78

@@ -19,17 +20,20 @@ if (!file_exists($loader)) {
1920

2021
require $loader;
2122

23+
(new Dotenv())->load(__DIR__.'/../.env');
24+
25+
2226
$application = new Application('Herald client', '0.0.1');
2327
$application->setCatchExceptions(true);
2428
$application->add(new \Herald\Client\Command\SendCommand());
2529
$application->add(new \Herald\Client\Command\MessageListCommand());
2630
$application->add(new \Herald\Client\Command\MessageGetCommand());
27-
$application->add(new \Herald\Client\Command\CheckTemplateCommand());
31+
$application->add(new \Herald\Client\Command\TemplateExistsCommand());
2832

2933
$application->add(new \Herald\Client\Command\ListListCommand());
3034
$application->add(new \Herald\Client\Command\ListFieldListCommand());
35+
$application->add(new \Herald\Client\Command\ListContactsCommand());
3136
$application->add(new \Herald\Client\Command\SegmentListCommand());
32-
$application->add(new \Herald\Client\Command\ContactListCommand());
3337
$application->add(new \Herald\Client\Command\ContactAddCommand());
3438
$application->add(new \Herald\Client\Command\ContactViewCommand());
3539
$application->add(new \Herald\Client\Command\ContactDeleteCommand());

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
"guzzlehttp/guzzle": "^4.0|^5.0|^6.0"
2525
},
2626
"require-dev": {
27-
"symfony/console": "^2.4|^3.0"
27+
"symfony/console": "^2.4|^3.0",
28+
"symfony/dotenv": "^3.0"
2829
},
2930
"autoload": {
3031
"psr-4": {

composer.lock

Lines changed: 68 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Client.php

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,54 @@ class Client implements MessageSenderInterface
1717
private $account;
1818
private $library;
1919

20-
public function __construct($username, $password, $apiUrl, $account, $library, $transportAccount)
20+
public function __construct(
21+
$username,
22+
$password,
23+
$apiUrl,
24+
$account,
25+
$library,
26+
$transportAccount = null
27+
)
2128
{
2229
$this->username = $username;
2330
$this->password = $password;
2431
$this->apiUrl = $apiUrl;
2532
$this->account = $account;
2633
$this->library = $library;
34+
if (!$transportAccount) {
35+
$transportAccount = "-";
36+
}
2737
$this->transportAccount = $transportAccount;
2838
$this->baseUrl = $apiUrl.'/'.$account.'/'.$library;
2939
}
3040

41+
public static function fromDsn($dsn)
42+
{
43+
if (!filter_var($dsn, FILTER_VALIDATE_URL)) {
44+
throw new RuntimeException("DSN is an invalid URL: " . $dsn);
45+
}
46+
47+
$part = parse_url($dsn);
48+
49+
$username = $part['user'];
50+
$password = $part['pass'];
51+
$apiUrl = $part['scheme'] . '://' . $part['host'] . '/api/v2';
52+
$part['path'] = trim($part['path'], '/');
53+
$pathPart = explode('/', $part['path']);
54+
if ((count($pathPart)<2) || (count($pathPart)>3)) {
55+
throw new RuntimeException("Expecting url path with exactly 2 or 3 parts: " . $part['path']);
56+
}
57+
58+
$account = $pathPart[0];
59+
$library = $pathPart[1];
60+
$transportAccount = null;
61+
if (count($pathPart)>2) {
62+
$transportAccount = $pathPart[2];
63+
}
64+
65+
return new self($username, $password, $apiUrl, $account, $library, $transportAccount);
66+
}
67+
3168
public function setTemplateNamePrefix($prefix)
3269
{
3370
$this->templateNamePrefix = $prefix;

0 commit comments

Comments
 (0)