Skip to content

Commit

Permalink
Merge pull request #10 from hnuti-brontosaurus/upgrade-to-new-bis-api
Browse files Browse the repository at this point in the history
Upgrade to new bis api
  • Loading branch information
dakur authored Dec 17, 2021
2 parents 8bcf16b + 4093d10 commit 4499e0a
Show file tree
Hide file tree
Showing 48 changed files with 1,347 additions and 1,460 deletions.
198 changes: 198 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
This library allows you to easily communicate with BIS API.

# Installation

## Composer

Add path to `repositories`:

```
{
"url": "https://github.com/hnuti-brontosaurus/php-bis-api-client.git",
"type": "vcs"
}
```

and install package:
```
composer require hnuti-brontosaurus/php-bis-api-client
```

## Manually

Download latest version from [github](https://github.com/hnuti-brontosaurus/php-bis-api-client/releases) to your computer.


# Usage

First you need to create client instance. Note that you need to know the API URL and obtain client ID and secret from BIS administrator
to be able to authenticate against BIS.

```php
$client = (new BisClientFactory(
'apiUrl',
'clientId',
'clientSecret',
))->create();
```

Now you can perform any of available operations.

## Events

### Single event

Retrieve all information about single event:

```php
$event = $client->getEvent($id);

// examples of reading data
$event->getName();
$event->getOrganizer()->getResponsiblePerson();
$event->getRegistrationType()->isOfTypeCustomWebpage();
$event->getPlace()->getCoordinates();
```

### More events

Retrieve all information about multiple events.

Basic usage:

```php
$parameters = new \HnutiBrontosaurus\BisClient\Request\Event\EventParameters();
$events = $client->getEvents($parameters); // $parameters are optional

// example of reading data
foreach ($events as $event) {
$event->getName();
}
```

#### Filters

You can filter in many ways:

```php
$parameters = new \HnutiBrontosaurus\BisClient\Request\Event\EventParameters();

// only events of "voluntary" type
$parameters->setType(\HnutiBrontosaurus\BisClient\Enums\EventType::VOLUNTARY());

// only events of "PsB" program
$parameters->setProgram(\HnutiBrontosaurus\BisClient\Enums\Program::PSB());

// only events of "first time attendees" target group
$parameters->setTargetGroup(\HnutiBrontosaurus\BisClient\Enums\TargetGroup::FIRST_TIME_ATTENDEES());

// only events organized by organizational unit with ID 123
$parameters->setOrganizedBy(123);

// excludes running events
$parameters->excludeRunning();

$events = $client->getEvents($parameters);
```

For type, program and target group, you can set more values at once:

```php
$parameters = new \HnutiBrontosaurus\BisClient\Request\Event\EventParameters();

$parameters->setTypes([
\HnutiBrontosaurus\BisClient\Enums\EventType::VOLUNTARY(),
\HnutiBrontosaurus\BisClient\Enums\EventType::SPORT(),
]);

$events = $client->getEvents($parameters);
```

Note that each method call rewrites the previous one:

```php
$parameters = new \HnutiBrontosaurus\BisClient\Request\Event\EventParameters();

// sets "voluntary" type
$parameters->setType(\HnutiBrontosaurus\BisClient\Enums\EventType::VOLUNTARY());
// rewrites type with "sport"
$parameters->setType(\HnutiBrontosaurus\BisClient\Enums\EventType::SPORT());

$events = $client->getEvents($parameters);
```

#### Sorting

You can even use some basic sorting options:

```php
$parameters = new \HnutiBrontosaurus\BisClient\Request\Event\EventParameters();

// sort events by date from or date to
$parameters->orderByDateFrom();
$parameters->orderByDateTo(); // default

$events = $client->getEvents($parameters);
```

### Adding attendee

You can add attendee to an event:

```php
$client->addAttendee(new \HnutiBrontosaurus\BisClient\Request\Event\EventAttendee(
123, // event ID
'Jan', // first name
'Novák', // last name
'12.3.2004', // birth date
'123 456 789', // phone number
'[email protected]', // e-mail address
'poznámka', // note
['odpověď na otázku č. 1', '', 'odpověď na otázku č. 3'], // answers to optional questions (optional)
));
```

## Organizational units

Retrieve all information about all organizational units:

```php
$organizationalUnits = $client->getOrganizationalUnits();

// example of reading data
foreach ($organizationalUnits as $organizationalUnit) {
$organizationalUnit->getName();
$organizationalUnit->getCity();
$organizationalUnit->getChairman();
$organizationalUnit->getCoordinates();
}
```

# Development

## Installation

```
composer install
```

## Structure

- `docs` – instruction on how connection between brontoweb and BIS works (todo: move to brontoweb repo)
- `src` – source code
- `Enums` – basic enum types
- `Request` – request-related value objects
- `Response` – request-related value objects and exceptions
- `BisClient` – client itself, serves for making requests to BIS API
- `BisClientFactory` – collects configuration data, ensures authentication against BIS and returns `BisClient`
- `HttpClient` – wrapper around Guzzle client which adds BIS API specific pieces into the request
- `tests` – test code

**Note that this library bundles Guzzle HTTP client as we can not rely on having composer in user's codebase.**

## Tests

This library has just `tests/index.php` which – if run on a webserver – will
pass or fail visually – no error and results output or an exception.

Note that you have to obtain client ID and secret as well to be able to run the test. Ask BIS administrator to get it, copy `tests/secret.template.php` to `tests/secret.php` and insert credentials there.
9 changes: 3 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,19 @@
"minimum-stability": "stable",
"require": {
"php": ">=8.0",
"ext-dom": "*",
"grifart/enum": "^0.2.1",
"guzzlehttp/guzzle": "^6.3"
"guzzlehttp/guzzle": "^7.3"
},
"require-dev": {
"phpstan/phpstan": "^0.12.88",
"tracy/tracy": "^2.5"
},
"autoload": {
"psr-4": {
"HnutiBrontosaurus\\BisApiClient\\": "src/"
"HnutiBrontosaurus\\BisClient\\": "src/"
},
"classmap": [
"src/exceptions.php",
"src/Response/exceptions.php",
"src/Response/OrganizationalUnit/exceptions.php"
"src/exceptions.php"
]
},
"config": {
Expand Down
65 changes: 65 additions & 0 deletions src/Authenticator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php declare(strict_types = 1);

namespace HnutiBrontosaurus\BisClient;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Psr7\Request;


final class Authenticator
{

private ?AuthorizationToken $token;

public function __construct(
private string $clientId,
private string $clientSecret,
private Client $httpClient,
) {
$this->token = null; // not yet authenticated
}


/**
* @throws UnableToAuthorize
* @throws ConnectionToBisFailed
*/
public function authenticate(): AuthorizationToken
{
if ($this->token !== null) {
return $this->token;
}

try {
$response = $this->httpClient->send(new Request(
'POST',
Endpoint::AUTHENTICATION(),
[
'Accept' => 'application/json',
'Content-Type' => 'application/json',
],
\json_encode([
'grant_type' => 'client_credentials',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
]),
));
} catch (ClientException $e) {
if ($e->getCode() === 401) {
throw UnableToAuthorize::withPrevious($e);
}

throw ConnectionToBisFailed::withPrevious($e);

} catch (GuzzleException $e) {
throw ConnectionToBisFailed::withPrevious($e);
}

$payload = \json_decode($response->getBody()->getContents());
$this->token = AuthorizationToken::from($payload->access_token);
return $this->token;
}

}
28 changes: 28 additions & 0 deletions src/AuthorizationToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php declare(strict_types = 1);

namespace HnutiBrontosaurus\BisClient;


final class AuthorizationToken
{

private function __construct(
private string $value,
) {}

public static function from(string $value): self
{
return new self($value);
}

public function toString(): string
{
return $this->value;
}

public function __toString(): string
{
return $this->toString();
}

}
Loading

0 comments on commit 4499e0a

Please sign in to comment.