src/Products/NotificationsBundle/Form/Forms/Messages/MessageDataForm.php line 90

Open in your IDE?
  1. <?php
  2. namespace Products\NotificationsBundle\Form\Forms\Messages;
  3. use App\Form\Type\ReactMediaManagerType;
  4. use App\Form\Type\TextareaCounterType;
  5. use App\Util\Json;
  6. use Cms\CoreBundle\Util\Doctrine\EntityManager;
  7. use Products\NotificationsBundle\Entity\AbstractList;
  8. use Products\NotificationsBundle\Entity\Notifications\Channels\ChannelsInterface;
  9. use Products\NotificationsBundle\Entity\Notifications\Message;
  10. use Products\NotificationsBundle\Form\Type\FancyEntityType;
  11. use Products\NotificationsBundle\Form\Type\ReactVoiceRecorderType;
  12. use Products\NotificationsBundle\Form\Type\RichTextType;
  13. use Products\NotificationsBundle\Form\Type\SourceTextType;
  14. use Symfony\Component\Form\AbstractType;
  15. use Symfony\Component\Form\Extension\Core\Type\HiddenType;
  16. use Symfony\Component\Form\Extension\Core\Type\TextareaType;
  17. use Symfony\Component\Form\FormBuilderInterface;
  18. use Symfony\Component\Form\FormEvent;
  19. use Symfony\Component\Form\FormEvents;
  20. use Symfony\Component\OptionsResolver\OptionsResolver;
  21. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  22. use Symfony\Component\Validator\Constraints\Length;
  23. use Symfony\Component\Validator\Constraints\NotBlank;
  24. /**
  25.  * Class MessageDataForm
  26.  * @package Products\NotificationsBundle\Form\Forms\Messages
  27.  */
  28. final class MessageDataForm extends AbstractType
  29. {
  30.     // TODO: this needs handled a different way...
  31.     private const SMS_LENGTH 160;
  32.     private const URL_LENGTH 21;
  33.     private const SPACING_LENGTH 1;
  34.     private const HEADER_LENGTH 0;
  35.     public const MAX_LENGTH self::SMS_LENGTH self::HEADER_LENGTH self::SPACING_LENGTH self::URL_LENGTH;
  36.     /**
  37.      * @var EntityManager
  38.      */
  39.     protected EntityManager $em;
  40.     /**
  41.      * @var AuthorizationCheckerInterface
  42.      */
  43.     private AuthorizationCheckerInterface $authorizationChecker;
  44.     /**
  45.      * @param EntityManager $em
  46.      * @param AuthorizationCheckerInterface $authorizationChecker
  47.      */
  48.     public function __construct(
  49.         EntityManager $em,
  50.         AuthorizationCheckerInterface $authorizationChecker
  51.     )
  52.     {
  53.         $this->em $em;
  54.         $this->authorizationChecker $authorizationChecker;
  55.     }
  56.     /**
  57.      * {@inheritDoc}
  58.      */
  59.     public function buildForm(FormBuilderInterface $builder, array $options): void
  60.     {
  61.         /** @var Message $message */
  62.         $message $builder->getData();
  63.         $descriptionType RichTextType::class;
  64.         if ($message->isHtml()) {
  65.             $descriptionType SourceTextType::class;
  66.         }
  67.         $prefillParams $options['prefillParams'] ?? [];
  68.         $builder
  69.             ->add('prefillParams'HiddenType::class, [
  70.                 'data' => Json::encode($prefillParams),
  71.                 'mapped' => false,
  72.             ])
  73.             ->add('lists'FancyEntityType::class, [
  74.                 'class' => AbstractList::class,
  75.                 'multiple' => true,
  76.                 'choices' => array_filter(
  77.                     $this->em->getRepository(AbstractList::class)->findAll(),
  78.                     function($list) use ($message) {
  79.                         return $this->authorizationChecker->isGranted(
  80.                             sprintf(
  81.                                 'app.notifications.messaging.%s',
  82.                                 $message->isUrgent() ? 'urgent' 'general',
  83.                             ),
  84.                             $list,
  85.                         );
  86.                     },
  87.                 ),
  88.                 'choice_label' => 'name',
  89.                 'label_tooltip' => 'Select the list(s) you would like to send to.',
  90.             ])
  91.             ->add('title'TextareaCounterType::class, [
  92.                 'label_tooltip' => 'Be concise but thorough. The content in this field will be sent as a text message. <a target="_blank" href="https://help.schoolnow.com/kb/send-a-new-broadcast">Learn more.</a>',
  93.                 'limit' => self::MAX_LENGTH,
  94.                 'constraints' => [
  95.                     new NotBlank(),
  96.                     new Length([
  97.                         'max' => self::MAX_LENGTH,
  98.                     ]),
  99.                 ],
  100.             ])
  101.             ->add('description'$descriptionType, [
  102.                 'label_tooltip' => 'The content entered here will be the body of the email and also set up as a web page text recipients can click to.',
  103.                 'required' => true,
  104.                 'constraints' => [
  105.                     new NotBlank(
  106.                         ['message' => 'Details field should not be blank.']
  107.                     ),
  108.                 ],
  109.             ])
  110.             ->add('forceTranslation'HiddenType::class, [
  111.                 'mapped' => false,
  112.                 'required' => false,
  113.                 'data' => '0',
  114.                 'attr' => [
  115.                     'class' => 'force-translation',
  116.                 ],
  117.             ])
  118.             ->add('media'ReactMediaManagerType::class, [
  119.                 'label_tooltip' => 'Select a message header image. <a target="_blank" href="https://help.schoolnow.com/kb/what-are-the-ideal-image-header-sizes-to-use-for-outgoing-messages">View recommended sizes</a>',
  120.                 'limit' => 1,
  121.             ])
  122.             ->addEventListener(FormEvents::PRE_SUBMIT, [$this'onPreSubmit'])
  123.             ->addEventListener(FormEvents::POST_SUBMIT, [$this'onPostSubmit']);
  124.         if ($message->isUrgent()) {
  125.             $builder
  126.                 ->add('script'TextareaType::class, [
  127.                     'attr' => ['rows' => 4],
  128.                     'label_tooltip' => 'Voice is only available for urgent messages. Choose how you will create your voice message.',
  129.                     'required' => false,
  130.                     'constraints' => [
  131.                         new NotBlank(
  132.                             ['message' => 'Please add a voice transcription for both voice message generation and translation services to be performed.']
  133.                         ),
  134.                     ],
  135.                 ])
  136.                 ->add('recording'ReactVoiceRecorderType::class, [
  137.                     'required' => true,
  138.                     'label_tooltip' => false,
  139.                     'label' => false,
  140.                     'constraints' => [
  141.                         new NotBlank(
  142.                             ['message' => 'Recording is missing. Click "Convert text to speech" or add a recording.']
  143.                         ),
  144.                     ],
  145.                 ]);
  146.             $builder->addEventSubscriber(new ScriptChangeDetectionListener());
  147.         }
  148.     }
  149.     /**
  150.      * @param FormEvent $event
  151.      * @return void
  152.      */
  153.     public function onPreSubmit(FormEvent $event): void
  154.     {
  155.         /** @var Message $message */
  156.         $message $event->getData();
  157.         if ( ! $message) {
  158.             return;
  159.         }
  160.         if ((isset($message['html']) && (bool)$message['html'] === false) || empty($message['description_html'])) {
  161.             return;
  162.         }
  163.         $message['description'] = $message['description_html'];
  164.         $event->setData($message);
  165.     }
  166.     /**
  167.      * @param FormEvent $event
  168.      * @return void
  169.      */
  170.     public function onPostSubmit(FormEvent $event): void
  171.     {
  172.         $message $event->getData();
  173.         if ( ! $message instanceof Message) {
  174.             return;
  175.         }
  176.         if ($message->getMedia()->count() > 0) {
  177.             return;
  178.         }
  179.         $message->removeChannel(ChannelsInterface::CHANNELS__INSTAGRAM);
  180.         $event->setData($message);
  181.     }
  182.     public function configureOptions(OptionsResolver $resolver): void
  183.     {
  184.         parent::configureOptions($resolver);
  185.         $resolver->setDefaults([
  186.             'prefillParams' => null,
  187.         ]);
  188.     }
  189. }