initial commit

This commit is contained in:
2020-12-30 13:12:18 +07:00
commit f7cafcb397
10 changed files with 748 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace App\Command;
use App\Operation\JokeOperation;
class JokeCommand extends \Ahc\Cli\Input\Command
{
private JokeOperation $jokeOperation;
public function __construct(JokeOperation $jokeOperation)
{
parent::__construct('joke', 'Get some joke');
$this->jokeOperation = $jokeOperation;
}
public function execute(): void
{
$io = $this->app()->io();
$joke = $this->jokeOperation->getRandomJoke();
$io->green($joke, true);
}
}

View File

@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
namespace App\Operation;
use App\Service\CachedJokes;
use App\Service\JokeInterface;
use Psr\SimpleCache\CacheInterface;
class JokeOperation
{
protected JokeInterface $jokeService;
protected CacheInterface $cache;
public function __construct(JokeInterface $jokeService, CacheInterface $cache)
{
$this->jokeService = $jokeService;
$this->cache = $cache;
}
public function getRandomJoke(): string
{
$reflection = new \ReflectionClass($this->jokeService);
$cachedJokesAttr = $reflection->getMethod('getRandomJoke')->getAttributes(CachedJokes::class);
if (count($cachedJokesAttr) > 0) {
/** @var CachedJokes $cache */
$cache = $cachedJokesAttr[0]->newInstance();
$cacheKey = $cache->getCacheKey(JokeInterface::CATEGORY_ANY);
if ($this->cache->has($cacheKey)) {
return $this->cache->get($cacheKey);
}
}
$randomJoke = $this->jokeService->getRandomJoke();
$randomJokeStr = $randomJoke['joke'];
if (isset($cacheKey)) {
$this->cache->set($cacheKey, $randomJokeStr);
}
return $randomJokeStr;
}
}

View File

@@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace App\Service;
#[\Attribute]
class CachedJokes
{
public function getCacheKey(string $jokeType): string
{
return "jokes-{$jokeType}";
}
}

View File

@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace App\Service;
interface JokeInterface
{
public const CATEGORY_ANY = 'Any';
public const CATEGORY_MISC = 'Miscellaneous';
public const CATEGORY_PROGRAMMING = 'Programming';
public const CATEGORY_DARK = 'Dark';
public const CATEGORY_PUN = 'Pun';
public const CATEGORY_SPOOKY = 'Spooky';
public const CATEGORY_CHRISTMAS = 'Christmas';
public function getRandomJoke(): array;
}

View File

@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace App\Service;
use Psr\Http\Message\ResponseInterface;
/**
* Class JokeService
* @link https://sv443.net/jokeapi/v2
*/
class JokeService implements JokeInterface
{
protected \GuzzleHttp\Client $guzzleClient;
public function __construct(\GuzzleHttp\Client $guzzleClient)
{
$this->guzzleClient = $guzzleClient;
}
#[CachedJokes]
public function getRandomJoke(): array
{
$response = $this->sendRequest(static::CATEGORY_ANY);
$responseContent = (string) $response->getBody();
return \json_decode($responseContent, true);
}
protected function sendRequest(string ...$categories): ResponseInterface
{
$categoriesStr = implode(',', $categories);
return $this->guzzleClient->get("/joke/{$categoriesStr}", [
\GuzzleHttp\RequestOptions::QUERY => [
'format' => 'json',
'amount' => 1,
'type' => 'single',
],
]);
}
}