Completed
Push — master ( 692aa1...25e5a7 )
by Paweł
60:22
created

ContentPushController::getExistingArticleOrNull()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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