Issues (3627)

Controller/Api/CampaignApiController.php (1 issue)

1
<?php
2
3
/*
4
 * @copyright   2014 Mautic Contributors. All rights reserved
5
 * @author      Mautic
6
 *
7
 * @link        http://mautic.org
8
 *
9
 * @license     GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
10
 */
11
12
namespace Mautic\CampaignBundle\Controller\Api;
13
14
use Mautic\ApiBundle\Controller\CommonApiController;
15
use Mautic\CampaignBundle\Entity\Campaign;
16
use Mautic\CampaignBundle\Membership\MembershipManager;
17
use Mautic\CoreBundle\Helper\InputHelper;
18
use Mautic\LeadBundle\Controller\LeadAccessTrait;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
21
22
class CampaignApiController extends CommonApiController
23
{
24
    use LeadAccessTrait;
25
26
    /**
27
     * @var MembershipManager
28
     */
29
    private $membershipManager;
30
31
    public function initialize(FilterControllerEvent $event)
32
    {
33
        $this->model             = $this->getModel('campaign');
34
        $this->membershipManager = $this->get('mautic.campaign.membership.manager');
35
        $this->entityClass       = Campaign::class;
36
        $this->entityNameOne     = 'campaign';
37
        $this->entityNameMulti   = 'campaigns';
38
        $this->permissionBase    = 'campaign:campaigns';
39
        $this->serializerGroups  = ['campaignDetails', 'campaignEventDetails', 'categoryList', 'publishDetails', 'leadListList', 'formList'];
40
41
        parent::initialize($event);
42
    }
43
44
    /**
45
     * Adds a lead to a campaign.
46
     *
47
     * @param int $id     Campaign ID
48
     * @param int $leadId Lead ID
49
     *
50
     * @return \Symfony\Component\HttpFoundation\Response
51
     *
52
     * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
53
     */
54
    public function addLeadAction($id, $leadId)
55
    {
56
        $entity = $this->model->getEntity($id);
57
        if (null !== $entity) {
58
            $leadModel = $this->getModel('lead');
59
            $lead      = $leadModel->getEntity($leadId);
60
61
            if (null == $lead) {
62
                return $this->notFound();
63
            } elseif (!$this->security->hasEntityAccess('lead:leads:editown', 'lead:leads:editother', $lead->getOwner())) {
64
                return $this->accessDenied();
65
            }
66
67
            $this->membershipManager->addContact($lead, $entity);
68
69
            $view = $this->view(['success' => 1], Response::HTTP_OK);
70
71
            return $this->handleView($view);
72
        }
73
74
        return $this->notFound();
75
    }
76
77
    /**
78
     * Removes given lead from a campaign.
79
     *
80
     * @param int $id     Campaign ID
81
     * @param int $leadId Lead ID
82
     *
83
     * @return \Symfony\Component\HttpFoundation\Response
84
     *
85
     * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
86
     */
87
    public function removeLeadAction($id, $leadId)
88
    {
89
        $entity = $this->model->getEntity($id);
90
        if (null !== $entity) {
91
            $lead = $this->checkLeadAccess($leadId, 'edit');
92
            if ($lead instanceof Response) {
93
                return $lead;
94
            }
95
96
            $this->membershipManager->removeContact($lead, $entity);
97
98
            $view = $this->view(['success' => 1], Response::HTTP_OK);
99
100
            return $this->handleView($view);
101
        }
102
103
        return $this->notFound();
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     *
109
     * @param \Mautic\LeadBundle\Entity\Lead &$entity
110
     * @param                                $parameters
111
     * @param                                $form
112
     * @param string                         $action
113
     */
114
    protected function preSaveEntity(&$entity, $form, $parameters, $action = 'edit')
115
    {
116
        $method = $this->request->getMethod();
117
118
        if ('POST' === $method || 'PUT' === $method) {
119
            if (empty($parameters['events'])) {
120
                $msg = $this->get('translator')->trans('mautic.campaign.form.events.notempty', [], 'validators');
121
122
                return $this->returnError($msg, Response::HTTP_BAD_REQUEST);
123
            } elseif (empty($parameters['lists']) && empty($parameters['forms'])) {
124
                $msg = $this->get('translator')->trans('mautic.campaign.form.sources.notempty', [], 'validators');
125
126
                return $this->returnError($msg, Response::HTTP_BAD_REQUEST);
127
            }
128
        }
129
130
        $deletedSources = ['lists' => [], 'forms' => []];
131
        $deletedEvents  = [];
132
        $currentSources = [
133
            'lists' => isset($parameters['lists']) ? $this->modifyCampaignEventArray($parameters['lists']) : [],
134
            'forms' => isset($parameters['forms']) ? $this->modifyCampaignEventArray($parameters['forms']) : [],
135
        ];
136
137
        // delete events and sources which does not exist in the PUT request
138
        if ('PUT' === $method) {
139
            $requestEventIds   = [];
140
            $requestSegmentIds = [];
141
            $requestFormIds    = [];
142
143
            foreach ($parameters['events'] as $key => $requestEvent) {
144
                if (!isset($requestEvent['id'])) {
145
                    return $this->returnError('$campaign[events]['.$key.']["id"] is missing', Response::HTTP_BAD_REQUEST);
146
                }
147
                $requestEventIds[] = $requestEvent['id'];
148
            }
149
150
            foreach ($entity->getEvents() as $currentEvent) {
151
                if (!in_array($currentEvent->getId(), $requestEventIds)) {
152
                    $deletedEvents[] = $currentEvent->getId();
153
                }
154
            }
155
156
            if (isset($parameters['lists'])) {
157
                foreach ($parameters['lists'] as $requestSegment) {
158
                    if (!isset($requestSegment['id'])) {
159
                        return $this->returnError('$campaign[lists]['.$key.']["id"] is missing', Response::HTTP_BAD_REQUEST);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $key seems to be defined by a foreach iteration on line 143. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
160
                    }
161
                    $requestSegmentIds[] = $requestSegment['id'];
162
                }
163
            }
164
165
            foreach ($entity->getLists() as $currentSegment) {
166
                if (!in_array($currentSegment->getId(), $requestSegmentIds)) {
167
                    $deletedSources['lists'][$currentSegment->getId()] = 'ignore';
168
                }
169
            }
170
171
            if (isset($parameters['forms'])) {
172
                foreach ($parameters['forms'] as $requestForm) {
173
                    if (!isset($requestForm['id'])) {
174
                        return $this->returnError('$campaign[forms]['.$key.']["id"] is missing', Response::HTTP_BAD_REQUEST);
175
                    }
176
                    $requestFormIds[] = $requestForm['id'];
177
                }
178
            }
179
180
            foreach ($entity->getForms() as $currentForm) {
181
                if (!in_array($currentForm->getId(), $requestFormIds)) {
182
                    $deletedSources['forms'][$currentForm->getId()] = 'ignore';
183
                }
184
            }
185
        }
186
187
        // Set lead sources
188
        $this->model->setLeadSources($entity, $currentSources, $deletedSources);
189
190
        // Build and set Event entities
191
        if (isset($parameters['events']) && isset($parameters['canvasSettings'])) {
192
            $this->model->setEvents($entity, $parameters['events'], $parameters['canvasSettings'], $deletedEvents);
193
        }
194
195
        // Persist to the database before building connection so that IDs are available
196
        $this->model->saveEntity($entity);
197
198
        // Update canvas settings with new event IDs then save
199
        if (isset($parameters['canvasSettings'])) {
200
            $this->model->setCanvasSettings($entity, $parameters['canvasSettings']);
201
        }
202
203
        if ('PUT' === $method && !empty($deletedEvents)) {
204
            $this->getModel('campaign.event')->deleteEvents($entity->getEvents()->toArray(), $deletedEvents);
205
        }
206
    }
207
208
    /**
209
     * Change the array structure.
210
     *
211
     * @param array $events
212
     *
213
     * @return array
214
     */
215
    public function modifyCampaignEventArray($events)
216
    {
217
        $updatedEvents = [];
218
219
        if ($events && is_array($events)) {
220
            foreach ($events as $event) {
221
                if (!empty($event['id'])) {
222
                    $updatedEvents[$event['id']] = 'ignore';
223
                }
224
            }
225
        }
226
227
        return $updatedEvents;
228
    }
229
230
    /**
231
     * Obtains a list of campaign contacts.
232
     *
233
     * @param $id
234
     *
235
     * @return \Symfony\Component\HttpFoundation\Response
236
     */
237
    public function getContactsAction($id)
238
    {
239
        $entity = $this->model->getEntity($id);
240
241
        if (null === $entity) {
242
            return $this->notFound();
243
        }
244
245
        if (!$this->checkEntityAccess($entity)) {
246
            return $this->accessDenied();
247
        }
248
249
        $where = InputHelper::clean($this->request->query->get('where', []));
250
        $order = InputHelper::clean($this->request->query->get('order', []));
251
        $start = (int) $this->request->query->get('start', 0);
252
        $limit = (int) $this->request->query->get('limit', 100);
253
254
        $where[] = [
255
            'col'  => 'campaign_id',
256
            'expr' => 'eq',
257
            'val'  => $id,
258
        ];
259
260
        $where[] = [
261
            'col'  => 'manually_removed',
262
            'expr' => 'eq',
263
            'val'  => 0,
264
        ];
265
266
        return $this->forward(
267
            'MauticCoreBundle:Api\StatsApi:list',
268
            [
269
                'table'     => 'campaign_leads',
270
                'itemsName' => 'contacts',
271
                'order'     => $order,
272
                'where'     => $where,
273
                'start'     => $start,
274
                'limit'     => $limit,
275
            ]
276
        );
277
    }
278
279
    public function cloneCampaignAction($campaignId)
280
    {
281
        if (empty($campaignId) || false == intval($campaignId)) {
282
            return $this->notFound();
283
        }
284
285
        $original = $this->model->getEntity($campaignId);
286
        if (empty($original)) {
287
            return $this->notFound();
288
        }
289
        $entity = clone $original;
290
291
        if (!$this->checkEntityAccess($entity, 'create')) {
292
            return $this->accessDenied();
293
        }
294
295
        $this->model->saveEntity($entity);
296
297
        $headers = [];
298
        //return the newly created entities location if applicable
299
300
        $route               = 'mautic_api_campaigns_getone';
301
        $headers['Location'] = $this->generateUrl(
302
            $route,
303
            array_merge(['id' => $entity->getId()], $this->routeParams),
304
            true
305
        );
306
307
        $view = $this->view([$this->entityNameOne => $entity], Response::HTTP_OK, $headers);
308
309
        $this->setSerializationContext($view);
310
311
        return $this->handleView($view);
312
    }
313
}
314