<?php
namespace Platform\ControlPanelBundle\Form;
use App\Validator\Constraints\RRule;
use Cms\CoreBundle\Entity\OneRosterSync;
use Cms\CoreBundle\Form\Type\ChosenChoiceType;
use Cms\CoreBundle\Service\OneRoster\AbstractOneRosterApi;
use DateTimeZone;
use Exception;
use InvalidArgumentException;
use Recurr\Rule;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
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\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Validator\Constraints\NotBlank;
/**
* Class OneRosterSyncType
* @package Platform\ControlPanelBundle\Form
*/
final class OneRosterSyncType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('vendor', ChoiceType::class, [
'expanded' => false,
'multiple' => false,
'required' => true,
'placeholder' => 'Select vendor...',
'empty_data' => null,
'choices' => AbstractOneRosterApi::VENDORS,
'choice_label' => function ($value, $key) {
return $value;
},
'choice_value' => function ($value) {
return $value;
},
])
->add('apiClientId', TextType::class, [
'constraints' => [
new NotBlank(),
],
])
->add('apiClientSecret', TextType::class, [
'constraints' => [
new NotBlank(),
],
])
->add('apiAppName', TextType::class, [
'required' => false,
])
->add('baseUri', TextType::class, [
'required' => false,
])
->add('districtId', TextType::class, [
'constraints' => [
new NotBlank(),
],
])
->add('strategies', ChosenChoiceType::class, [
'expanded' => false,
'multiple' => true,
'required' => false,
'choices' => OneRosterSync::STRATEGIES,
// 'choice_translation_domain' => 'CmsCoreBundle',
'choice_label' => function ($value, $key) {
return sprintf(
'app.oneroster.syncs.strategies.labels.%s',
$key
);
},
'choice_value' => function ($value) {
return $value;
},
])
->add('flags', ChosenChoiceType::class, [
'expanded' => false,
'multiple' => true,
'required' => false,
'choices' => OneRosterSync::FLAGS,
// 'choice_translation_domain' => 'CmsCoreBundle',
'choice_label' => function ($value, $key) {
return sprintf(
'app.oneroster.syncs.flags.labels.%s',
$key
);
},
'choice_value' => function ($value) {
return $value;
},
])
->add('schedule', TextareaType::class, [
'required' => false,
'label_tooltip' => true,
'constraints' => [
new RRule(),
],
'attr' => [
'rows' => 2,
'style' => 'height: auto;',
],
]);
$builder->get('strategies')->addModelTransformer(
new CallbackTransformer(
function (int $masks) {
$data = [];
foreach (OneRosterSync::STRATEGIES as $mask) {
if (($masks & $mask) > 0) {
$data[] = $mask;
}
}
return $data;
},
function (array $masks) {
return array_reduce(
$masks,
function (int $carry, int $mask) {
return $carry | $mask;
},
0
);
}
)
);
$builder->get('flags')->addModelTransformer(
new CallbackTransformer(
function (int $masks) {
$data = [];
foreach (OneRosterSync::FLAGS as $mask) {
if (($masks & $mask) > 0) {
$data[] = $mask;
}
}
return $data;
},
function (array $masks) {
return array_reduce(
$masks,
function ($carry, $mask) {
return ($carry | $mask);
},
0
);
}
)
);
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
/** @var OneRosterSync $oneRosterSync */
$oneRosterSync = $event->getData();
$timezone = new DateTimeZone('UTC');
try {
if (empty($oneRosterSync->getSchedule())) {
$oneRosterSync->setNextRunAt(null, null, $timezone);
return;
}
try {
new Rule($oneRosterSync->getSchedule());
} catch (Exception $exception) {
return;
}
$oneRosterSync->setNextRunAt(true, null, $timezone);
} catch (InvalidArgumentException $exception) {
$oneRosterSync->setNextRunAt(null, null, $timezone);
}
});
}
}