Completed
Push — master ( a5200d...3d485f )
by Paweł
51:04
created

ContentPushController::pushContentAction()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3.2621

Importance

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