Completed
Push — master ( 8d3dbf...7592af )
by Paweł
62:36
created

ContentPushController::pushAssetsAction()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 0
cts 0
cp 0
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 21
nc 3
nop 1
crap 20
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 Behat\Transliterator\Transliterator;
20
use Hoa\Mime\Mime;
21
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
22
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
23
use SWP\Bundle\ContentBundle\ArticleEvents;
24
use SWP\Bundle\ContentBundle\Event\ArticleEvent;
25
use SWP\Bundle\ContentBundle\Form\Type\MediaFileType;
26
use SWP\Bundle\ContentBundle\Model\ArticleMedia;
27
use SWP\Component\Bridge\Model\PackageInterface;
28
use SWP\Component\Common\Criteria\Criteria;
29
use SWP\Component\Common\Response\ResponseContext;
30
use SWP\Component\Common\Response\SingleResourceResponse;
31
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
32
use Symfony\Component\HttpFoundation\Request;
33
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
34
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
35
36
class ContentPushController extends Controller
37
{
38
    /**
39
     * Receives HTTP Push Request's payload which is then processed by the pipeline.
40
     *
41
     * @ApiDoc(
42
     *     resource=true,
43
     *     description="Adds a new content from HTTP Push",
44
     *     statusCodes={
45
     *         201="Returned on successful post."
46
     *     }
47
     * )
48
     * @Route("/api/{version}/content/push", options={"expose"=true}, defaults={"version"="v1"}, name="swp_api_content_push")
49
     * @Method("POST")
50
     */
51 11
    public function pushContentAction(Request $request)
52
    {
53 11
        $package = $this->handlePackage($request);
54 11
        $articleRepository = $this->get('swp.repository.article');
55
56 11
        $existingArticle = $articleRepository->findOneBy(['slug' => Transliterator::urlize($package->getSlugline())]);
57
58 11
        if (null !== $existingArticle) {
59
            $this->get('swp.hydrator.article')->hydrate($existingArticle, $package);
60
            $this->get('event_dispatcher')->dispatch(ArticleEvents::PRE_CREATE, new ArticleEvent($existingArticle, $package));
61
62
            $this->get('swp.object_manager.article')->flush();
63
64
            return new SingleResourceResponse(['status' => 'OK'], new ResponseContext(201));
65
        }
66
67 11
        $article = $this->get('swp_content.transformer.package_to_article')->transform($package);
68 11
        $this->get('event_dispatcher')->dispatch(ArticleEvents::PRE_CREATE, new ArticleEvent($article, $package));
69 10
        $articleRepository->add($article);
70 10
        $this->get('event_dispatcher')->dispatch(ArticleEvents::POST_CREATE, new ArticleEvent($article));
71
72 10
        return new SingleResourceResponse(['status' => 'OK'], new ResponseContext(201));
73
    }
74
75
    /**
76
     * Receives HTTP Push Request's assets payload which is then processed and stored.
77
     *
78
     * @ApiDoc(
79
     *     resource=true,
80
     *     description="Adds new assets from HTTP Push",
81
     *     statusCodes={
82
     *         201="Returned on successful post.",
83
     *         500="Returned on invalid file.",
84
     *         200="Returned on form errors"
85
     *     },
86
     *     input="SWP\Bundle\ContentBundle\Form\Type\MediaFileType"
87
     * )
88
     * @Route("/api/{version}/assets/push", options={"expose"=true}, defaults={"version"="v1"}, name="swp_api_assets_push")
89
     * @Method("POST")
90
     */
91
    public function pushAssetsAction(Request $request)
92
    {
93
        $form = $this->createForm(MediaFileType::class);
94
        $form->handleRequest($request);
95
        if ($form->isSubmitted() && $form->isValid()) {
96
            $mediaManager = $this->get('swp_content_bundle.manager.media');
97
            $uploadedFile = $form->getData()['media'];
98
            $mediaId = $request->request->get('media_id');
99
            if ($uploadedFile->isValid()) {
100
                $media = $mediaManager->handleUploadedFile(
101
                    $uploadedFile,
102
                    ArticleMedia::handleMediaId($mediaId)
103
                );
104
105
                $this->get('swp.object_manager.media')->flush();
106
107
                return new SingleResourceResponse([
108
                    'media_id' => $mediaId,
109
                    'URL' => $mediaManager->getMediaPublicUrl($media),
110
                    'media' => base64_encode($mediaManager->getFile($media)),
111
                    'mime_type' => Mime::getMimeFromExtension($media->getFileExtension()),
112
                    'filemeta' => [],
113
                ], new ResponseContext(201));
114
            }
115
116
            throw new \Exception('Uploaded file is not valid:'.$uploadedFile->getErrorMessage());
117
        }
118
119
        return new SingleResourceResponse($form);
120
    }
121
122
    /**
123
     * Checks if media exists in storage.
124
     *
125
     * @ApiDoc(
126
     *     resource=true,
127
     *     description="Gets a single media file",
128
     *     statusCodes={
129
     *         404="Returned when file doesn't exist.",
130
     *         200="Returned on form errors"
131
     *     }
132
     * )
133
     * @Route("/api/{version}/assets/push/{mediaId}", options={"expose"=true}, defaults={"version"="v1"}, requirements={"mediaId"=".+"}, name="swp_api_assets_get")
134
     * @Route("/api/{version}/assets/get/{mediaId}", options={"expose"=true}, defaults={"version"="v1"}, requirements={"mediaId"=".+"}, name="swp_api_assets_get_1")
135
     * @Method("GET")
136
     */
137
    public function getAssetsAction($mediaId)
138
    {
139
        $media = $this->get('swp.repository.image')->getByCriteria(new Criteria([
140
            'assetId' => ArticleMedia::handleMediaId($mediaId),
141
        ]), [], 'am')->getQuery()->getOneOrNullResult();
142
143
        if (null === $media) {
144
            throw new NotFoundHttpException('Media don\'t exist in storage');
145
        }
146
147
        $mediaManager = $this->get('swp_content_bundle.manager.media');
148
149
        return new SingleResourceResponse([
150
            'media_id' => $mediaId,
151
            'URL' => $mediaManager->getMediaPublicUrl($media),
152
            'media' => base64_encode($mediaManager->getFile($media)),
153
            'mime_type' => Mime::getMimeFromExtension($media->getFileExtension()),
154
            'filemeta' => [],
155
        ]);
156
    }
157
158
    /**
159
     * @param Request $request
160
     *
161
     * @return PackageInterface
162
     */
163 11
    private function handlePackage(Request $request): PackageInterface
164
    {
165 11
        $content = $request->getContent();
166 11
        $package = $this->get('swp_bridge.transformer.json_to_package')->transform($content);
167
168 11
        $packageRepository = $this->get('swp.repository.package');
169 11
        $existingPackage = $packageRepository->findOneBy(['guid' => $package->getGuid()]);
170 11
        if (null !== $existingPackage) {
171
            $packageRepository->remove($existingPackage);
172
        }
173 11
        $packageRepository->add($package);
174
175 11
        return $package;
176
    }
177
}
178