Completed
Pull Request — master (#18)
by Steve
05:29
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
    private $diceGenerator;
20
    private $diceCounter;
21
    private $rendererCollection;
22
23
    public function __construct(
24
        UrlDiceGenerator $diceGenerator,
25
        RendererCollection $rendererCollection,
26
        DiceCounter $diceCounter
27
    ) {
28
        $this->diceGenerator = $diceGenerator;
29
        $this->rendererCollection = $rendererCollection;
30
        $this->diceCounter = $diceCounter;
31
    }
32
33
    public function __invoke(Request $request, Response $response, $args)
34
    {
35
        return $this->getDice($request, $response, $args);
36
    }
37
38
    public function getDice(Request $request, Response $response, $args)
39
    {
40
        $diceResponse = $response
41
            ->withHeader("cache-control", "no-cache")
42
            ->withHeader('Access-Control-Allow-Origin', '*');
43
        try {
44
            $diceCollection = $this->diceCollectionFromRequest($request, $args);
45
            $this->diceCounter->count($diceCollection);
46
            return $this->writeAppropriateFormatResponse($request, $diceResponse, $diceCollection);
47
        } catch (UncreatableDiceException $creationError) {
48
            return $diceResponse->withStatus(400)
49
                ->write("Unable to roll diceCollection: " . $creationError->getMessage());
50
        } catch (UnrenderableDiceException $renderError) {
51
            return $diceResponse->withStatus(400)
52
                ->write("Unable to render request: " . $renderError->getMessage());
53
        }
54
    }
55
56
    /**
57
     * Returns key value pairs mapping a url prefix to a handled content type
58
     * so ["json" => "application/json", "etc" => "..."]
59
     * @return string[]
60
     */
61
    public function contentTypesForPaths() : array
62
    {
63
        return $this->rendererCollection->contentTypesForPaths();
64
    }
65
66
    /**
67
     * @param Request $request
68
     * @param Response $response
69
     * @param Dice[] $diceCollection
70
     * @return Response
71
     */
72
    private function writeAppropriateFormatResponse(Request $request, Response $response, array $diceCollection)
73
    {
74
        $acceptHeader = $request->getHeader('accept');
75
        $requestedContentType = $acceptHeader[0];
76
        try {
77
            $renderer = $this->rendererCollection->newForAcceptType($requestedContentType);
78
            return $response->write($renderer->renderDice($diceCollection))
79
                ->withHeader("Content-Type", $renderer->contentType());
80
        } catch (UnknownRendererException $error) {
81
            return $response->withStatus(406)
82
                ->write("Not sure how to respond with: " . $requestedContentType);
83
        }
84
    }
85
86
    /**
87
     * @param Dice[] $diceCollection
88
     * @param Request $request
89
     * @return Dice[]
90
     */
91
    private function makeDiceTotallyLegit(array $diceCollection, Request $request)
92
    {
93
        $rolledValue = $request->getHeader('totally-legit')[0];
94
        return array_map(
95
            function (Dice $dice) use ($rolledValue) {
96
                return new TotallyLegit($dice, (int) $rolledValue);
97
            },
98
            $diceCollection
99
        );
100
    }
101
102
    /**
103
     * @param Request $request
104
     * @param mixed[] $args
105
     * @return Dice[]
106
     */
107
    private function diceCollectionFromRequest(Request $request, array $args)
108
    {
109
        $diceCollection = $this->diceGenerator->diceFromUrlString($args['dice']);
110
        if ($request->hasHeader('totally-legit')) {
111
            return $this->makeDiceTotallyLegit($diceCollection, $request);
112
        }
113
        return $diceCollection;
114
    }
115
}
116