Skip to content

Commit

Permalink
wip 2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
guanguans committed Jan 18, 2024
1 parent 79c3a0d commit bcd3699
Show file tree
Hide file tree
Showing 16 changed files with 607 additions and 2 deletions.
8 changes: 6 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,12 @@
}
],
"require": {
"php": ">=7.2.5",
"php": ">=7.4",
"ext-json": "*",
"guzzlehttp/guzzle": "^7.8",
"league/config": "^1.2",
"overtrue/http": "^1.2",
"php-http/discovery": "^1.19",
"psr/log": "^1.1 || ^2.0 || ^3.0",
"symfony/options-resolver": "^5.4 || ^6.0 || ^7.0"
},
Expand Down Expand Up @@ -123,7 +126,8 @@
"allow-plugins": {
"bamarni/composer-bin-plugin": true,
"ergebnis/composer-normalize": true,
"phpstan/extension-installer": true
"phpstan/extension-installer": true,
"php-http/discovery": true
},
"apcu-autoloader": true,
"classmap-authoritative": false,
Expand Down
154 changes: 154 additions & 0 deletions src/Foundation/Concerns/HasOptions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<?php

declare(strict_types=1);

/**
* This file is part of the guanguans/notify.
*
* (c) guanguans <[email protected]>
*
* This source file is subject to the MIT license that is bundled.
*/

namespace Guanguans\Notify\Foundation\Concerns;

use Symfony\Component\OptionsResolver\OptionsResolver;

/**
* @property array $defined;
* @property array $required;
* @property array $deprecated;
* @property array $defaults;
* @property bool $prototype;
* @property array $allowedValues;
* @property array $allowedTypes;
* @property array $normalizers;
* @property array $infos;
*/
trait HasOptions
{
protected array $options = [];

protected function configureOptionsResolver(OptionsResolver $optionsResolver): OptionsResolver
{
// configure options resolver...
return $optionsResolver;
}

private function configureAndResolveOptions(array $options, callable $configurator): array
{
$resolver = new OptionsResolver();

$configurator($resolver);

return $resolver->resolve($options);
}

private function preConfigureOptionsResolver(OptionsResolver $optionsResolver): OptionsResolver
{
property_exists($this, 'defined') and $optionsResolver->setDefined($this->defined);
property_exists($this, 'required') and $optionsResolver->setRequired($this->required);
property_exists($this, 'defaults') and $optionsResolver->setDefaults($this->defaults);
property_exists($this, 'prototype') and $optionsResolver->setPrototype($this->prototype);

if (property_exists($this, 'deprecated')) {
foreach ($this->deprecated as $option => $deprecated) {
array_unshift($deprecated, $option);
$optionsResolver->setDeprecated(...$deprecated);
}
}

if (property_exists($this, 'allowedValues')) {
foreach ($this->allowedValues as $option => $allowedValue) {
$optionsResolver->setAllowedValues($option, $allowedValue);
}
}

if (property_exists($this, 'allowedTypes')) {
foreach ($this->allowedTypes as $option => $allowedType) {
$optionsResolver->setAllowedTypes($option, $allowedType);
}
}

if (property_exists($this, 'normalizers')) {
foreach ($this->normalizers as $option => $normalizer) {
$optionsResolver->setNormalizer($option, $normalizer);
}
}

if (property_exists($this, 'infos')) {
foreach ($this->infos as $option => $info) {
$optionsResolver->setInfo($option, $info);
}
}

return $optionsResolver;
}

public function setOptions(array $options): self
{
$this->options = array_replace_recursive(
$this->options,
$this->configureAndResolveOptions($options, function (OptionsResolver $optionsResolver): void {
$this->configureOptionsResolver($this->preConfigureOptionsResolver($optionsResolver));
})
);

return $this;
}

public function setOption(string $option, $value): self
{
return $this->setOptions([$option => $value]);
}

public function getOption(string $option, $default = null)
{
return $this->options[$option] ?? $default;
}

public function getOptions(): array
{
return $this->options;
}

public function __get($option)
{
return $this->offsetGet($option);
}

public function __set($option, $value)
{
$this->offsetSet($option, $value);
}

public function __isset($option)
{
return $this->offsetExists($option);
}

public function __unset($option)
{
$this->offsetUnset($option);
}

public function offsetExists($offset)
{
return isset($this->options[$offset]);
}

public function offsetGet($offset)
{
return $this->getOption($offset);
}

public function offsetSet($offset, $value)
{
$this->setOption($offset, $value);
}

public function offsetUnset($offset)
{
unset($this->options[$offset]);
}
}
23 changes: 23 additions & 0 deletions src/Foundation/Concerns/Tappable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

/**
* This file is part of the guanguans/notify.
*
* (c) guanguans <[email protected]>
*
* This source file is subject to the MIT license that is bundled.
*/

namespace Guanguans\Notify\Foundation\Concerns;

trait Tappable
{
public function tap(callable $callback): self
{
$callback($this);

return $this;
}
}
27 changes: 27 additions & 0 deletions src/Foundation/Contracts/Arrayable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

/**
* This file is part of the guanguans/notify.
*
* (c) guanguans <[email protected]>
*
* This source file is subject to the MIT license that is bundled.
*/

namespace Guanguans\Notify\Foundation\Contracts;

/**
* @template TKey of array-key
* @template TValue
*/
interface Arrayable
{
/**
* Get the instance as an array.
*
* @return array<TKey, TValue>
*/
public function toArray(): array;
}
20 changes: 20 additions & 0 deletions src/Foundation/Contracts/Credential.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

/**
* This file is part of the guanguans/notify.
*
* (c) guanguans <[email protected]>
*
* This source file is subject to the MIT license that is bundled.
*/

namespace Guanguans\Notify\Foundation\Contracts;

use Psr\Http\Message\RequestInterface;

interface Credential
{
public function applyToRequest(RequestInterface $request): RequestInterface;
}
20 changes: 20 additions & 0 deletions src/Foundation/Contracts/HttpMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

/**
* This file is part of the guanguans/notify.
*
* (c) guanguans <[email protected]>
*
* This source file is subject to the MIT license that is bundled.
*/

namespace Guanguans\Notify\Foundation\Contracts;

use Psr\Http\Message\RequestInterface;

interface HttpMessage extends Message
{
public function toRequest(): RequestInterface;
}
21 changes: 21 additions & 0 deletions src/Foundation/Contracts/Jsonable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

/**
* This file is part of the guanguans/notify.
*
* (c) guanguans <[email protected]>
*
* This source file is subject to the MIT license that is bundled.
*/

namespace Guanguans\Notify\Foundation\Contracts;

interface Jsonable
{
/**
* @return string|false
*/
public function toJson(int $options = 0);
}
17 changes: 17 additions & 0 deletions src/Foundation/Contracts/Message.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

/**
* This file is part of the guanguans/notify.
*
* (c) guanguans <[email protected]>
*
* This source file is subject to the MIT license that is bundled.
*/

namespace Guanguans\Notify\Foundation\Contracts;

interface Message extends \ArrayAccess, Arrayable, \Stringable, Jsonable
{
}
45 changes: 45 additions & 0 deletions src/Foundation/HttpClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

/**
* This file is part of the guanguans/notify.
*
* (c) guanguans <[email protected]>
*
* This source file is subject to the MIT license that is bundled.
*/

namespace Guanguans\Notify\Foundation;

use Guanguans\Notify\Foundation\Concerns\Tappable;
use Guanguans\Notify\Foundation\Contracts\Credential;
use Guanguans\Notify\Foundation\Contracts\Message;
use Http\Discovery\Psr18ClientDiscovery;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\ResponseInterface;

class HttpClient
{
use Tappable;

private Credential $credential;
private ClientInterface $httpClient;

public function __construct(Credential $credential = null, ClientInterface $httpClient = null)
{
$this->credential = $credential ?? new NullCredential();
$this->httpClient = $httpClient ?? Psr18ClientDiscovery::find();
}

/**
* @throws ClientExceptionInterface
*/
public function sendMessage(Message $message): ResponseInterface
{
return $this->httpClient->sendRequest(
$this->credential->applyToRequest($message->toRequest())
);
}
}
Loading

0 comments on commit bcd3699

Please sign in to comment.