Initial commit: CloudOps infrastructure platform

This commit is contained in:
root
2026-04-09 19:58:57 +02:00
commit 1166a52f26
7762 changed files with 839452 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
<?php
namespace Mautic\WebhookBundle\Form\DataTransformer;
use Doctrine\Common\Collections\Collection;
use Mautic\WebhookBundle\Entity\Event;
use Mautic\WebhookBundle\Entity\Webhook;
use Symfony\Component\Form\DataTransformerInterface;
/**
* @implements DataTransformerInterface<Collection<int, Event>, array<int, string>>
*/
class EventsToArrayTransformer implements DataTransformerInterface
{
public function __construct(
private Webhook $webhook,
) {
}
/**
* Convert from the PersistentCollection of Event entities to a simple array.
*
* @param $events Collection<int, Event>
*
* @return array<int, string>
*/
public function transform(mixed $events): mixed
{
$eventArray = [];
foreach ($events as $event) {
$eventArray[] = $event->getEventType();
}
return $eventArray;
}
/**
* Convert a simple array into a PersistentCollection of Event entities.
*
* @param $submittedArray array<int, string>
*
* @return Collection<int, Event>
*/
public function reverseTransform(mixed $submittedArray): mixed
{
// Get a list of existing events and types
$events = $this->webhook->getEvents();
$eventTypes = $events->getKeys();
// Check to see what events have been removed
$removed = array_diff($eventTypes, $submittedArray);
foreach ($removed as $type) {
$this->webhook->removeEvent($events[$type]);
}
// Now check to see what events have been added
$added = array_diff($submittedArray, $eventTypes);
foreach ($added as $type) {
// Create a new entity
$event = new Event();
$event->setWebhook($this->webhook)->setEventType($type);
$events[] = $event;
}
$this->webhook->setEvents($events);
return $events;
}
}

View File

@@ -0,0 +1,107 @@
<?php
namespace Mautic\WebhookBundle\Form\Type;
use Mautic\CoreBundle\Form\Type\SortableListType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\UrlType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* @extends AbstractType<array<mixed>>
*/
class CampaignEventSendWebhookType extends AbstractType
{
public function __construct(
private TranslatorInterface $translator,
) {
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add(
'url',
UrlType::class,
[
'label' => 'mautic.webhook.event.sendwebhook.url',
'label_attr' => ['class' => 'control-label'],
'attr' => ['class' => 'form-control'],
'required' => true,
'constraints' => [
new NotBlank(
[
'message' => 'mautic.core.value.required',
]
),
],
]
);
$builder->add(
'method',
ChoiceType::class,
[
'choices' => [
'GET' => 'get',
'POST' => 'post',
'PUT' => 'put',
'PATCH' => 'patch',
'DELETE' => 'delete',
],
'multiple' => false,
'label_attr' => ['class' => 'control-label'],
'label' => 'mautic.webhook.event.sendwebhook.method',
'attr' => [
'class' => 'form-control',
],
'placeholder' => false,
'required' => false,
]
);
$builder->add(
'headers',
SortableListType::class,
[
'required' => false,
'label' => 'mautic.webhook.event.sendwebhook.headers',
'option_required' => false,
'with_labels' => true,
]
);
$builder->add(
'additional_data',
SortableListType::class,
[
'required' => false,
'label' => 'mautic.webhook.event.sendwebhook.data',
'option_required' => false,
'with_labels' => true,
]
);
$builder->add(
'timeout',
NumberType::class,
[
'label' => 'mautic.webhook.event.sendwebhook.timeout',
'label_attr' => ['class' => 'control-label'],
'attr' => [
'class' => 'form-control',
'postaddon_text' => $this->translator->trans('mautic.core.time.seconds'),
],
'data' => !empty($options['data']['timeout']) ? $options['data']['timeout'] : 10,
]
);
}
public function getBlockPrefix(): string
{
return 'campaignevent_sendwebhook';
}
}

View File

@@ -0,0 +1,89 @@
<?php
namespace Mautic\WebhookBundle\Form\Type;
use Doctrine\Common\Collections\Order;
use Mautic\CoreBundle\Form\DataTransformer\ArrayLinebreakTransformer;
use Mautic\CoreBundle\Form\Type\YesNoButtonGroupType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
/**
* @extends AbstractType<array<mixed>>
*/
class ConfigType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->add('queue_mode', ChoiceType::class, [
'choices' => [
'mautic.webhook.config.immediate_process' => 'immediate_process',
'mautic.webhook.config.cron_process' => 'command_process',
],
'label' => 'mautic.webhook.config.form.queue.mode',
'attr' => [
'class' => 'form-control',
'tooltip' => 'mautic.webhook.config.form.queue.mode.tooltip',
],
'placeholder' => false,
'constraints' => [
new NotBlank(
[
'message' => 'mautic.core.value.required',
]
),
],
]);
$builder->add('events_orderby_dir', ChoiceType::class, [
'choices' => [
'mautic.webhook.config.event.orderby.chronological' => Order::Ascending->value,
'mautic.webhook.config.event.orderby.reverse.chronological' => Order::Descending->value,
],
'label' => 'mautic.webhook.config.event.orderby',
'attr' => [
'class' => 'form-control',
'tooltip' => 'mautic.webhook.config.event.orderby.tooltip',
],
'required' => false,
]);
$builder->add(
'webhook_email_details',
YesNoButtonGroupType::class,
[
'label' => 'mautic.webhook.config.email.details',
'data' => (bool) ($options['data']['webhook_email_details'] ?? null),
'attr' => [
'class' => 'form-control',
'tooltip' => 'mautic.webhook.config.email.details.tooltip',
],
]
);
$builder->add(
$builder->create(
'webhook_allowed_private_addresses',
TextareaType::class,
[
'label' => 'mautic.webhook.config.allowed_private_addresses',
'label_attr' => ['class' => 'control-label'],
'attr' => [
'class' => 'form-control',
'tooltip' => 'mautic.webhook.config.allowed_private_addresses.tooltip',
'rows' => 8,
],
'required' => false,
]
)->addViewTransformer(new ArrayLinebreakTransformer())
);
}
public function getBlockPrefix(): string
{
return 'webhookconfig';
}
}

View File

@@ -0,0 +1,155 @@
<?php
namespace Mautic\WebhookBundle\Form\Type;
use Doctrine\Common\Collections\Order;
use Mautic\CategoryBundle\Form\Type\CategoryListType;
use Mautic\CoreBundle\Form\EventListener\CleanFormSubscriber;
use Mautic\CoreBundle\Form\Type\FormButtonsType;
use Mautic\CoreBundle\Form\Type\YesNoButtonGroupType;
use Mautic\CoreBundle\Helper\EncryptionHelper;
use Mautic\WebhookBundle\Entity\Webhook;
use Mautic\WebhookBundle\Form\DataTransformer\EventsToArrayTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\UrlType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* @extends AbstractType<Webhook>
*/
class WebhookType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder->addEventSubscriber(new CleanFormSubscriber(['description' => 'strict_html']));
/** @var Webhook $webhook */
$webhook = $builder->getData();
$builder->add(
'name',
TextType::class,
[
'label' => 'mautic.core.name',
'label_attr' => ['class' => 'control-label'],
'attr' => ['class' => 'form-control'],
'required' => true,
]
);
$builder->add(
'description',
TextareaType::class,
[
'label' => 'mautic.webhook.form.description',
'required' => false,
'attr' => [
'class' => 'form-control',
],
]
);
$builder->add(
'webhookUrl',
UrlType::class,
[
'label' => 'mautic.webhook.form.webhook_url',
'label_attr' => ['class' => 'control-label'],
'attr' => ['class' => 'form-control'],
'required' => true,
]
);
$builder->add(
'secret',
TextType::class,
[
'label' => 'mautic.webhook.form.secret',
'label_attr' => ['class' => 'control-label'],
'attr' => [
'class' => 'form-control',
'tooltip' => 'mautic.webhook.secret.tooltip',
],
'data' => $webhook->getSecret() ?? EncryptionHelper::generateKey(),
'required' => false,
]
);
$events = $options['events'];
$choices = [];
foreach ($events as $type => $event) {
$choices[$event['label']] = $type;
}
$builder->add(
'events',
ChoiceType::class,
[
'choices' => $choices,
'multiple' => true,
'expanded' => true,
'label' => 'mautic.webhook.form.webhook.events',
'label_attr' => ['class' => 'control-label'],
'attr' => ['class' => ''],
]
);
$builder->get('events')->addModelTransformer(new EventsToArrayTransformer($options['data']));
$builder->add('buttons', FormButtonsType::class);
$builder->add(
'sendTest',
ButtonType::class,
[
'attr' => ['class' => 'btn btn-tertiary', 'onclick' => 'Mautic.sendHookTest(this)'],
'label' => 'mautic.webhook.send.test.payload',
]
);
$builder->add(
'category',
CategoryListType::class,
[
'bundle' => 'Webhook',
]
);
$builder->add('isPublished', YesNoButtonGroupType::class);
$builder->add(
'eventsOrderbyDir',
ChoiceType::class,
[
'choices' => [
'mautic.webhook.config.event.orderby.chronological' => Order::Ascending->value,
'mautic.webhook.config.event.orderby.reverse.chronological' => Order::Descending->value,
],
'label' => 'mautic.webhook.config.event.orderby',
'attr' => [
'class' => 'form-control',
'tooltip' => 'mautic.webhook.config.event.orderby.tooltip',
],
'placeholder' => 'mautic.core.form.default',
'required' => false,
]
);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults(
[
'data_class' => Webhook::class,
]
);
$resolver->setDefined(['events']);
}
}