Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
timacdonald committed Oct 23, 2020
1 parent 1bf8105 commit b352881
Show file tree
Hide file tree
Showing 23 changed files with 514 additions and 244 deletions.
5 changes: 4 additions & 1 deletion .php_cs.dist
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
<?php

// specify the paths to fix, as normal...

$finder = PhpCsFixer\Finder::create()
->in(__DIR__.'/src')
->in(__DIR__.'/tests');

return TiMacDonald\styles($finder);
// then call and return the following global function...

return TiMacDonald\styles($finder);
2 changes: 1 addition & 1 deletion psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<issueHandlers>
<PropertyNotSetInConstructor>
<errorLevel type="suppress">
<file name="tests/MultiformatResponseTest.php" />
<file name="tests/SuperResponseTest.php" />
</errorLevel>
</PropertyNotSetInConstructor>
</issueHandlers>
Expand Down
5 changes: 5 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,8 @@ tl;dr; DHH and Adam Wathan are awesome.

You are free to use this package, but I ask that you reach out to someone (not me) who has previously, or is currently, maintaining or contributing to an open source library you are using in your project and thank them for their work. Consider your entire tech stack: packages, frameworks, languages, databases, operating systems, frontend, backend, etc.

-----------

## Fallback response

When no suitable response is detected by the checkers
20 changes: 20 additions & 0 deletions src/Checkers/Concerns/DetectValidMethodStrings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace TiMacDonald\Multiformat\Checkers\Concerns;

use function preg_match;

trait DetectValidMethodStrings
{
private static function doesntContainAnyValidMethodCharacters(string $characters): bool
{
return ! self::containsSomeValidMethodCharacters($characters);
}

private static function containsSomeValidMethodCharacters(string $characters): bool
{
return preg_match('/[a-zA-Z0-9_\\x80-\\xff]/', $characters) === 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
namespace TiMacDonald\Multiformat\Checkers;

use function assert;

use Illuminate\Http\Request;
use function is_string;

use TiMacDonald\Multiformat\Contracts\MimeToType;
use TiMacDonald\Multiformat\ResponseTypes;
use TiMacDonald\Multiformat\ResponseType;

class MimeContentType
class HeaderContentType
{
use Concerns\DetectValidMethodStrings;

/**
* @var \TiMacDonald\Multiformat\Contracts\MimeToType
*/
Expand All @@ -24,15 +24,19 @@ public function __construct(MimeToType $mimeToType)
$this->mimeToType = $mimeToType;
}

public function __invoke(Request $request): ?ResponseTypes
public function __invoke(Request $request): ?ResponseType
{
foreach ($request->getAcceptableContentTypes() as $contentType) {
assert(is_string($contentType));

$type = ($this->mimeToType)($contentType);

if ($type !== null) {
return new ResponseTypes([$type]);
if ($type === null) {
continue;
}

if (self::containsSomeValidMethodCharacters($type)) {
return new ResponseType($type);
}
}

Expand Down
13 changes: 6 additions & 7 deletions src/Checkers/HeaderVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,25 @@
namespace TiMacDonald\Multiformat\Checkers;

use Illuminate\Http\Request;
use function is_numeric;

use function is_string;
use function str_replace;
use TiMacDonald\Multiformat\ResponseTypes;
use TiMacDonald\Multiformat\ResponseType;

class HeaderVersion
{
public function __invoke(Request $request): ?ResponseTypes
use Concerns\DetectValidMethodStrings;

public function __invoke(Request $request): ?ResponseType
{
$version = $request->header('Api-Version');

if (! is_string($version)) {
return null;
}

if (! is_numeric(str_replace('.', '', $version))) {
if (self::doesntContainAnyValidMethodCharacters($version)) {
return null;
}

return new ResponseTypes(['version_'.str_replace('.', '_', $version).'_']);
return new ResponseType("Version{$version}");
}
}
13 changes: 6 additions & 7 deletions src/Checkers/QueryVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,25 @@
namespace TiMacDonald\Multiformat\Checkers;

use Illuminate\Http\Request;
use function is_numeric;

use function is_string;
use function str_replace;
use TiMacDonald\Multiformat\ResponseTypes;
use TiMacDonald\Multiformat\ResponseType;

class QueryVersion
{
public function __invoke(Request $request): ?ResponseTypes
use Concerns\DetectValidMethodStrings;

public function __invoke(Request $request): ?ResponseType
{
$version = $request->query('v');

if (! is_string($version)) {
return null;
}

if (! is_numeric(str_replace('.', '', $version))) {
if (self::doesntContainAnyValidMethodCharacters($version)) {
return null;
}

return new ResponseTypes(['version_'.str_replace('.', '_', $version).'_']);
return new ResponseType("Version{$version}");
}
}
14 changes: 9 additions & 5 deletions src/Checkers/UrlContentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
namespace TiMacDonald\Multiformat\Checkers;

use function assert;

use function explode;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use function is_string;

use TiMacDonald\Multiformat\ResponseTypes;
use TiMacDonald\Multiformat\ResponseType;

class UrlContentType
{
public function __invoke(Request $request): ?ResponseTypes
use Concerns\DetectValidMethodStrings;

public function __invoke(Request $request): ?ResponseType
{
$filename = Arr::last(explode('/', $request->path()));

Expand All @@ -30,6 +30,10 @@ public function __invoke(Request $request): ?ResponseTypes

assert(is_string($type));

return new ResponseTypes([$type]);
if (self::doesntContainAnyValidMethodCharacters($type)) {
return null;
}

return new ResponseType($type);
}
}
15 changes: 9 additions & 6 deletions src/Checkers/UrlVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,29 @@
namespace TiMacDonald\Multiformat\Checkers;

use Illuminate\Http\Request;
use function is_numeric;
use Illuminate\Support\Str;

use function is_string;
use function str_replace;
use TiMacDonald\Multiformat\ResponseTypes;
use TiMacDonald\Multiformat\ResponseType;

class UrlVersion
{
public function __invoke(Request $request): ?ResponseTypes
use Concerns\DetectValidMethodStrings;

public function __invoke(Request $request): ?ResponseType
{
$version = $request->route('version');

if (! is_string($version)) {
return null;
}

if (! is_numeric(str_replace('.', '', $version))) {
if (self::doesntContainAnyValidMethodCharacters($version)) {
return null;
}

return new ResponseTypes(['version_'.str_replace('.', '_', $version).'_']);
$version = Str::after($version, 'v');

return new ResponseType("Version{$version}");
}
}
10 changes: 0 additions & 10 deletions src/Contracts/ApiFallback.php

This file was deleted.

12 changes: 12 additions & 0 deletions src/Contracts/FallbackResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace TiMacDonald\Multiformat\Contracts;

use Illuminate\Http\Request;

interface FallbackResponse
{
public function __invoke(Request $request, object $response): callable;
}
4 changes: 2 additions & 2 deletions src/Contracts/TypeCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace TiMacDonald\Multiformat\Contracts;

use Illuminate\Http\Request;
use TiMacDonald\Multiformat\ResponseTypes;
use Illuminate\Support\Collection;

interface TypeCheck
{
public function __invoke(Request $request, array $checkers): ResponseTypes;
public function __invoke(Request $request, array $checkers): Collection;
}
13 changes: 0 additions & 13 deletions src/Contracts/TypeToCallback.php

This file was deleted.

12 changes: 12 additions & 0 deletions src/Contracts/TypesToCallback.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace TiMacDonald\Multiformat\Contracts;

use Illuminate\Support\Collection;

interface TypesToCallback
{
public function __invoke(Collection $options): callable;
}
24 changes: 24 additions & 0 deletions src/Functions/FallbackResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace TiMacDonald\Multiformat\Functions;

use Illuminate\Http\Request;
use Illuminate\Http\Response;
use function method_exists;
use TiMacDonald\Multiformat\Contracts\FallbackResponse as FallbackResponseContract;

class FallbackResponse implements FallbackResponseContract
{
public function __invoke(Request $request, object $response): callable
{
return static function () use ($request, $response) {
if (method_exists($response, 'unsupportedResponse')) {
return $response->unsupportedResponse($request);
}

return new Response(null, 406);
};
}
}
26 changes: 26 additions & 0 deletions src/Functions/MimeToType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace TiMacDonald\Multiformat\Functions;

use Symfony\Component\Mime\MimeTypes;
use TiMacDonald\Multiformat\Contracts\MimeToType as MimeToTypeContract;

class MimeToType implements MimeToTypeContract
{
/**
* @var MimeTypes
*/
private $mimeTypes;

public function __construct(MimeTypes $mimeTypes)
{
$this->mimeTypes = $mimeTypes;
}

public function __invoke(string $mime): ?string
{
return $this->mimeTypes->getExtensions($mime)[0] ?? null;
}
}
41 changes: 41 additions & 0 deletions src/Functions/TypeCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace TiMacDonald\Multiformat\Functions;

use function app;
use function assert;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use function is_callable;
use TiMacDonald\Multiformat\Contracts\TypeCheck as TypeCheckContract;
use TiMacDonald\Multiformat\ResponseType;

class TypeCheck implements TypeCheckContract
{
public function __invoke(Request $request, array $checkers): Collection
{
return Collection::make($checkers)
->map(
/** @param callable|string $checker */
static function ($checker): callable {
if (is_callable($checker)) {
return $checker;
}

$checker = app()->make($checker);

assert(is_callable($checker));

return $checker;
}
)->map(static function (callable $checker) use ($request): ResponseType {
$responseTypes = $checker($request);

assert($responseTypes instanceof ResponseType);

return $responseTypes;
});
}
}
Loading

0 comments on commit b352881

Please sign in to comment.