<?php
/**
* Created by simpson <simpsonwork@gmail.com>
* Date: 2019-04-29
* Time: 18:49
*/
namespace App\Form;
use AngelGamez\TranslatableBundle\Entity\TranslatableValue;
use App\Entity\ClientTypes;
use App\Entity\Location\City;
use App\Entity\Location\Station;
use App\Entity\Profile\Confirmation\ApprovalRequest;
use App\Entity\Profile\Genders;
use App\Entity\Profile\PersonParameters;
use App\Entity\Profile\Photo;
use App\Entity\Profile\Profile;
use App\Entity\Profile\ProfileService;
use App\Entity\Profile\Video;
use App\Entity\Service;
use App\Entity\ServiceGroups;
use App\Event\UploadedFileModified;
use App\Form\Type\ApartmentsPricingType;
use App\Form\Type\CarPricingType;
use App\Form\Type\ClientRestrictionsType;
use App\Form\Type\ExpressPricingType;
use App\Form\Type\MapCoordinateType;
use App\Form\Type\MessengersType;
use App\Form\Type\PersonParametersType;
use App\Form\Type\PhoneCallRestrictionsType;
use App\Form\Type\ProvideServicesCollectionType;
use App\Form\Type\TakeOutPricingType;
use App\Repository\ApprovalRequestsRepository;
use App\Repository\CityRepository;
use App\Repository\ServiceRepository;
use App\Service\DefaultCityProvider;
use App\Service\Features;
use App\Service\ImageProcessor;
use App\Service\PhoneNumberService;
use App\Service\EntitySortService;
use App\Service\ProfileAdBoard;
use App\Service\TextUniqueService;
use App\Validator\Constraints\TextIsNotASpam;
use Carbon\CarbonImmutable;
use Cocur\Slugify\SlugifyInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use League\Flysystem\FilesystemOperator;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\Exception;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
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\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\Util\OrderedHashMapIterator;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Constraints\GreaterThan;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
class CreateOrEditProfileForm extends AbstractType implements DataMapperInterface
{
use ProvidedServicesFormTrait;
/** @var Service[] */
private array $services;
private mixed $needToCheckDescriptionIsUnique;
private mixed $originalProfileId = null;
private ?TranslatableValue $originalProfileDescription = null;
private bool $isFake = false;
private ?Profile $profileBeforeFormDataApplied;
public function __construct(
private Features $features,
private DefaultCityProvider $defaultCityProvider,
private CityRepository $cityRepository,
private PhoneNumberService $phoneNumberService,
private ApprovalRequestsRepository $approvalRequestsRepository,
private EntitySortService $sortService,
private ServiceRepository $serviceRepository,
private EntityManagerInterface $entityManager,
private TextUniqueService $textUniqueService,
private EventDispatcherInterface $eventDispatcher,
private ProfileAdBoard $profileAdBoard,
private SlugifyInterface $slugify,
private FilesystemOperator $profileMediaFilesystem,
private FilesystemOperator $profileMediaSelfieFilesystem,
private ImageProcessor $imageProcessor,
private ParameterBagInterface $parameterBag,
)
{
$this->services = $serviceRepository->findAll();
}
public function setIsFake(bool $fake): void
{
$this->isFake = $fake;
}
/**
* @inheritDoc
*/
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$this->isFake = $options['is_fake'] ?? false;
/** @var City $defaultCity */
$defaultCity = $options['default_city'];
$this->needToCheckDescriptionIsUnique = $options['check_description_is_unique'] ?? false;
if (is_array($options['original_profile_data'])) {
$this->originalProfileId = $options['original_profile_data']['id'] ?? null;
$this->originalProfileDescription = $options['original_profile_data']['description'] ?? null;
}
if ($this->features->multiple_cities()) {
$countryCode = $defaultCity->getCountryCode();
$builder->add('city', EntityType::class, [
'class' => City::class,
'choice_label' => 'name',
'choice_attr' => function (City $city): array {
$mapCoordinate = $city->getMapCoordinate();
if (!$mapCoordinate) {
return [];
}
return [
'data-latitude' => $mapCoordinate->getLatitude(),
'data-longitude' => $mapCoordinate->getLongitude(),
];
},
'query_builder' => function (EntityRepository $repository) use ($countryCode) {
return $repository->createQueryBuilder('city')
->andWhere('city.countryCode = :countryCode')
->setParameter('countryCode', $countryCode);
},
]);
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($defaultCity): void {
$form = $event->getForm();
/** @var Profile $profile */
$profile = $event->getData();
if (!$profile || $profile->isDraft()) {
$form->get('city')->setData($defaultCity);
}
});
}
$builder->add('map_coordinate', MapCoordinateType::class, [
'required' => false,
]);
$builder->add('stations', EntityType::class, [
'required' => false,
'multiple' => true,
'class' => Station::class,
'choice_label' => 'name',
'choice_attr' => function (Station $station): array {
return [
'data-city' => $station->getCity()->getId(),
];
},
'query_builder' => function (EntityRepository $repository) {
$qb = $repository->createQueryBuilder('station');
$this->sortService->modifyQueryBuilderToSortByCurrentTranslation($qb, 'station', 'name');
return $qb;
},
'constraints' => [
new Callback(function ($object, ExecutionContextInterface $context, $payload): void {
if (!empty($object) && count($object) > 3) {
$context->buildViolation('Max 3 stations can be chosen')
->atPath('stations')
->addViolation();
}
}),
],
]);
$builder->add('primary_station', HiddenType::class, [
'mapped' => false,
'required' => false,
]);
$builder->add('provided_services', ProvideServicesCollectionType::class, [
'attr' => [
'masseur_exclude_service_groups' => implode(',', [
ServiceGroups::SEX, ServiceGroups::EXTREME, ServiceGroups::BDSM, ServiceGroups::MISC,
]),
],
]);
if ($this->features->extended_profile_form()) {
$builder->add('client_types', ChoiceType::class, [
'required' => false,
'multiple' => true,
'expanded' => true,
'choices' => ClientTypes::getList(),
]);
}
$builder->add('name', TextType::class, [
'constraints' => [
new NotNull(),
new NotBlank(),
],
]);
if ($this->features->has_profile_translations() && $this->features->has_translations()) {
$builder->add('name_en', TextType::class, [
'constraints' => [
new NotNull(),
new NotBlank(),
],
]);
}
$aboutConstraints = [
new NotNull(),
new NotBlank(),
new Length(['min' => 100]),
];
if ($this->features->check_description_unique()) {
$aboutConstraints[] = new TextIsNotASpam();
}
$builder->add('about', TextareaType::class, [
'constraints' => $aboutConstraints,
]);
if ($this->features->has_profile_translations() && $this->features->has_translations()) {
$builder->add('about_en', TextareaType::class, [
'constraints' => $aboutConstraints,
]);
}
if ($this->features->has_masseurs()) {
$builder->add('is_masseur', CheckboxType::class, [
'required' => false,
]);
}
$builder->add('person_parameters', PersonParametersType::class);
$builder->add('phone_number', TextType::class, [
'constraints' => [
new NotNull(),
new NotBlank(),
],
]);
if ($this->features->extended_profile_form()) {
$builder->add('messengers', MessengersType::class);
}
$builder->add('phone_call_restrictions', PhoneCallRestrictionsType::class);
$builder->add('client_restrictions', ClientRestrictionsType::class);
if ($this->features->crop_avatar()) {
$builder->add('avatar', HiddenType::class, [
'required' => true,
'constraints' => [
new NotNull(),
new NotBlank(),
],
]);
}
$photosConstraints = $this->features->crop_avatar() ? [] : [
new Callback(function ($object, ExecutionContextInterface $context, $payload): void {
if (empty($object)) {
$context->buildViolation('At least 1 photo should be uploaded')
->atPath('photos')
->addViolation();
}
}),
];
$builder->add('photos', CollectionType::class, [
'entry_type' => HiddenType::class,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'constraints' => $photosConstraints,
]);
if (false == $this->features->crop_avatar()) {
$builder->add('main_photo', HiddenType::class, [
'required' => true,
'constraints' => [
new NotNull(),
new NotBlank(),
],
]);
}
if ($this->features->extended_profile_form()) {
$builder->add('selfies', CollectionType::class, [
'entry_type' => HiddenType::class,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
]);
}
$builder->add('videos', CollectionType::class, [
'entry_type' => HiddenType::class,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
]);
$builder->add('media_params', HiddenType::class, [
'required' => false,
]);
$builder->add('apartments_pricing', ApartmentsPricingType::class, [
'required' => false,
]);
$builder->add('take_out_pricing', TakeOutPricingType::class, [
'required' => false,
]);
if (false == $this->features->extended_profile_form()) {
$builder->add('extra_charge', NumberType::class, [
'required' => false,
'constraints' => new GreaterThan(0),
]);
}
if ($this->features->extended_profile_form()) {
$builder->add('express_pricing', ExpressPricingType::class, [
'required' => false,
]);
$builder->add('car_pricing', CarPricingType::class, [
'required' => false,
]);
}
//TODO feature dependent!!!!!
//approval photo - see ProfileEditingController
if (false === 1) {
$builder->add('approval_photo', FileType::class, [
'label' => 'Upload your photo for profile approval',
'required' => false,
]);
} else {
$builder->add('approval_photo', CollectionType::class, [
'entry_type' => HiddenType::class,
'allow_add' => true,
'allow_delete' => true,
'delete_empty' => true,
'label' => 'Upload your photo for profile approval',
'required' => false,
]);
}
$builder->add('approval_status', HiddenType::class)->get('approval_status')->setData(null);
$builder->add('uploaded_approval_photo', HiddenType::class);
//end approval
$builder->add('submit', SubmitType::class);
$builder->addEventListener(FormEvents::POST_SUBMIT, [$this, 'onPostSubmit']);
$builder->setDataMapper($this);
}
/**
* @inheritDoc
*/
public function buildView(FormView $view, FormInterface $form, array $options): void
{
if (null === $form->getData() && $form->has('is_masseur')) {
// Отметка чекбокса массажистки в форме создания анкеты
$form->get('is_masseur')->setData($options['precheck_masseur']);
}
}
/**
* @inheritDoc
*/
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setRequired('default_city');
$resolver->setAllowedTypes('default_city', City::class);
$resolver->setDefined('precheck_masseur');
$resolver->setAllowedTypes('precheck_masseur', 'bool');
$resolver->setDefined('check_description_is_unique');
$resolver->setAllowedTypes('check_description_is_unique', 'bool');
$resolver->setDefined('original_profile_data');
$resolver->setDefined('is_fake');
$resolver->setAllowedTypes('is_fake', 'bool');
$resolver->setDefaults([
'data_class' => Profile::class,
'empty_data' => null,
'precheck_masseur' => false,
'allow_extra_fields' => true,
'check_description_is_unique' => true,
'original_profile_data' => null,
'is_fake' => false,
]);
}
/**
* @inheritDoc
*/
public function mapDataToForms($profile, $forms)
{
/** @var FormInterface[] $forms */
$forms = iterator_to_array($forms);
/** @var Profile $profile */
$forms['provided_services']->setData(
$this->serviceToProvideOptionsList(
$this->serviceRepository,
null !== $profile ? $profile->getProvidedServices()->toArray() : null
)
);
if (null === $profile) {
return null;
}
if (!$profile instanceof Profile) {
throw new Exception\UnexpectedTypeException($profile, Profile::class);
}
if (isset($forms['city'])) {
$forms['city']->setData($profile->getCity());
}
$forms['map_coordinate']->setData($profile->getMapCoordinate());
$forms['stations']->setData($profile->getStations());
$forms['primary_station']->setData(
$profile->getPrimaryStation()?->getId()
);
if ($this->features->extended_profile_form()) {
$forms['client_types']->setData($profile->getClientTypes());
}
$forms['name']->setData($profile->getName()->getTranslation('ru'));
$forms['about']->setData($profile->getDescription()->getTranslation('ru'));
if (isset($forms['is_masseur'])) {
$forms['is_masseur']->setData($profile->isMasseur());
}
$forms['person_parameters']->setData($profile->getPersonParameters());
// $phoneNumberInternational = $this->phoneNumberService->getInternationalNumber($profile->getPhoneNumber(), $profile->getCity());
$forms['phone_number']->setData($profile->getPhoneNumber());
if ($this->features->extended_profile_form()) {
$forms['messengers']->setData($profile->getMessengers());
}
$forms['phone_call_restrictions']->setData($profile->getPhoneCallRestrictions());
$forms['client_restrictions']->setData($profile->getClientRestrictions());
$forms['apartments_pricing']->setData($profile->getApartmentsPricing());
$forms['take_out_pricing']->setData($profile->getTakeOutPricing());
if (false == $this->features->extended_profile_form()) {
$forms['extra_charge']->setData($profile->getExtraCharge());
}
if ($this->features->extended_profile_form()) {
$forms['car_pricing']->setData($profile->getCarPricing());
$forms['express_pricing']->setData($profile->getExpressPricing());
}
if ($this->features->crop_avatar()) {
if ($profile->getAvatar()) {
$forms['avatar']->setData($profile->getAvatar()->getPath());
}
}
$videoPaths = array_map(function (Video $video): string {
return $video->getPath();
}, $profile->getVideos()->toArray());
$forms['videos']->setData($videoPaths);
$photoPaths = array_map(function (Photo $photo): string {
return $photo->getPath();
}, $profile->getPhotos()->toArray());
$forms['photos']->setData($photoPaths);
if (false == $this->features->crop_avatar()) {
if (null !== $mainPhoto = $profile->getMainPhoto()) {
$forms['main_photo']->setData($mainPhoto->getPath());
}
}
if ($this->features->extended_profile_form()) {
$photoPaths = array_map(function (Photo $photo): string {
return $photo->getPath();
}, $profile->getSelfies()->toArray());
$forms['selfies']->setData($photoPaths);
}
$approvalRequest = $this->approvalRequestsRepository->getByProfile($profile);
$approvalMedia = $approvalRequest ? ($this->features->approval_by_video() ? $approvalRequest->getVideo() : $approvalRequest->getPhoto()) : null;
if ($approvalRequest && $approvalRequest->isApproved() == false && $approvalMedia) {
$forms['uploaded_approval_photo']->setData($approvalMedia->getPath());
}
$forms['approval_status']->setData(
$approvalRequest && ($approvalRequest->isWaiting() || $approvalRequest->isRejected())
? $approvalRequest->getStatus()
: ($profile->isApproved() ? ApprovalRequest::STATUS_APPROVED : null)
);
if ($this->features->has_profile_translations() && $this->features->has_translations()) {
$forms['name_en']->setData($profile->getName()->getTranslation('en'));
$forms['about_en']->setData($profile->getDescription()->getTranslation('en'));
}
}
/**
* @inheritDoc
*/
public function mapFormsToData($forms, &$profile): void
{
/** @var FormInterface[] $forms */
$forms = iterator_to_array($forms);
if (!$profile instanceof Profile) {
$profile = Profile::draft(CarbonImmutable::now());
}
$this->profileBeforeFormDataApplied = clone $profile;
//dump($profile->getAdBoardPlacement(), isset($data['is_masseur']), $profile->isMasseur());die;
if (
$profile->getAdBoardPlacement()
&& (
(!isset($forms['is_masseur']) && $profile->isMasseur())
|| (isset($forms['is_masseur']) && $profile->isMasseur() != (bool)$forms['is_masseur']->getData())
)
) {
$this->profileAdBoard->doRemoveFromAdBoard($profile);
}
if (isset($forms['is_masseur'])) {
$isMasseur = (bool)$forms['is_masseur']->getData();
$profile->toggleMasseur($isMasseur);
} else {
$profile->toggleMasseur(false);
}
$name = (new TranslatableValue())->ru($forms['name']->getData());
$description = (new TranslatableValue())->ru($forms['about']->getData() ?? '');
if ($this->features->has_profile_translations() && $this->features->has_translations()) {
$name = $name->en($forms['name_en']->getData());
$description = $description->en($forms['about_en']->getData() ?? '');
}
if (!$this->slugify->slugify($name)) {
$forms['name']->addError(new FormError('Введите имя.'));
}
$profile->setBio($name, $description);
if (isset($forms['city'])) {
$city = $forms['city']->getData();
} else {
$city = $this->defaultCityProvider->getDefaultCity();
}
/** @var ArrayCollection $stations */
$stations = $forms['stations']->getData();
$stations = $stations->filter(function ($station) use ($city): bool {
return $station->getCity()->getId() == $city->getId();
});
$profile->setLocation(
$city,
$stations,
$forms['map_coordinate']->getData()
);
$primaryStationId = $forms['primary_station']->getData();
if ($primaryStationId) {
foreach ($stations as $station) {
if ((string)$station->getId() === (string)$primaryStationId) {
$profile->setPrimaryStation($station);
break;
}
}
}
/** @var PersonParameters $personParametersFormData */
$personParametersFormData = $forms['person_parameters']->getData();
if (false == $profile->isDraft() && isset($forms['person_parameters']['gender'])) {
//при редактировании хоязину нельзя менять пол анкеты
if ($personParametersFormData->getGender() != $profile->getPersonParameters()->getGender()) {
$personParametersFormData->setGender($profile->getPersonParameters()->getGender());
}
}
$profile->setPersonParameters($personParametersFormData);
if ($city != $this->defaultCityProvider->getDefaultCity()) {
$profile->getPersonParameters()->setGender(Genders::FEMALE);
}
if ($profile->getPersonParameters()->getGender() != Genders::FEMALE) {
$profile->toggleMasseur(false);
}
$this->serviceToProvideOptionsToProvidedServices($profile, $forms['provided_services']->getData(), ProfileService::class, $this->serviceRepository);
if ($this->features->extended_profile_form()) {
$profile->setClientTypes($forms['client_types']->getData() ?? []);
}
$phoneNumber = $forms['phone_number']->getData();
$phoneNumber = $this->phoneNumberService->getInternationalNumber($phoneNumber, $city);
if (null !== $phoneNumber) {
$profile->setPhoneCallOptions(
$phoneNumber,
$forms['phone_call_restrictions']->getData(),
$this->features->extended_profile_form() ? $forms['messengers']->getData() : null
);
}
$profile->setClientRestrictions($forms['client_restrictions']->getData());
$profile->setPricing(
$forms['apartments_pricing']->getData(),
$forms['take_out_pricing']->getData(),
false == $this->features->extended_profile_form() ? $forms['extra_charge']->getData() : null,
$this->features->extended_profile_form() ? $forms['express_pricing']->getData() : null,
$this->features->extended_profile_form() ? $forms['car_pricing']->getData() : null
);
if ($this->features->crop_avatar()) {
if ($avatarPath = $forms['avatar']->getData()) {
if (!$profile->getAvatar() || $avatarPath != $profile->getAvatar()->getPath()) {
if ($profile->getAvatar())
$this->entityManager->remove($profile->getAvatar());
$profile->setAvatar($avatarPath);
}
}
}
$videoPaths = $forms['videos']->getData();
if (is_array($videoPaths)) {
$existingVideoPaths = $profile->getVideos()->map(function (Video $video): string {
return $video->getPath();
})->getValues();
$videoPathsToAdd = array_diff($videoPaths, $existingVideoPaths);
$videoPathsToRemove = array_diff($existingVideoPaths, $videoPaths);
// Новые загруженные видео добавляются в отдельную очередь для последующей обработки
foreach ($videoPathsToAdd as $videoPath) {
$profile->addRawVideo($videoPath);
}
foreach ($videoPathsToRemove as $videoPath) {
$profile->removeVideo($videoPath);
}
}
$photoPaths = $forms['photos']->getData();
if (is_array($photoPaths)) {
$existingPhotoPaths = $profile->getPhotos()->map(function (Photo $photo): string {
return $photo->getPath();
})->getValues();
$photoPathsToAdd = array_diff($photoPaths, $existingPhotoPaths);
$photoPathsToRemove = array_diff($existingPhotoPaths, $photoPaths);
foreach ($photoPathsToAdd as $photoPath)
$profile->addPhoto($photoPath, false);
foreach ($photoPathsToRemove as $photoPath)
$profile->removePhoto($photoPath);
$photoPathsActual = array_diff($photoPaths, $photoPathsToRemove);
if (false === $this->isFake) {
//апдейтим позиции
ksort($photoPathsActual);
$photoPathsActual = array_values($photoPathsActual);
$i = 0;
foreach ($profile->getPhotos() as $k => $photo) {
if ($photoPathsActual[$i] != $photo->getPath()) {
$photo->setPath($photoPathsActual[$i]);
}
$i++;
}
}
}
if (false == $this->features->crop_avatar()) {
if (null !== $mainPhoto = $forms['main_photo']->getData()) {
$profile->changeMainPhoto($mainPhoto);
}
}
if ($this->features->extended_profile_form()) {
$selfiePaths = $forms['selfies']->getData();
if (is_array($selfiePaths)) {
$existingPhotoPaths = $profile->getSelfies()->map(function (Photo $photo): string {
return $photo->getPath();
})->getValues();
$photoPathsToAdd = array_diff($selfiePaths, $existingPhotoPaths);
$photoPathsToRemove = array_diff($existingPhotoPaths, $selfiePaths);
foreach ($photoPathsToAdd as $photoPath) {
$profile->addSelfie($photoPath, false);
}
foreach ($photoPathsToRemove as $photoPath) {
if ($profile->removeSelfie($photoPath)) {
$this->profileMediaSelfieFilesystem->delete($photoPath);
}
}
$photoPathsActual = array_diff($selfiePaths, $photoPathsToRemove);
if (false === $this->isFake) {
//апдейтим позиции
ksort($photoPathsActual);
$photoPathsActual = array_values($photoPathsActual);
$i = 0;
foreach ($profile->getSelfies() as $k => $photo) {
if ($photoPathsActual[$i] != $photo->getPath()) {
$photo->setPath($photoPathsActual[$i]);
}
$i++;
}
}
}
}
if (false === $this->isFake) {
$mediaParams = $forms['media_params']->getData() ?? '[]';
$mediaParams = json_decode($mediaParams, true);
foreach ($mediaParams as $type => $media) {
foreach ($media as $path => $params) {
$this->imageProcessor->rotateImage($path, -1 * $params['rotation'], $this->profileMediaFilesystem);
$this->eventDispatcher->dispatch(new UploadedFileModified($path, $this->parameterBag->get('app.path.media.profile')), UploadedFileModified::NAME);
}
}
}
if (true == $profile->isDraft()) {
$randomPhoneNumber = $this->phoneNumberService->generateRandomPhone();
$profile->setSeoPhoneNumber($randomPhoneNumber);
}
}
/**
* @inheritDoc
*/
public function getBlockPrefix()
{
return '';
}
public function onPostSubmit(FormEvent $event): void
{
$form = $event->getForm();
$profile = $this->profileBeforeFormDataApplied;
if ($this->features->check_description_unique() && $this->needToCheckDescriptionIsUnique) {
if (null == $profile->getDescription()
|| ($this->originalProfileDescription && $profile->getDescription()->getTranslation('ru') != $this->originalProfileDescription->getTranslation('ru'))) {
if (($about = $form->get('about'))->getErrors()->count() == 0) {
$isUnique = null !== $about && $this->textUniqueService->isProfileTextUnique($about->getData() ?? '', $this->originalProfileId ? [$this->originalProfileId] : []);
if (false == $isUnique) {
$form->addError(new FormError('Ваш текст не уникален. Допускаются анкеты только с уникальным описанием. Измените текст.'));
$about->addError(new FormError('Ваш текст не уникален. Допускаются анкеты только с уникальным описанием. Измените текст.'));
}
}
}
if (null == $profile->getDescription()
|| ($this->originalProfileDescription && $profile->getDescription()->getTranslation('en') != $this->originalProfileDescription->getTranslation('en'))) {
if (isset($forms['about_en']) && ($about_en = $form->get('about_en'))->getErrors()->count() == 0) {
$isUnique = null !== $about_en && $this->textUniqueService->isProfileTextUnique($about_en->getData() ?? '', $this->originalProfileId ? [$this->originalProfileId] : []);
if (false == $isUnique) {
$form->addError(new FormError('Ваш текст не уникален. Допускаются анкеты только с уникальным описанием. Измените текст.'));
$about_en->addError(new FormError('Ваш текст не уникален. Допускаются анкеты только с уникальным описанием. Измените текст.'));
}
}
}
}
}
protected function canApplyForApproval(Profile $profile, ?ApprovalRequest $approvalRequest): bool
{
return false == $profile->isApproved()
&& (!$approvalRequest instanceof \App\Entity\Profile\Confirmation\ApprovalRequest || false == $approvalRequest->isWaiting());
}
}
// $builder->add('services', EntityType::class, [
// 'multiple' => true,
// 'expanded' => true,
// 'class' => Service::class,
// 'choice_label' => 'name',
// 'choice_attr' => function (Service $service) {
// return [
// 'service-group' => $service->getGroup(),
// ];
// },
// 'query_builder' => function (EntityRepository $repository) {
// return $repository->createQueryBuilder('service')
// ->addOrderBy('service.group')
// ->addOrderBy('service.id')
// ;
// },
// 'mapped' => false, //???
// ]);