ContentfulSyncController   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 12
lcom 1
cbo 2
dl 0
loc 131
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
B handleIncomingWebhook() 0 43 7
A parseRequestContent() 0 7 1
A getEntryContentType() 0 4 1
A getResourceId() 0 4 1
A getContentfulTopic() 0 4 1
1
<?php
2
3
namespace Digia\Lumen\ContentfulSync\Http\Controllers;
4
5
use Contentful\Core\Resource\ResourceArray;
6
use Contentful\Core\Resource\ResourceInterface;
7
use Contentful\Delivery\Client;
8
use Contentful\Delivery\Resource\Entry;
9
use Digia\Lumen\ContentfulSync\Contracts\ContentfulSyncServiceContract;
10
use Digia\Lumen\ContentfulSync\Exceptions\ContentfulSyncException;
11
use Digia\Lumen\ContentfulSync\Http\Middleware\NewRelicMiddleware;
12
use Illuminate\Http\Request;
13
use Illuminate\Http\Response;
14
use Laravel\Lumen\Routing\Controller;
15
use Nord\Lumen\Contentful\ContentfulServiceContract;
16
17
/**
18
 * Handles incoming webhooks from Contentful
19
 *
20
 * @package Digia\Lumen\ContentfulSync\Http\Controllers
21
 */
22
class ContentfulSyncController extends Controller
23
{
24
25
    protected const TOPIC_CONTENT_MANAGEMENT_ASSET_PUBLISH   = 'ContentManagement.Asset.publish';
26
    protected const TOPIC_CONTENT_MANAGEMENT_ASSET_UNPUBLISH = 'ContentManagement.Asset.unpublish';
27
    protected const TOPIC_CONTENT_MANAGEMENT_ASSET_DELETE    = 'ContentManagement.Asset.delete';
28
    protected const TOPIC_CONTENT_MANAGEMENT_ENTRY_PUBLISH   = 'ContentManagement.Entry.publish';
29
    protected const TOPIC_CONTENT_MANAGEMENT_ENTRY_UNPUBLISH = 'ContentManagement.Entry.unpublish';
30
    protected const TOPIC_CONTENT_MANAGEMENT_ENTRY_DELETE    = 'ContentManagement.Entry.delete';
31
32
    /**
33
     * @var ContentfulServiceContract
34
     */
35
    private $contentfulService;
36
37
    /**
38
     * @var ContentfulSyncServiceContract
39
     */
40
    private $contentfulSyncService;
41
42
    /**
43
     * ContentfulSyncController constructor.
44
     *
45
     * @param ContentfulServiceContract     $contentfulService
46
     * @param ContentfulSyncServiceContract $contentfulSyncService
47
     */
48
    public function __construct(
49
        ContentfulServiceContract $contentfulService,
50
        ContentfulSyncServiceContract $contentfulSyncService
51
    ) {
52
        $this->contentfulService     = $contentfulService;
53
        $this->contentfulSyncService = $contentfulSyncService;
54
    }
55
56
    /**
57
     * @param Request $request
58
     *
59
     * @return Response
60
     *
61
     * @throws \InvalidArgumentException if the space or environment ID is invalid
62
     * @throws ContentfulSyncException if the webhook cannot be handled
63
     */
64
    public function handleIncomingWebhook(Request $request): Response
65
    {
66
        $requestContent = (string)$request->getContent();
67
68
        // Instrument the request so the middleware can do its job
69
        $contentfulTopic = $this->getContentfulTopic($request);
70
        $request->attributes->set(NewRelicMiddleware::ATTRIBUTE_TOPIC, $contentfulTopic);
71
72
        // Handle different topics differently
73
        switch ($contentfulTopic) {
74
            case self::TOPIC_CONTENT_MANAGEMENT_ASSET_PUBLISH:
75
                $this->contentfulSyncService->publishAsset($requestContent);
76
                break;
77
            case self::TOPIC_CONTENT_MANAGEMENT_ASSET_UNPUBLISH:
78
            case self::TOPIC_CONTENT_MANAGEMENT_ASSET_DELETE:
79
                $resource = $this->parseRequestContent($requestContent);
80
                $this->contentfulSyncService->deleteAsset($this->getResourceId($resource));
81
                break;
82
            case self::TOPIC_CONTENT_MANAGEMENT_ENTRY_PUBLISH:
83
                /** @var Entry $resource */
84
                $resource    = $this->parseRequestContent($requestContent);
85
                $contentType = $this->getEntryContentType($resource);
86
87
                $request->attributes->set(NewRelicMiddleware::ATTRIBUTE_CONTENT_TYPE, $contentType);
88
89
                $this->contentfulSyncService->publishEntry($contentType, $requestContent);
90
                break;
91
            case self::TOPIC_CONTENT_MANAGEMENT_ENTRY_UNPUBLISH:
92
            case self::TOPIC_CONTENT_MANAGEMENT_ENTRY_DELETE:
93
                /** @var Entry $resource */
94
                $resource    = $this->parseRequestContent($requestContent);
95
                $contentType = $this->getEntryContentType($resource);
96
97
                $request->attributes->set(NewRelicMiddleware::ATTRIBUTE_CONTENT_TYPE, $contentType);
98
99
                $this->contentfulSyncService->deleteEntry($contentType, $this->getResourceId($resource));
100
                break;
101
            default:
102
                throw new ContentfulSyncException(sprintf('Unknown topic "%s"', $contentfulTopic));
103
        }
104
105
        return new Response();
106
    }
107
108
    /**
109
     * Parse the specified request content into a Contentful SDK resource
110
     *
111
     * @param string $resourceContent
112
     *
113
     * @return ResourceInterface|ResourceArray
114
     */
115
    private function parseRequestContent(string $resourceContent)
116
    {
117
        /** @var Client $client */
118
        $client = $this->contentfulService->getClient();
119
120
        return $client->parseJson($resourceContent);
121
    }
122
123
    /**
124
     * @param Entry $entry
125
     *
126
     * @return string
127
     */
128
    private function getEntryContentType(Entry $entry): string
129
    {
130
        return $entry->getSystemProperties()->getContentType()->getId();
131
    }
132
133
    /**
134
     * @param ResourceInterface $resource
135
     *
136
     * @return string
137
     */
138
    private function getResourceId(ResourceInterface $resource): string
139
    {
140
        return $resource->getSystemProperties()->getId();
141
    }
142
143
    /**
144
     * @param Request $request
145
     *
146
     * @return string
147
     */
148
    private function getContentfulTopic(Request $request): string
149
    {
150
        return $request->header('X-Contentful-Topic', '');
151
    }
152
}
153