Completed
Push — master ( 8687c2...995275 )
by Steve
02:00
created

DiceRequestHandler::__invoke()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace MeadSteve\DiceApi\RequestHandler;
4
5
use MeadSteve\DiceApi\Counters\DiceCounter;
6
use MeadSteve\DiceApi\Dice;
7
use MeadSteve\DiceApi\UrlDiceGenerator;
8
use MeadSteve\DiceApi\Dice\UncreatableDiceException;
9
use MeadSteve\DiceApi\DiceDecorators\TotallyLegit;
10
use MeadSteve\DiceApi\Renderer\RendererCollection;
11
use MeadSteve\DiceApi\Renderer\UnknownRendererException;
12
use MeadSteve\DiceApi\Renderer\UnrenderableDiceException;
13
use Slim\Http\Request;
14
use Slim\Http\Response;
15
16
class DiceRequestHandler
17
{
18
    /**
19
     * @var UrlDiceGenerator
20
     */
21
    private $diceGenerator;
22
23
    /**
24
     * @var DiceCounter
25
     */
26
    private $diceCounter;
27
28
    /**
29
     * @var RendererCollection
30
     */
31
    private $rendererCollection;
32
33
    public function __construct(
34
        UrlDiceGenerator $diceGenerator,
35
        RendererCollection $rendererCollection,
36
        DiceCounter $diceCounter
37
    ) {
38
        $this->diceGenerator = $diceGenerator;
39
        $this->rendererCollection = $rendererCollection;
40
        $this->diceCounter = $diceCounter;
41
    }
42
43
    public function __invoke(Request $request, Response $response, $args)
44
    {
45
        return $this->getDice($request, $response, $args);
46
    }
47
48
    public function getDice(Request $request, Response $response, $args): Response
49
    {
50
        $diceResponse = $response
51
            ->withHeader("cache-control", "no-cache")
52
            ->withHeader('Access-Control-Allow-Origin', '*');
53
        try {
54
            $diceCollection = $this->diceCollectionFromRequest($request, $args);
55
            $this->diceCounter->count($diceCollection);
56
            return $this->writeAppropriateFormatResponse($request, $diceResponse, $diceCollection);
57
        } catch (UncreatableDiceException $creationError) {
58
            return $diceResponse->withStatus(400)
59
                ->write("Unable to roll diceCollection: " . $creationError->getMessage());
60
        } catch (UnrenderableDiceException $renderError) {
61
            return $diceResponse->withStatus(400)
62
                ->write("Unable to render request: " . $renderError->getMessage());
63
        }
64
    }
65
66
    /**
67
     * Returns key value pairs mapping a url prefix to a handled content type
68
     * so ["json" => "application/json", "etc" => "..."]
69
     * @return string[]
70
     */
71
    public function contentTypesForPaths() : array
72
    {
73
        return $this->rendererCollection->contentTypesForPaths();
74
    }
75
76
    /**
77
     * @param Request $request
78
     * @param Response $response
79
     * @param Dice[] $diceCollection
80
     * @return Response
81
     */
82
    private function writeAppropriateFormatResponse(Request $request, Response $response, array $diceCollection)
83
    {
84
        $acceptHeader = $request->getHeader('accept');
85
        $requestedContentType = $acceptHeader[0];
86
        try {
87
            $renderer = $this->rendererCollection->newForAcceptType($requestedContentType);
88
            return $response->write($renderer->renderDice($diceCollection))
89
                ->withHeader("Content-Type", $renderer->contentType());
90
        } catch (UnknownRendererException $error) {
91
            return $response->withStatus(406)
92
                ->write("Not sure how to respond with: " . $requestedContentType);
93
        }
94
    }
95
96
    /**
97
     * @param Dice[] $diceCollection
98
     * @param Request $request
99
     * @return Dice[]
100
     */
101
    private function makeDiceTotallyLegit(array $diceCollection, Request $request)
102
    {
103
        $rolledValue = $request->getHeader('totally-legit')[0];
104
        return array_map(
105
            function (Dice $dice) use ($rolledValue): Dice {
106
                return new TotallyLegit($dice, (int) $rolledValue);
107
            },
108
            $diceCollection
109
        );
110
    }
111
112
    /**
113
     * @param Request $request
114
     * @param mixed[] $args
115
     * @return Dice[]
116
     */
117
    private function diceCollectionFromRequest(Request $request, array $args)
118
    {
119
        $diceCollection = $this->diceGenerator->diceFromUrlString($args['dice']);
120
        if ($request->hasHeader('totally-legit')) {
121
            return $this->makeDiceTotallyLegit($diceCollection, $request);
122
        }
123
        return $diceCollection;
124
    }
125
}
126