Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
"ext-curl": "*",
"ext-json": "*",
"php": "^7.2 || ^8.0",
"jean85/pretty-package-versions": "^1.5 || ^2.0"
"jean85/pretty-package-versions": "^1.5 || ^2.0",
"guzzlehttp/guzzle": "^7.9"
},
"require-dev": {
"phpunit/phpunit": "^8.2",
"friendsofphp/php-cs-fixer": "^2.15",
"friendsofphp/php-cs-fixer": "^2.19",
"symfony/var-dumper": "^5.2"
},
"autoload": {
Expand Down
3 changes: 1 addition & 2 deletions src/Catcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use Hawk\Addons\Environment;
use Hawk\Addons\Headers;
use Hawk\Transport\CurlTransport;
use Throwable;

/**
Expand Down Expand Up @@ -157,7 +156,7 @@ private function __construct(array $options)
$builder->registerAddon(new Headers());
$builder->registerAddon(new Environment());

$transport = new CurlTransport($options->getUrl(), $options->getTimeout());
$transport = Transport::init($options);

$this->handler = new Handler($options, $transport, $builder);

Expand Down
7 changes: 7 additions & 0 deletions src/Exception/TransportException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Hawk\Exception;

class TransportException extends \ErrorException
{
}
5 changes: 2 additions & 3 deletions src/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Hawk;

use Hawk\Exception\SilencedErrorException;
use Hawk\Transport\TransportInterface;

class Handler
{
Expand All @@ -19,7 +18,7 @@ class Handler
/**
* Transport layer for sending events to the remote server.
*
* @var TransportInterface
* @var Transport
*/
private $transport;

Expand Down Expand Up @@ -86,7 +85,7 @@ class Handler

public function __construct(
Options $options,
TransportInterface $transport,
Transport $transport,
EventPayloadBuilder $eventPayloadBuilder
) {
$this->options = $options;
Expand Down
12 changes: 12 additions & 0 deletions src/Options.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ class Options
*/
private $timeout = 2;

/**
* @var string
*/
private $transport = 'curl';

/**
* Map of accepted option keys to class properties.
*/
Expand All @@ -59,6 +64,7 @@ class Options
'beforeSend' => 'beforeSend',
'before_send' => 'beforeSend',
'timeout' => 'timeout',
'transport' => 'transport',
];

/**
Expand Down Expand Up @@ -91,6 +97,7 @@ private function setOption(string $key, $value): void
case 'integrationToken':
case 'release':
case 'url':
case 'transport':
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest to add a separate case for transport validation to restrict it only for allowed values

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@neSpecc Hawk\Transport::init have validation

public static function init(Options $options)
{
    $transports = self::getTransports();

    if (!array_key_exists($options->getTransport(), $transports)) {
        throw new TransportException('Invalid transport specified');
    }

    return new $transports[$options->getTransport()]($options);
}

if (!is_string($value)) {
throw new \InvalidArgumentException("Option '$key' must be a string.");
}
Expand Down Expand Up @@ -169,4 +176,9 @@ public function getTimeout(): int
{
return $this->timeout;
}

public function getTransport(): string
{
return $this->transport;
}
}
92 changes: 92 additions & 0 deletions src/Transport.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

declare(strict_types=1);

namespace Hawk;

use Hawk\Exception\TransportException;
use Hawk\Transport\CurlTransport;
use Hawk\Transport\GuzzleTransport;

/**
* Interface TransportInterface
*
* @package Hawk\Transport
*/
class Transport
{
/**
* @var string
*/
protected $url;

/**
* @var int
Comment on lines +18 to +24
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs missed

Copy link
Member

@neSpecc neSpecc Dec 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs are needed not only for typings. Add descriptions: why this property or function is used

*/
protected $timeout;

public static function init(Options $options)
{
$transports = self::getTransports();

if (!array_key_exists($options->getTransport(), $transports)) {
throw new TransportException('Invalid transport specified');
}

return new $transports[$options->getTransport()]($options);
}

public static function getTransports(): array
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

docs missed

{
return [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a hardcoded static registry in getTransports violates the Open-Closed Principle (OCP). Adding a new transport requires modifying the base class.

'curl' => CurlTransport::class,
'guzzle' => GuzzleTransport::class,
];
}

public function __construct(Options $options)
{
$this->url = $options->getUrl();
$this->timeout = $options->getTimeout();
}

/**
* Returns URL that object must send an Event
*
* @return string
*/
public function getUrl(): string
{
return $this->url;
}

public function getTimeout(): int
{
return $this->timeout;
}

/**
* Sends an Event
*
* @param Event $event
*
* @return mixed
*/
public function send(Event $event)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public function send(Event $event): ?array

{
$response = $this->_send($event);

try {
$data = json_decode($response, true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$data = json_decode($response, true);
if (json_last_error() !== JSON_ERROR_NONE) {
...
}

} catch (\Exception $e) {
$data = null;
}

return $data;
}

protected function _send(Event $event): string
{
throw new TransportException('Not implemented transport method _send()');
}
}
39 changes: 9 additions & 30 deletions src/Transport/CurlTransport.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,30 @@
namespace Hawk\Transport;

use Hawk\Event;
use Hawk\Options;
use Hawk\Transport;

/**
* Class CurlTransport is a transport object
*
* @package Hawk\Transport
*/
class CurlTransport implements TransportInterface
class CurlTransport extends Transport
{
/**
* URL to send occurred event
*
* @var string
*/
private $url;

/**
* CURLOPT_TIMEOUT
*
* @var int
*/
private $timeout;

/**
* CurlTransport constructor.
*
* @param string $url
*/
public function __construct(string $url, int $timeout)
{
$this->url = $url;
$this->timeout = $timeout;
}

/**
* @inheritDoc
* @param Options $options
*/
public function getUrl(): string
public function __construct(Options $options)
{
return $this->url;
parent::__construct($options);
}

/**
* @inheritDoc
*/
public function send(Event $event)
protected function _send(Event $event): string
{
/**
* If php-curl is not available then throw an exception
Expand All @@ -59,12 +38,12 @@ public function send(Event $event)
}

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $this->url);
curl_setopt($curl, CURLOPT_URL, $this->getUrl());
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($event, JSON_UNESCAPED_UNICODE));
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($curl, CURLOPT_TIMEOUT, $this->getTimeout());
$response = curl_exec($curl);
curl_close($curl);

Expand Down
36 changes: 24 additions & 12 deletions src/Transport/GuzzleTransport.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,46 @@
namespace Hawk\Transport;

use Hawk\Event;
use Hawk\Options;
use Hawk\Transport;

/**
* Class GuzzleTransport
*
* @package Hawk\Transport
*/
class GuzzleTransport implements TransportInterface
class GuzzleTransport extends Transport
{
private $url;

public function __construct(string $url)
{
$this->url = $url;
}
/**
* @var \GuzzleHttp\Client
*/
private $client;

/**
* @inheritDoc
* GuzzleTransport constructor.
*
* @param Options $options
*/
public function getUrl(): string
public function __construct(Options $options)
{
return $this->url;
parent::__construct($options);

$this->client = new \GuzzleHttp\Client();
}

/**
* @inheritDoc
*/
public function send(Event $event): void
protected function _send(Event $event): string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_send method violates the PSR-12 recommendations.
It is not recommended to add underscores to method names.

{
// TODO: Implement send() method.
$response = $this->client->post($this->getUrl(), [
'headers' => [
'Content-Type' => 'application/json',
],
'body' => json_encode($event, JSON_UNESCAPED_UNICODE),
'timeout' => $this->getTimeout(),
]);

return $response->getBody()->getContents();
}
}
31 changes: 0 additions & 31 deletions src/Transport/TransportInterface.php

This file was deleted.

Loading
Loading