mautic / app /bundles /CampaignBundle /Controller /Api /CampaignApiController.php
chrisbryan17's picture
Upload folder using huggingface_hub
d2897cd verified
<?php
namespace Mautic\CampaignBundle\Controller\Api;
use Doctrine\Persistence\ManagerRegistry;
use Mautic\ApiBundle\Controller\CommonApiController;
use Mautic\ApiBundle\Helper\EntityResultHelper;
use Mautic\CampaignBundle\Entity\Campaign;
use Mautic\CampaignBundle\Membership\MembershipManager;
use Mautic\CampaignBundle\Model\CampaignModel;
use Mautic\CampaignBundle\Model\EventModel;
use Mautic\CoreBundle\Factory\MauticFactory;
use Mautic\CoreBundle\Factory\ModelFactory;
use Mautic\CoreBundle\Helper\AppVersion;
use Mautic\CoreBundle\Helper\CoreParametersHelper;
use Mautic\CoreBundle\Helper\InputHelper;
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
use Mautic\CoreBundle\Translation\Translator;
use Mautic\LeadBundle\Controller\LeadAccessTrait;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
/**
* @extends CommonApiController<Campaign>
*/
class CampaignApiController extends CommonApiController
{
use LeadAccessTrait;
/**
* @var CampaignModel|null
*/
protected $model;
public function __construct(
CorePermissions $security,
Translator $translator,
EntityResultHelper $entityResultHelper,
RouterInterface $router,
FormFactoryInterface $formFactory,
AppVersion $appVersion,
private RequestStack $requestStack,
private MembershipManager $membershipManager,
ManagerRegistry $doctrine,
ModelFactory $modelFactory,
EventDispatcherInterface $dispatcher,
CoreParametersHelper $coreParametersHelper,
MauticFactory $factory
) {
$campaignModel = $modelFactory->getModel('campaign');
\assert($campaignModel instanceof CampaignModel);
$this->model = $campaignModel;
$this->entityClass = Campaign::class;
$this->entityNameOne = 'campaign';
$this->entityNameMulti = 'campaigns';
$this->permissionBase = 'campaign:campaigns';
$this->serializerGroups = ['campaignDetails', 'campaignEventDetails', 'categoryList', 'publishDetails', 'leadListList', 'formList'];
parent::__construct($security, $translator, $entityResultHelper, $router, $formFactory, $appVersion, $requestStack, $doctrine, $modelFactory, $dispatcher, $coreParametersHelper, $factory);
}
/**
* Adds a lead to a campaign.
*
* @param int $id Campaign ID
* @param int $leadId Lead ID
*
* @return Response
*
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function addLeadAction($id, $leadId)
{
$entity = $this->model->getEntity($id);
if (null !== $entity) {
$leadModel = $this->getModel('lead');
$lead = $leadModel->getEntity($leadId);
if (null == $lead) {
return $this->notFound();
} elseif (!$this->security->hasEntityAccess('lead:leads:editown', 'lead:leads:editother', $lead->getOwner())) {
return $this->accessDenied();
}
$this->membershipManager->addContact($lead, $entity);
$view = $this->view(['success' => 1], Response::HTTP_OK);
return $this->handleView($view);
}
return $this->notFound();
}
/**
* Removes given lead from a campaign.
*
* @param int $id Campaign ID
* @param int $leadId Lead ID
*
* @return Response
*
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
public function removeLeadAction($id, $leadId)
{
$entity = $this->model->getEntity($id);
if (null !== $entity) {
$lead = $this->checkLeadAccess($leadId, 'edit');
if ($lead instanceof Response) {
return $lead;
}
$this->membershipManager->removeContact($lead, $entity);
$view = $this->view(['success' => 1], Response::HTTP_OK);
return $this->handleView($view);
}
return $this->notFound();
}
/**
* @param Campaign &$entity
* @param string $action
*/
protected function preSaveEntity(&$entity, $form, $parameters, $action = 'edit')
{
$method = $this->requestStack->getCurrentRequest()->getMethod();
if ('POST' === $method || 'PUT' === $method) {
if (empty($parameters['events'])) {
$msg = $this->translator->trans('mautic.campaign.form.events.notempty', [], 'validators');
return $this->returnError($msg, Response::HTTP_BAD_REQUEST);
} elseif (empty($parameters['lists']) && empty($parameters['forms'])) {
$msg = $this->translator->trans('mautic.campaign.form.sources.notempty', [], 'validators');
return $this->returnError($msg, Response::HTTP_BAD_REQUEST);
}
}
$deletedSources = ['lists' => [], 'forms' => []];
$deletedEvents = [];
$currentSources = [
'lists' => isset($parameters['lists']) ? $this->modifyCampaignEventArray($parameters['lists']) : [],
'forms' => isset($parameters['forms']) ? $this->modifyCampaignEventArray($parameters['forms']) : [],
];
// delete events and sources which does not exist in the PUT request
if ('PUT' === $method) {
$requestEventIds = [];
$requestSegmentIds = [];
$requestFormIds = [];
foreach ($parameters['events'] as $key => $requestEvent) {
if (!isset($requestEvent['id'])) {
return $this->returnError('$campaign[events]['.$key.']["id"] is missing', Response::HTTP_BAD_REQUEST);
}
$requestEventIds[] = $requestEvent['id'];
}
foreach ($entity->getEvents() as $currentEvent) {
if (!in_array($currentEvent->getId(), $requestEventIds)) {
$deletedEvents[] = $currentEvent->getId();
}
}
if (isset($parameters['lists'])) {
foreach ($parameters['lists'] as $requestSegment) {
if (!isset($requestSegment['id'])) {
return $this->returnError('$campaign[lists]['.$key.']["id"] is missing', Response::HTTP_BAD_REQUEST);
}
$requestSegmentIds[] = $requestSegment['id'];
}
}
foreach ($entity->getLists() as $currentSegment) {
if (!in_array($currentSegment->getId(), $requestSegmentIds)) {
$deletedSources['lists'][$currentSegment->getId()] = 'ignore';
}
}
if (isset($parameters['forms'])) {
foreach ($parameters['forms'] as $requestForm) {
if (!isset($requestForm['id'])) {
return $this->returnError('$campaign[forms]['.$key.']["id"] is missing', Response::HTTP_BAD_REQUEST);
}
$requestFormIds[] = $requestForm['id'];
}
}
foreach ($entity->getForms() as $currentForm) {
if (!in_array($currentForm->getId(), $requestFormIds)) {
$deletedSources['forms'][$currentForm->getId()] = 'ignore';
}
}
}
// Set lead sources
$this->model->setLeadSources($entity, $currentSources, $deletedSources);
// Build and set Event entities
if (isset($parameters['events']) && isset($parameters['canvasSettings'])) {
$this->model->setEvents($entity, $parameters['events'], $parameters['canvasSettings'], $deletedEvents);
}
// Persist to the database before building connection so that IDs are available
$this->model->saveEntity($entity);
// Update canvas settings with new event IDs then save
if (isset($parameters['canvasSettings'])) {
$this->model->setCanvasSettings($entity, $parameters['canvasSettings']);
}
if (Request::METHOD_PUT === $method && !empty($deletedEvents)) {
$campaignEventModel = $this->getModel('campaign.event');
\assert($campaignEventModel instanceof EventModel);
$campaignEventModel->deleteEvents($entity->getEvents()->toArray(), $deletedEvents);
}
}
/**
* Change the array structure.
*
* @param array $events
*/
public function modifyCampaignEventArray($events): array
{
$updatedEvents = [];
if ($events && is_array($events)) {
foreach ($events as $event) {
if (!empty($event['id'])) {
$updatedEvents[$event['id']] = 'ignore';
}
}
}
return $updatedEvents;
}
/**
* Obtains a list of campaign contacts.
*
* @return Response
*/
public function getContactsAction(Request $request, $id)
{
$entity = $this->model->getEntity($id);
if (null === $entity) {
return $this->notFound();
}
if (!$this->checkEntityAccess($entity)) {
return $this->accessDenied();
}
$where = InputHelper::clean($request->query->get('where') ?? []);
$order = InputHelper::clean($request->query->get('order') ?? []);
$start = (int) $request->query->get('start', 0);
$limit = (int) $request->query->get('limit', 100);
$where[] = [
'col' => 'campaign_id',
'expr' => 'eq',
'val' => $id,
];
$where[] = [
'col' => 'manually_removed',
'expr' => 'eq',
'val' => 0,
];
return $this->forward(
'Mautic\CoreBundle\Controller\Api\StatsApiController::listAction',
[
'table' => 'campaign_leads',
'itemsName' => 'contacts',
'order' => $order,
'where' => $where,
'start' => $start,
'limit' => $limit,
]
);
}
public function cloneCampaignAction($campaignId)
{
if (empty($campaignId) || false == intval($campaignId)) {
return $this->notFound();
}
$original = $this->model->getEntity($campaignId);
if (empty($original)) {
return $this->notFound();
}
$entity = clone $original;
if (!$this->checkEntityAccess($entity, 'create')) {
return $this->accessDenied();
}
$this->model->saveEntity($entity);
$headers = [];
// return the newly created entities location if applicable
$route = 'mautic_api_campaigns_getone';
$headers['Location'] = $this->generateUrl(
$route,
array_merge(['id' => $entity->getId()], $this->routeParams),
true
);
$view = $this->view([$this->entityNameOne => $entity], Response::HTTP_OK, $headers);
$this->setSerializationContext($view);
return $this->handleView($view);
}
}