Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\IntegrationsBundle\Controller;
|
||||
|
||||
use Mautic\CoreBundle\Controller\CommonController;
|
||||
use Mautic\IntegrationsBundle\Exception\IntegrationNotFoundException;
|
||||
use Mautic\IntegrationsBundle\Exception\UnauthorizedException;
|
||||
use Mautic\IntegrationsBundle\Helper\AuthIntegrationsHelper;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class AuthController extends CommonController
|
||||
{
|
||||
public function callbackAction(AuthIntegrationsHelper $authIntegrationsHelper, string $integration, Request $request)
|
||||
{
|
||||
$authenticationError = false;
|
||||
|
||||
try {
|
||||
$authIntegration = $authIntegrationsHelper->getIntegration($integration);
|
||||
$message = $authIntegration->authenticateIntegration($request);
|
||||
} catch (UnauthorizedException $exception) {
|
||||
$message = $exception->getMessage();
|
||||
$authenticationError = true;
|
||||
} catch (IntegrationNotFoundException) {
|
||||
return $this->notFound();
|
||||
}
|
||||
|
||||
return $this->render(
|
||||
'@Integrations/Auth/authenticated.html.twig',
|
||||
[
|
||||
'message' => $message,
|
||||
'authenticationError' => $authenticationError,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\IntegrationsBundle\Controller;
|
||||
|
||||
use Mautic\CoreBundle\Controller\AbstractFormController;
|
||||
use Mautic\CoreBundle\Twig\Extension\FormExtension;
|
||||
use Mautic\IntegrationsBundle\Event\ConfigAuthUrlEvent;
|
||||
use Mautic\IntegrationsBundle\Event\ConfigSaveEvent;
|
||||
use Mautic\IntegrationsBundle\Event\FormLoadEvent;
|
||||
use Mautic\IntegrationsBundle\Event\KeysSaveEvent;
|
||||
use Mautic\IntegrationsBundle\Exception\IntegrationNotFoundException;
|
||||
use Mautic\IntegrationsBundle\Form\Type\IntegrationConfigType;
|
||||
use Mautic\IntegrationsBundle\Helper\ConfigIntegrationsHelper;
|
||||
use Mautic\IntegrationsBundle\Helper\FieldMergerHelper;
|
||||
use Mautic\IntegrationsBundle\Helper\FieldValidationHelper;
|
||||
use Mautic\IntegrationsBundle\Integration\BasicIntegration;
|
||||
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormAuthInterface;
|
||||
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormAuthorizeButtonInterface;
|
||||
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormCallbackInterface;
|
||||
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormFeatureSettingsInterface;
|
||||
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormFeaturesInterface;
|
||||
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormInterface;
|
||||
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormNotesInterface;
|
||||
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormSyncInterface;
|
||||
use Mautic\IntegrationsBundle\IntegrationEvents;
|
||||
use Mautic\PluginBundle\Entity\Integration;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Session\Session;
|
||||
|
||||
class ConfigController extends AbstractFormController
|
||||
{
|
||||
/**
|
||||
* @var BasicIntegration|ConfigFormInterface
|
||||
*/
|
||||
private $integrationObject;
|
||||
|
||||
/**
|
||||
* @var Integration
|
||||
*/
|
||||
private $integrationConfiguration;
|
||||
|
||||
/**
|
||||
* @return array|JsonResponse|RedirectResponse|Response
|
||||
*/
|
||||
public function editAction(
|
||||
Request $request,
|
||||
ConfigIntegrationsHelper $integrationsHelper,
|
||||
EventDispatcherInterface $dispatcher,
|
||||
FieldValidationHelper $fieldValidator,
|
||||
FormFactoryInterface $formFactory,
|
||||
FormExtension $formExtension,
|
||||
string $integration,
|
||||
) {
|
||||
// Check ACL
|
||||
if (!$this->security->isGranted('plugin:plugins:manage')) {
|
||||
return $this->accessDenied();
|
||||
}
|
||||
|
||||
try {
|
||||
$this->integrationObject = $integrationsHelper->getIntegration($integration);
|
||||
$this->integrationConfiguration = $this->integrationObject->getIntegrationConfiguration();
|
||||
} catch (IntegrationNotFoundException) {
|
||||
return $this->notFound();
|
||||
}
|
||||
|
||||
$event = new FormLoadEvent($this->integrationConfiguration);
|
||||
$dispatcher->dispatch($event, IntegrationEvents::INTEGRATION_CONFIG_FORM_LOAD);
|
||||
|
||||
// Create the form
|
||||
$form = $this->getForm($formFactory);
|
||||
|
||||
if (Request::METHOD_POST === $request->getMethod()) {
|
||||
return $this->submitForm($request, $integrationsHelper, $fieldValidator, $dispatcher, $formFactory, $formExtension, $form);
|
||||
}
|
||||
|
||||
// Clear the session of previously stored fields in case it got stuck
|
||||
/** @var Session $session */
|
||||
$session = $request->getSession();
|
||||
$session->remove("$integration-fields");
|
||||
|
||||
return $this->showForm($request, $form, $formExtension);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormInterface<mixed> $form
|
||||
*/
|
||||
private function submitForm(
|
||||
Request $request,
|
||||
ConfigIntegrationsHelper $integrationsHelper,
|
||||
FieldValidationHelper $fieldValidator,
|
||||
EventDispatcherInterface $eventDispatcher,
|
||||
FormFactoryInterface $formFactory,
|
||||
FormExtension $formExtension,
|
||||
FormInterface $form,
|
||||
): JsonResponse|Response {
|
||||
if ($this->isFormCancelled($form)) {
|
||||
return $this->closeForm($request);
|
||||
}
|
||||
|
||||
// Get the fields before the form binds partial data due to pagination
|
||||
$settings = $this->integrationConfiguration->getFeatureSettings();
|
||||
$fieldMappings = $settings['sync']['fieldMappings'] ?? [];
|
||||
$oldApiKeys = $this->integrationConfiguration->getApiKeys();
|
||||
|
||||
// Submit the form
|
||||
$form->handleRequest($request);
|
||||
|
||||
$configEvent = new KeysSaveEvent($this->integrationConfiguration, $oldApiKeys);
|
||||
$this->dispatcher->dispatch($configEvent, IntegrationEvents::INTEGRATION_API_KEYS_BEFORE_SAVE);
|
||||
|
||||
if ($this->integrationObject instanceof ConfigFormSyncInterface) {
|
||||
$integration = $this->integrationObject->getName();
|
||||
$settings = $this->integrationConfiguration->getFeatureSettings();
|
||||
$session = $request->getSession();
|
||||
$updatedFields = $session->get("$integration-fields", []);
|
||||
|
||||
$fieldMerger = new FieldMergerHelper($this->integrationObject, $fieldMappings);
|
||||
|
||||
foreach ($updatedFields as $object => $fields) {
|
||||
$fieldMerger->mergeSyncFieldMapping($object, $fields);
|
||||
}
|
||||
|
||||
$settings['sync']['fieldMappings'] = $fieldMerger->getFieldMappings();
|
||||
|
||||
$fieldValidator->validateRequiredFields($form, $this->integrationObject, $settings['sync']['fieldMappings']);
|
||||
|
||||
$this->integrationConfiguration->setFeatureSettings($settings);
|
||||
}
|
||||
|
||||
// Dispatch event prior to saving the Integration. Bundles/plugins may need to modify some field values before save
|
||||
$configEvent = new ConfigSaveEvent($this->integrationConfiguration);
|
||||
$eventDispatcher->dispatch($configEvent, IntegrationEvents::INTEGRATION_CONFIG_BEFORE_SAVE);
|
||||
|
||||
// Show the form if there are errors and the plugin is published or the authorized button was clicked
|
||||
$integrationDetailsPost = $request->request->all()['integration_details'] ?? [];
|
||||
$authorize = !empty($integrationDetailsPost['in_auth']);
|
||||
if ($form->isSubmitted() && !$form->isValid() && ($this->integrationConfiguration->getIsPublished() || $authorize)) {
|
||||
return $this->showForm($request, $form, $formExtension);
|
||||
}
|
||||
|
||||
// Save the integration configuration
|
||||
$integrationsHelper->saveIntegrationConfiguration($this->integrationConfiguration);
|
||||
|
||||
// Dispatch after save event
|
||||
$eventDispatcher->dispatch($configEvent, IntegrationEvents::INTEGRATION_CONFIG_AFTER_SAVE);
|
||||
|
||||
// Show the form if the apply button was clicked
|
||||
if ($this->isFormApplied($form)) {
|
||||
// Regenerate the form
|
||||
$this->resetFieldsInSession($request);
|
||||
$form = $this->getForm($formFactory);
|
||||
|
||||
return $this->showForm($request, $form, $formExtension);
|
||||
}
|
||||
|
||||
// Otherwise close the modal
|
||||
return $this->closeForm($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FormInterface<mixed>
|
||||
*/
|
||||
private function getForm(FormFactoryInterface $formFactory): FormInterface
|
||||
{
|
||||
return $formFactory->create(
|
||||
$this->integrationObject->getConfigFormName() ?: IntegrationConfigType::class,
|
||||
$this->integrationConfiguration,
|
||||
[
|
||||
'action' => $this->generateUrl('mautic_integration_config', ['integration' => $this->integrationObject->getName()]),
|
||||
'integration' => $this->integrationObject->getName(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormInterface<mixed> $form
|
||||
*/
|
||||
private function showForm(Request $request, FormInterface $form, FormExtension $formExtension): Response
|
||||
{
|
||||
$integrationObject = $this->integrationObject;
|
||||
$formView = $form->createView();
|
||||
|
||||
$showFeaturesTab = $integrationObject instanceof ConfigFormFeaturesInterface
|
||||
|| $integrationObject instanceof ConfigFormSyncInterface
|
||||
|| $integrationObject instanceof ConfigFormFeatureSettingsInterface;
|
||||
|
||||
$hasFeatureErrors = (
|
||||
$integrationObject instanceof ConfigFormFeatureSettingsInterface
|
||||
&& $formExtension->containsErrors($formView['featureSettings']['integration'])
|
||||
) || (
|
||||
isset($formView['featureSettings']['sync']['integration'])
|
||||
&& $formExtension->containsErrors($formView['featureSettings']['sync']['integration'])
|
||||
);
|
||||
|
||||
$hasAuthErrors = $integrationObject instanceof ConfigFormAuthInterface && $formExtension->containsErrors($formView['apiKeys']);
|
||||
|
||||
$useSyncFeatures = $integrationObject instanceof ConfigFormSyncInterface;
|
||||
|
||||
$useFeatureSettings = $integrationObject instanceof ConfigFormFeatureSettingsInterface;
|
||||
|
||||
$useAuthorizationUrl = $integrationObject instanceof ConfigFormAuthorizeButtonInterface;
|
||||
|
||||
$callbackUrl = $integrationObject instanceof ConfigFormCallbackInterface ?
|
||||
$integrationObject->getRedirectUri()
|
||||
: false;
|
||||
|
||||
$useConfigFormNotes = $integrationObject instanceof ConfigFormNotesInterface;
|
||||
|
||||
return $this->delegateView(
|
||||
[
|
||||
'viewParameters' => [
|
||||
'integrationObject' => $integrationObject,
|
||||
'form' => $formView,
|
||||
'activeTab' => $request->get('activeTab'),
|
||||
'showFeaturesTab' => $showFeaturesTab,
|
||||
'hasFeatureErrors' => $hasFeatureErrors,
|
||||
'hasAuthErrors' => $hasAuthErrors,
|
||||
'useSyncFeatures' => $useSyncFeatures,
|
||||
'useFeatureSettings' => $useFeatureSettings,
|
||||
'useAuthorizationUrl' => $useAuthorizationUrl,
|
||||
'callbackUrl' => $callbackUrl,
|
||||
'useConfigFormNotes' => $useConfigFormNotes,
|
||||
],
|
||||
'contentTemplate' => $integrationObject->getConfigFormContentTemplate()
|
||||
?: '@Integrations/Config/form.html.twig',
|
||||
'passthroughVars' => [
|
||||
'activeLink' => '#mautic_plugin_index',
|
||||
'mauticContent' => 'integrationsConfig',
|
||||
'route' => false,
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function closeForm(Request $request): JsonResponse
|
||||
{
|
||||
$this->resetFieldsInSession($request);
|
||||
|
||||
$response = [
|
||||
'closeModal' => 1,
|
||||
'enabled' => $this->integrationConfiguration->getIsPublished(),
|
||||
'name' => $this->integrationConfiguration->getName(),
|
||||
'mauticContent' => 'integrationsConfig',
|
||||
'flashes' => $this->getFlashContent(),
|
||||
];
|
||||
|
||||
if ($this->integrationObject instanceof ConfigFormAuthorizeButtonInterface) {
|
||||
// Dispatch event to allow listeners to extract information and/or manipulate the URL
|
||||
$authUrl = $this->integrationObject->getAuthorizationUrl();
|
||||
$authUrlEvent = new ConfigAuthUrlEvent($this->integrationConfiguration, $authUrl);
|
||||
$this->dispatcher->dispatch($authUrlEvent, IntegrationEvents::INTEGRATION_CONFIG_ON_GENERATE_AUTH_URL);
|
||||
|
||||
$response['authUrl'] = $authUrlEvent->getAuthUrl();
|
||||
}
|
||||
|
||||
return new JsonResponse($response);
|
||||
}
|
||||
|
||||
private function resetFieldsInSession(Request $request): void
|
||||
{
|
||||
$session = $request->getSession();
|
||||
$session->remove("{$this->integrationObject->getName()}-fields");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\IntegrationsBundle\Controller;
|
||||
|
||||
use Mautic\CoreBundle\Controller\CommonController;
|
||||
use Mautic\IntegrationsBundle\Exception\IntegrationNotFoundException;
|
||||
use Mautic\IntegrationsBundle\Form\Type\IntegrationSyncSettingsObjectFieldMappingType;
|
||||
use Mautic\IntegrationsBundle\Helper\ConfigIntegrationsHelper;
|
||||
use Mautic\IntegrationsBundle\Helper\FieldFilterHelper;
|
||||
use Mautic\IntegrationsBundle\Helper\FieldMergerHelper;
|
||||
use Mautic\IntegrationsBundle\Integration\Interfaces\ConfigFormSyncInterface;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class FieldPaginationController extends CommonController
|
||||
{
|
||||
/**
|
||||
* @return Response
|
||||
*/
|
||||
public function paginateAction(
|
||||
Request $request,
|
||||
FormFactoryInterface $formFactory,
|
||||
ConfigIntegrationsHelper $integrationsHelper,
|
||||
string $integration,
|
||||
string $object,
|
||||
int $page,
|
||||
) {
|
||||
// Check ACL
|
||||
if (!$this->security->isGranted('plugin:plugins:manage')) {
|
||||
return $this->accessDenied();
|
||||
}
|
||||
|
||||
// Find the integration
|
||||
try {
|
||||
/** @var ConfigFormSyncInterface $integrationObject */
|
||||
$integrationObject = $integrationsHelper->getIntegration($integration);
|
||||
$integrationConfiguration = $integrationObject->getIntegrationConfiguration();
|
||||
} catch (IntegrationNotFoundException) {
|
||||
return $this->notFound();
|
||||
}
|
||||
|
||||
$keyword = $request->get('keyword');
|
||||
$featureSettings = $integrationConfiguration->getFeatureSettings();
|
||||
$currentFields = $this->getFields($request, $integrationObject, $featureSettings, $object);
|
||||
|
||||
$fieldFilterHelper = new FieldFilterHelper($integrationObject);
|
||||
if ($keyword) {
|
||||
$fieldFilterHelper->filterFieldsByKeyword($object, $keyword, $page);
|
||||
} else {
|
||||
$fieldFilterHelper->filterFieldsByPage($object, $page);
|
||||
}
|
||||
|
||||
// Create the form
|
||||
$form = $formFactory->create(
|
||||
IntegrationSyncSettingsObjectFieldMappingType::class,
|
||||
$currentFields,
|
||||
[
|
||||
'integrationFields' => $fieldFilterHelper->getFilteredFields(),
|
||||
'page' => $page,
|
||||
'keyword' => $keyword,
|
||||
'totalFieldCount' => $fieldFilterHelper->getTotalFieldCount(),
|
||||
'object' => $object,
|
||||
'integrationObject' => $integrationObject,
|
||||
'csrf_protection' => false,
|
||||
]
|
||||
);
|
||||
|
||||
$html = $this->render(
|
||||
'@Integrations/Config/field_mapping.html.twig',
|
||||
[
|
||||
'form' => $form->createView(),
|
||||
'integration' => $integration,
|
||||
'object' => $object,
|
||||
'page' => $page,
|
||||
]
|
||||
)->getContent();
|
||||
|
||||
$prefix = "integration_config[featureSettings][sync][fieldMappings][$object]";
|
||||
$idPrefix = str_replace(['][', '[', ']'], '_', $prefix);
|
||||
if (str_ends_with($idPrefix, '_')) {
|
||||
$idPrefix = substr($idPrefix, 0, -1);
|
||||
}
|
||||
|
||||
$formType = 'integration_sync_settings_object_field_mapping';
|
||||
$html = preg_replace('/'.$formType.'\[(.*?)\]/', $prefix.'[$1]', $html);
|
||||
$html = str_replace($formType, $idPrefix, $html);
|
||||
|
||||
return new JsonResponse(
|
||||
[
|
||||
'success' => 1,
|
||||
'html' => $html,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function getFields(Request $request, ConfigFormSyncInterface $integrationObject, array $featureSettings, string $object): array
|
||||
{
|
||||
$fields = $featureSettings['sync']['fieldMappings'] ?? [];
|
||||
|
||||
if (!isset($fields[$object])) {
|
||||
$fields[$object] = [];
|
||||
}
|
||||
|
||||
// Pull those changed from session
|
||||
$session = $request->getSession();
|
||||
$sessionFields = $session->get(sprintf('%s-fields', $integrationObject->getName()), []);
|
||||
|
||||
if (!isset($sessionFields[$object])) {
|
||||
return $fields[$object];
|
||||
}
|
||||
|
||||
$fieldMerger = new FieldMergerHelper($integrationObject, $fields);
|
||||
$fieldMerger->mergeSyncFieldMapping($object, $sessionFields[$object]);
|
||||
|
||||
return $fieldMerger->getFieldMappings()[$object];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Mautic\IntegrationsBundle\Controller;
|
||||
|
||||
use Mautic\CoreBundle\Controller\CommonController;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class UpdateFieldController extends CommonController
|
||||
{
|
||||
public function updateAction(Request $request, string $integration, string $object, string $field): JsonResponse
|
||||
{
|
||||
// Clear the session of previously stored fields in case it got stuck
|
||||
$session = $request->getSession();
|
||||
$updatedFields = $session->get(sprintf('%s-fields', $integration), []);
|
||||
|
||||
if (!isset($updatedFields[$object])) {
|
||||
$updatedFields[$object] = [];
|
||||
}
|
||||
|
||||
if (!isset($updatedFields[$object][$field])) {
|
||||
$updatedFields[$object][$field] = [];
|
||||
}
|
||||
|
||||
if ($mappedField = $request->request->get('mappedField')) {
|
||||
$updatedFields[$object][$field]['mappedField'] = $mappedField;
|
||||
}
|
||||
|
||||
if ($syncDirection = $request->request->get('syncDirection')) {
|
||||
$updatedFields[$object][$field]['syncDirection'] = $syncDirection;
|
||||
}
|
||||
|
||||
$session->set(sprintf('%s-fields', $integration), $updatedFields);
|
||||
|
||||
return new JsonResponse([]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user