Completed
Push — master ( 3460d4...501fc3 )
by Paweł
76:02 queued 29:07
created

ContentPushController   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12

Test Coverage

Coverage 90%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 12
dl 0
loc 136
ccs 18
cts 20
cp 0.9
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getAssetsAction() 0 20 2
A pushContentAction() 0 19 2
B pushAssetsAction() 0 28 4
A handlePackage() 0 14 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Superdesk Web Publisher Content Bundle.
7
 *
8
 * Copyright 2016 Sourcefabric z.ú. and contributors.
9
 *
10
 * For the full copyright and license information, please see the
11
 * AUTHORS and LICENSE files distributed with this source code.
12
 *
13
 * @copyright 2016 Sourcefabric z.ú
14
 * @license http://www.superdesk.org/license
15
 */
16
17
namespace SWP\Bundle\ContentBundle\Controller;
18
19
use Hoa\Mime\Mime;
20
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
21
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
22
use SWP\Bundle\ContentBundle\ArticleEvents;
23
use SWP\Bundle\ContentBundle\Event\ArticleEvent;
24
use SWP\Bundle\ContentBundle\Form\Type\MediaFileType;
25
use SWP\Bundle\ContentBundle\Model\ArticleMedia;
26
use SWP\Component\Bridge\Model\PackageInterface;
27
use SWP\Component\Common\Criteria\Criteria;
28
use SWP\Component\Common\Response\ResponseContext;
29
use SWP\Component\Common\Response\SingleResourceResponse;
30
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
31
use Symfony\Component\HttpFoundation\Request;
32
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
33
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
34
35
class ContentPushController extends Controller
36
{
37
    /**
38
     * Receives HTTP Push Request's payload which is then processed by the pipeline.
39
     *
40
     * @ApiDoc(
41
     *     resource=true,
42
     *     description="Adds a new content from HTTP Push",
43
     *     statusCodes={
44
     *         201="Returned on successful post."
45
     *     }
46
     * )
47
     * @Route("/api/{version}/content/push", options={"expose"=true}, defaults={"version"="v1"}, name="swp_api_content_push")
48
     * @Method("POST")
49
     */
50 6
    public function pushContentAction(Request $request)
51
    {
52 6
        $package = $this->handlePackage($request);
53
54 6
        $article = $this->get('swp_content.transformer.package_to_article')->transform($package);
55 6
        $articleRepository = $this->get('swp.repository.article');
56
57
        // In case of resending article - remove previous one
58 6
        $existingArticle = $articleRepository->findOneBy(['slug' => $article->getSlug()]);
59 6
        if (null !== $existingArticle) {
60
            $articleRepository->remove($existingArticle);
61
        }
62
63 6
        $this->get('event_dispatcher')->dispatch(ArticleEvents::PRE_CREATE, new ArticleEvent($article, $package));
64 6
        $articleRepository->add($article);
65 6
        $this->get('event_dispatcher')->dispatch(ArticleEvents::POST_CREATE, new ArticleEvent($article));
66
67 6
        return new SingleResourceResponse(['status' => 'OK'], new ResponseContext(201));
68
    }
69
70
    /**
71
     * Receives HTTP Push Request's assets payload which is then processed and stored.
72
     *
73
     * @ApiDoc(
74
     *     resource=true,
75
     *     description="Adds new assets from HTTP Push",
76
     *     statusCodes={
77
     *         201="Returned on successful post.",
78
     *         500="Returned on invalid file.",
79
     *         200="Returned on form errors"
80
     *     },
81
     *     input="SWP\Bundle\ContentBundle\Form\Type\MediaFileType"
82
     * )
83
     * @Route("/api/{version}/assets/push", options={"expose"=true}, defaults={"version"="v1"}, name="swp_api_assets_push")
84
     * @Method("POST")
85
     */
86
    public function pushAssetsAction(Request $request)
87
    {
88
        $form = $this->createForm(MediaFileType::class);
89
        $form->handleRequest($request);
90
        if ($form->isSubmitted() && $form->isValid()) {
91
            $mediaManager = $this->container->get('swp_content_bundle.manager.media');
92
            $uploadedFile = $form->getData()['media'];
93
            $mediaId = $request->request->get('media_id');
94
            if ($uploadedFile->isValid()) {
95
                $media = $mediaManager->handleUploadedFile(
96
                    $uploadedFile,
97
                    ArticleMedia::handleMediaId($mediaId)
98
                );
99
100
                return new SingleResourceResponse([
101
                    'media_id' => $mediaId,
102
                    'URL' => $mediaManager->getMediaPublicUrl($media),
103
                    'media' => base64_encode($mediaManager->getFile($media)),
104
                    'mime_type' => Mime::getMimeFromExtension($media->getFileExtension()),
105
                    'filemeta' => [],
106
                ], new ResponseContext(201));
107
            }
108
109
            throw new \Exception('Uploaded file is not valid:'.$uploadedFile->getErrorMessage());
110
        }
111
112
        return new SingleResourceResponse($form);
113
    }
114
115
    /**
116
     * Checks if media exists in storage.
117
     *
118
     * @ApiDoc(
119
     *     resource=true,
120
     *     description="Gets a single media file",
121
     *     statusCodes={
122
     *         404="Returned when file doesn't exist.",
123
     *         200="Returned on form errors"
124
     *     }
125
     * )
126
     * @Route("/api/{version}/assets/push/{mediaId}", options={"expose"=true}, defaults={"version"="v1"}, requirements={"mediaId"=".+"}, name="swp_api_assets_get")
127
     * @Route("/api/{version}/assets/get/{mediaId}", options={"expose"=true}, defaults={"version"="v1"}, requirements={"mediaId"=".+"}, name="swp_api_assets_get_1")
128
     * @Method("GET")
129
     */
130
    public function getAssetsAction($mediaId)
131
    {
132
        $media = $this->get('swp.repository.media')->getByCriteria(new Criteria([
133
            'assetId' => $mediaId,
134
        ]), [], 'am')->getQuery()->getOneOrNullResult();
135
136
        if (null === $media) {
137
            throw new ResourceNotFoundException('Media don\'t exists in storage');
138
        }
139
140
        $mediaManager = $this->container->get('swp_content_bundle.manager.media');
141
142
        return new SingleResourceResponse([
143
            'media_id' => $mediaId,
144
            'URL' => $mediaManager->getMediaPublicUrl($media),
145
            'media' => base64_encode($mediaManager->getFile($media)),
146
            'mime_type' => Mime::getMimeFromExtension($media->getFileExtension()),
147
            'filemeta' => [],
148
        ]);
149
    }
150
151
    /**
152
     * @param Request $request
153
     *
154
     * @return PackageInterface
155
     */
156 6
    private function handlePackage(Request $request) : PackageInterface
157
    {
158 6
        $content = $request->getContent();
159 6
        $package = $this->get('swp_bridge.transformer.json_to_package')->transform($content);
160
161 6
        $packageRepository = $this->get('swp.repository.package');
162 6
        $existingPackage = $packageRepository->findOneBy(['guid' => $package->getGuid()]);
163 6
        if (null !== $existingPackage) {
164
            $packageRepository->remove($existingPackage);
165
        }
166 6
        $packageRepository->add($package);
167
168 6
        return $package;
169
    }
170
}
171