src/StartPlatz/Bundle/RheinlandPitchBundle/Controller/ApplyController.php line 1249

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace App\StartPlatz\Bundle\RheinlandPitchBundle\Controller;
  3. /**
  4.  * CRITICAL DEPENDENCY WARNING - EVENT REGISTRATION SYSTEM
  5.  * 
  6.  * This controller is heavily used by the EventBundle for event registrations.
  7.  * Event registration is the MOST IMPORTANT registration method for events.
  8.  * 
  9.  * DO NOT modify this controller without thoroughly testing event registration functionality.
  10.  * 
  11.  * Key dependencies from EventBundle:
  12.  * - EventBundle/Controller/EventRegistrationController uses this for all internal event registrations
  13.  * - Event registration forms are rendered using templates from this bundle
  14.  * - Application workflow (validation, status management) is shared with events
  15.  * 
  16.  * Critical methods used by events:
  17.  * - applyAction() - Main registration form handling
  18.  * - Form validation and submission logic
  19.  * - Email validation workflows (validateEmail/validateLogin)
  20.  * - Application status management
  21.  * 
  22.  * Templates used by events:
  23.  * - Apply/_edit.registration.event.widget.html.twig
  24.  * - Apply/_edit.registration.widget.html.twig
  25.  * - Apply/apply.default.html.twig (for anonymous access)
  26.  * 
  27.  * IMPORTANT: Event registrations depend on:
  28.  * - Application entity structure
  29.  * - Form field definitions in ApplicationType
  30.  * - Validation logic and error handling
  31.  * - Email confirmation workflows
  32.  * - Member/Team assignment logic
  33.  * 
  34.  * See also:
  35.  * - EventBundle/Controller/EventRegistrationController.php (registration logic, extracted from DefaultController)
  36.  * - StartupBundle/Entity/ApplicationRepository.php (for data operations)
  37.  * - Documentation: /doc/claude-files/application-process.md#event-integration
  38.  */
  39. use App\StartPlatz\Bundle\EventBundle\Entity\Event;
  40. use App\StartPlatz\Bundle\MailmanBundle\ConfirmationMailService;
  41. use App\StartPlatz\Bundle\MailmanBundle\Entity\MailTemplate;
  42. use App\StartPlatz\Bundle\MemberBundle\Entity\Member;
  43. use App\StartPlatz\Bundle\MemberBundle\Entity\MemberTeam;
  44. use App\StartPlatz\Bundle\MemberBundle\Entity\Option;
  45. use App\StartPlatz\Bundle\MemberBundle\Entity\Product;
  46. use App\StartPlatz\Bundle\MemberBundle\Entity\Team;
  47. use App\StartPlatz\Bundle\MetaBundle\Entity\Attribute;
  48. use App\StartPlatz\Bundle\MonsumBundle\Entity\Customer;
  49. use App\StartPlatz\Bundle\StartupBundle\Entity\Reminder;
  50. use App\StartPlatz\Bundle\StartupBundle\Entity\Startup;
  51. use App\StartPlatz\Bundle\WebsiteBundle\MenuTranslationService;
  52. use DateTime;
  53. use Doctrine\ORM\EntityManagerInterface;
  54. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  55. use Speicher210\CloudinaryBundle\Cloudinary\Api;
  56. use Symfony\Component\Mailer\MailerInterface;
  57. use Symfony\Component\Mime\Email;
  58. use Symfony\Component\Routing\Annotation\Route;
  59. use App\StartPlatz\Bundle\FeedbackBundle\CallbackService;
  60. use App\StartPlatz\Bundle\FeedbackBundle\Form\ContentPlainEditorFormType;
  61. use App\StartPlatz\Bundle\StartupBundle\Entity\Application;
  62. use App\StartPlatz\Bundle\StartupBundle\Entity\Batch;
  63. use App\StartPlatz\Bundle\StartupBundle\Entity\Program;
  64. use App\StartPlatz\Bundle\StartupBundle\Form\ApplicationType;
  65. use App\StartPlatz\Bundle\UserBundle\Entity\User;
  66. use App\StartPlatz\Bundle\UserBundle\Form\SetPasswordFormType;
  67. use App\StartPlatz\Bundle\UserBundle\LoginService;
  68. use App\StartPlatz\Bundle\WebsiteBundle\Utility\Utility;
  69. use App\StartPlatz\Ecosystem\Config\Runtime\Service\AlertRecipientService;
  70. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  71. use Symfony\Component\HttpFoundation\Request;
  72. use Symfony\Component\HttpFoundation\Response;
  73. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  74. use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
  75. use Symfony\Component\Stopwatch\Stopwatch;
  76. use Symfony\Component\Validator\Constraints as Assert;
  77. use Symfony\Component\Validator\Validation;
  78. use Twig\Environment;
  79. use Twig\Loader\ArrayLoader;
  80. class ApplyController extends AbstractController
  81. {
  82.     public function __construct(
  83.         private readonly MailerInterface              $mailer,
  84.         private readonly CallbackService              $callbackService,
  85.         private readonly LoginService                 $loginService,
  86.         private readonly UserPasswordEncoderInterface $encoder,
  87.         private readonly MenuTranslationService       $menuTranslationService,
  88.         private readonly ConfirmationMailService      $confirmationMailService,
  89.         private readonly Api                          $cloudinary,
  90.         private readonly Stopwatch                    $stopwatch,
  91.         private readonly EntityManagerInterface       $entityManager,
  92.         private readonly AlertRecipientService       $alertRecipientService,
  93.     ) {
  94.     }
  95.     /*
  96.      * this page uses a collection of bootstrap4 pages
  97.      * https://colorlib.com/wp/template/meetup/
  98.      */
  99.     #[Route('/apply/action/allmeda_application_set-application-done/{applicationId}'name'allmeda_application_set-application-done')]
  100.     /**
  101.      * @IsGranted("ROLE_ADMIN")
  102.      */
  103.     public function setApplicationDoneAction(Request $request$applicationId)
  104.     {
  105.         $em $this->entityManager;
  106.         if (!$redirect json_decode(base64_decode($request->get('redirect')))) {
  107.             $redirect json_decode(json_encode(['path' => 'allmeda_doku_twig-render-mail-from-template''parameters' => []]));
  108.         }
  109.         $application $em->getRepository(Application::class)->findOneBy(['id' => $applicationId]);
  110.         $application $em->getRepository(Application::class)->setApplicationDone($application);
  111.         $application $em->getRepository(Application::class)->setApplication($application);
  112.         return $this->redirect($this->generateUrl($redirect->path, (array)$redirect->parameters));
  113.     }
  114.     #[Route('/apply/action/allmeda_application_set-error-validate-email/{applicationId}'name'allmeda_application_set-error-validate-email')]
  115.     /**
  116.      * @IsGranted("ROLE_ADMIN")
  117.      */
  118.     public function setErrorValidateEmailAction(Request $request$applicationId)
  119.     {
  120.         $em $this->entityManager;
  121.         if (!$redirect json_decode(base64_decode($request->get('redirect')))) {
  122.             $redirect json_decode(json_encode(['path' => 'allmeda_doku_twig-render-mail-from-template''parameters' => []]));
  123.         }
  124.         $application $em->getRepository(Application::class)->findOneBy(['id' => $applicationId]);
  125.         $application $em->getRepository(Application::class)->setApplicationStarted($application);
  126.         $application $em->getRepository(Application::class)->setErrorValidateEmail($application);
  127.         $application $em->getRepository(Application::class)->setApplication($application);
  128.         return $this->redirect($this->generateUrl($redirect->path, (array)$redirect->parameters));
  129.     }
  130.     #[Route('/apply/action/allmeda_application_set-error-validate-login/{applicationId}'name'allmeda_application_set-error-validate-login')]
  131.     /**
  132.      * @IsGranted("ROLE_ADMIN")
  133.      */
  134.     public function setErrorValidateLoginAction(Request $request$applicationId)
  135.     {
  136.         $em $this->entityManager;
  137.         if (!$redirect json_decode(base64_decode($request->get('redirect')))) {
  138.             $redirect json_decode(json_encode(['path' => 'allmeda_doku_twig-render-mail-from-template''parameters' => []]));
  139.         }
  140.         $application $em->getRepository(Application::class)->findOneBy(['id' => $applicationId]);
  141.         $application $em->getRepository(Application::class)->setApplicationStarted($application);
  142.         $application $em->getRepository(Application::class)->setErrorValidateLogin($application);
  143.         $application $em->getRepository(Application::class)->setApplication($application);
  144.         return $this->redirect($this->generateUrl($redirect->path, (array)$redirect->parameters));
  145.     }
  146.     #[Route('/apply/action/list-tests'name'allmeda_startups_batches_test')]
  147.     public function listTestsAction(Request $request)
  148.     {
  149.         /*
  150.          * Program Slug: rheinland-pitch // Batch Slug:
  151.          * Program Slug: startup-tools // Batch Slug: 01-twilio-sms-voice-whatsapp
  152.          * Program Slug: online-circle-sales // Batch Slug: 05-session
  153.          * Program Slug: startplatz-aob // Batch Slug: 01-interesse-an-effzeh-karten
  154.          * Program Slug: feedback-zu-deiner-startup-idee // Batch Slug: 19-sondersitzung-woche-13
  155.          * Program Slug: rheinland-pitch-zuschauer // Batch Slug: 100-jubilaeum
  156.          * Program Slug: membership // Batch Slug: 17041-test-startup-membership
  157.          */
  158.         $tests = [
  159.             'Rheinland-Pitch' => ['batchId' => 283'programSlug' => 'rheinland-pitch''batchSlug' => ''],
  160.             'Feedback' => ['batchId' => 298'programSlug' => 'feedback-zu-deiner-startup-idee''batchSlug' => ''],
  161.             'Startup Tools' => ['batchId' => 269'programSlug' => 'startup-tools''batchSlug' => '01-twilio-sms-voice-whatsapp'],
  162.             'Startup Tools AWS' => ['batchId' => 188'programSlug' => 'startup-tools''batchSlug' => '01-aws'],
  163.             'Online Circle' => ['batchId' => 386'programSlug' => 'online-circle-sales''batchSlug' => 'session-11'],
  164.             'OC Gründerstip.' => ['batchId' => 305'programSlug' => 'online-circle-gruenderstipendium''batchSlug' => '03-session'],
  165.             'RPitch-Zuschauer' => ['batchId' => 123'programSlug' => 'rheinland-pitch-zuschauer''batchSlug' => '100-jubilaeum'],
  166.             'Membership' => ['batchId' => 208'programSlug' => 'membership''batchSlug' => '17041-test-startup-membership'],
  167.             'Membership Trial' => ['batchId' => 360'programSlug' => 'membership''batchSlug' => '16017-cgn-trial-community-membership'],
  168.             'Event' => ['batchId' => 357'programSlug' => 'businessclub-politischer-dialog''batchSlug' => 'spd-08-07-2021'],
  169.             'Sign Up Mentor' => ['batchId' => 391'programSlug' => 'sign-up''batchSlug' => 'mentor-registration-01'],
  170.         ];
  171.         return $this->render('@StartPlatzRheinlandPitchBundle/Apply/list-tests.html.twig', [
  172.             'tests' => $tests,
  173.         ]);
  174.     }
  175.     #[Route('/apply/action/run-workflow/{applicationId}'name'apply_action_run-workflow')]
  176.     public function runWorkflow(Request $request$applicationId)
  177.     {
  178.         $em $this->entityManager;
  179.         $responseContent "";
  180.         $application $em->getRepository(Application::class)->find($applicationId);
  181.         $message $em->getRepository(Application::class)->runApplicationDoneWorkflow($application);
  182.         $responseContent "workflow set for application with id={$applicationId} and {$message}";
  183.         $this->addFlash('notice'$responseContent );
  184.         return $this->redirect($this->generateUrl("allmeda_applications_home", ['filter'=>"batchId:{$application->getBatchId()}"]));
  185.     }
  186.     #[Route('/apply/settings'defaults: ['program' => 'example''batch' => 'batch11'])]
  187.     #[Route('/apply/{program}/settings'defaults: ['batch' => 'general'])]
  188.     #[Route('/apply/{program}/{batch}/settings'name'apply_settings')]
  189.     /**
  190.      * @IsGranted("ROLE_ADMIN")
  191.      */
  192.     public function setSettingsAction(Request $request$program$batch)
  193.     {
  194.         $em $this->entityManager;
  195.         $now = new datetime();
  196.         $metaName "settings.program.{$program}.{$batch}";
  197.         if (!$settingsProgram $em->getRepository(Option::class)->getOptionMetaValue($metaName)) {
  198.             if (!$settingsProgram $em->getRepository(Option::class)->getOptionMetaValue($metaName)) {
  199.                 $settingsProgram $this->getSettingsProgramDefault();
  200.                 $em->getRepository(Option::class)->setOptionMetaValueJsonEncoded($metaName"settingsProgram"$settingsProgram);
  201.             }
  202.         }
  203.         $content Utility::transformArrayAssocIntoCsvString($settingsProgram);
  204.         $data['content'] = $content;
  205.         $form $this->createForm(ContentPlainEditorFormType::class, $data);
  206.         $form->handleRequest($request);
  207.         if ($form->isSubmitted() && $form->isValid()) {
  208.             $data $form->getData();
  209.             $importString $data['content'];
  210.             $rows explode(PHP_EOL, (string) $importString);
  211.             foreach ($rows as $row) {
  212.                 $parts str_getcsv($row"\t");
  213.                 $settingsProgram[$parts[0]] = $parts[1];
  214.             }
  215.             $metaName "settings.program.{$settingsProgram['programSlug']}.{$settingsProgram['batchSlug']}";
  216.             $em->getRepository(Option::class)->setOptionMetaValueJsonEncoded($metaNamenull$settingsProgram);
  217.             $this->addFlash('notice''SUCCESS data saved');
  218.             $this->redirect($this->generateUrl('apply_settings', ['program' => $settingsProgram['programSlug'], 'batch' => $settingsProgram['batchSlug']]));
  219.         }
  220.         return $this->render('@StartPlatzRheinlandPitchBundle/Apply/settings.html.twig', [
  221.             'settings' => $settingsProgram,
  222.             'event' => $em->getRepository(Event::class)->findOneBy(['id' => '4982']),
  223.             'form' => $form->createView(),
  224.             'redirectUrl' => base64_encode(json_encode(['path' => 'apply_settings''parameters' => []])),
  225.         ]);
  226.     }
  227.     #[Route('/apply/'name'apply_home')]
  228.     public function indexAction(Request $request)
  229.     {
  230.         $em $this->entityManager;
  231.         $batches $em->getRepository(Batch::class)->findOpenApplications(['programId' => ['1''3''8'], 'visibility' => 'public']);
  232.         return $this->render('@StartPlatzRheinlandPitchBundle/Apply/index.html.twig', [
  233.             'batches' => $batches,
  234.             'redirectUrl' => base64_encode(json_encode(['path' => 'apply_home''parameters' => []])),
  235.         ]);
  236.     }
  237.     #[Route('/apply/{programSlug}'name'apply_program_redirect-to-next-open-application')]
  238.     public function findNextOpenApplicationAction(Request $request$programSlug)
  239.     {
  240.         $em $this->entityManager;
  241.         $test $request->get('test');
  242.         if (!$program $em->getRepository(Program::class /*Startup Program*/)->findOneBy(['slug' => $programSlug])) {
  243.             $this->addFlash('notice''ERROR Sorry, no program found');
  244.             return $this->redirect($this->generateUrl('apply_home', []));
  245.         }
  246.         $sorry "Sorry, no open application for {$program->getName()} right now";
  247.         if ($batch $em->getRepository(Batch::class)->findOpenApplicationsByProgram($program)) {
  248.             if ($test) {
  249.                 return $this->redirect($this->generateUrl('apply_program_home', ['programSlug' => $programSlug'batchSlug' => $batch->getSlug(), 'test' => $test]));
  250.             } else {
  251.                 return $this->redirect($this->generateUrl('apply_program_home', ['programSlug' => $programSlug'batchSlug' => $batch->getSlug()]));
  252.             }
  253.         } else {
  254.             $this->addFlash('notice''ERROR ' $sorry);
  255.             return $this->redirect($this->generateUrl('apply_home', []));
  256.         }
  257.     }
  258.     #[Route('/apply/{programSlug}/{batchSlug}/{id}/monsum-checkout'name'apply_program_monsum-checkout')]
  259.     public function checkoutAction(Request $request$programSlug$batchSlug$id)
  260.     {
  261.         $em $this->entityManager;
  262.         $now = new datetime();
  263.         /** @var User $user */
  264.         $user $this->getUser();
  265.         $em->getRepository(User::class)->writeActivity($user);
  266.         if (!$program $em->getRepository(Program::class /*Startup Program*/)->findOneBy(['slug' => $programSlug])) {
  267.             $this->addFlash('notice''ERROR Sorry, no program found');
  268.             return $this->redirect($this->generateUrl('apply_home', []));
  269.         }
  270.         if (!$batch $em->getRepository(Batch::class)->findOneBy(['slug' => $batchSlug'program' => $program])) {
  271.             $this->addFlash('notice''ERROR Sorry, no batch found');
  272.             return $this->redirect($this->generateUrl('apply_home', []));
  273.         }
  274.         if ($customerHash $request->get('customerId')) {
  275.             $customer $em->getRepository(Customer::class)->findOneBy(['hash' => $customerHash]);
  276.             $teamId $customer->getTeamId();
  277.             $team $em->getRepository(Team::class)->findOneBy(['id' => $teamId]);
  278.         }
  279.         $settings $em->getRepository(Application::class)->getSettingsProgram($program$batch);
  280.         $productNumber $batch->getBatchNumber();
  281.         $account $this->getAccountBySlug($batchSlug);
  282.         $accountHash $em->getRepository(Customer::class)->getAccountHashByAccount($account);
  283.         $promocode $request->get('promocode') ? $request->get('promocode') : '';
  284.         if (isset($settings['isFrame']) and $settings['isFrame']) {
  285.             return $this->render('@StartPlatzRheinlandPitchBundle/Apply/monsum.checkout.html.twig', [
  286.                 'accountHash' => $accountHash,
  287.                 'customerHash' => $customerHash,
  288.                 'productNumber' => $productNumber,
  289.                 'settings' => $settings,
  290.                 'redirectUrl' => base64_encode(json_encode(['path' => 'rheinland-pitch_apply_home''parameters' => []])),
  291.             ]);
  292.         } else {
  293.             if ($promocode) {
  294.                 return $this->redirect("https://app.monsum.com/checkout/0/{$accountHash}/{$customerHash}/{$productNumber}&promocode={$promocode}&x_applicationId={$id}");
  295.             } else {
  296.                 return $this->redirect("https://app.monsum.com/checkout/0/{$accountHash}/{$customerHash}/{$productNumber}&x_applicationId={$id}");
  297.             }
  298.             /* Gerrit stash membership 11.4.23
  299.             if ($promocode) {
  300.                 return $this->redirect("https://app.monsum.com/checkout/0/{$accountHash}/{$customerHash}/{$productNumber}&promocode={$promocode}&x_applicationId={$id}&success_url={$successUrl}");
  301.             } else {
  302.                 return $this->redirect("https://app.monsum.com/checkout/0/{$accountHash}/{$customerHash}/{$productNumber}&x_applicationId={$id}&success_url={$successUrl}");
  303.             }
  304.             */
  305.         }
  306.         /*
  307.         Rückgabe von Monsum auf
  308.         https://www.startplatz.de/x/membership/receipt-monsum/17048?customerId=6a982bbfe539c9cb0ba1ca967210e0cc&subscriptionId=83add62a2825deabc141b278bd7f1fe3
  309.          */
  310.     }
  311.     private function getAccountBySlug($slug)
  312.     {
  313.         $accountShortName explode('-'$slug)[1];
  314.         $accounts = [
  315.             "cgn" => "SP-CGN",
  316.             "dus" => "SP-DUS",
  317.             "test" => "TESTPLATZ",
  318.         ];
  319.         return $accounts[$accountShortName];
  320.     }
  321.     #[Route('/access/startup-membership/{programSlug}/{batchSlug}/'name'access_startup-membership')]
  322.     /**
  323.      * @IsGranted("ROLE_USER")
  324.      */
  325.     public function hasStartupMembershipAction(Request $request$programSlug$batchSlug)
  326.     {
  327.         $em $this->entityManager;
  328.         /** @var User $user */
  329.         $user $this->getUser();
  330.         $em->getRepository(User::class)->writeActivity($user);
  331.         if (!$program $em->getRepository(Program::class /*Startup Program*/)->findOneBy(['slug' => $programSlug])) {
  332.             $this->addFlash('notice''ERROR Sorry, no program found');
  333.             return $this->redirect($this->generateUrl('apply_home', []));
  334.         }
  335.         if (!$batch $em->getRepository(Batch::class)->findOneBy(['slug' => $batchSlug'program' => $program])) {
  336.             $this->addFlash('notice''ERROR Sorry, no batch found');
  337.             return $this->redirect($this->generateUrl('apply_home', []));
  338.         }
  339.         $settings = [
  340.             'bgImage' => 'https://res.cloudinary.com/startplatz/image/upload/v1610197223/applications/backgrounds/friendly-coworking.png',
  341.         ];
  342.         return $this->render('@StartPlatzRheinlandPitchBundle/Apply/checkHasStartupMembership.html.twig', [
  343.             'program' => $program,
  344.             'batch' => $batch,
  345.             'settings' => $settings,
  346.             'product' => ['name' => 'test'],
  347.             'action' => 'default',
  348.             'application' => ['websiteUrl' => ''],
  349.             'redirectUrl' => base64_encode(json_encode(['path' => 'rheinland-pitch_apply_home''parameters' => []])),
  350.         ]);
  351.     }
  352.     #[Route('/apply/rheinland-pitch/startup-academy-pitch-night-bewerbungen-00'name'redirect_applications')]
  353.     public function redirectApplicationAction()
  354.     {
  355.         return $this->redirect($this->generateUrl('apply_program_home', ['programSlug' => 'event''batchSlug' => 'startup-academy-pitch-night-bewerbungen-01''id' => 'start']));
  356.     }
  357.     private function getExtraFieldsAttributes($settings)
  358.     {
  359.         if (!isset($settings['extraFields'])) {
  360.             return $settings;
  361.         }
  362.         $em $this->entityManager;
  363.         $extraFields $settings['extraFields'];
  364.         $i 0;
  365.         foreach ($extraFields as $extraField) {
  366.             if ($extraField['type'] == 'choice') {
  367.                 $choices = [];
  368.                 if (isset($extraField['arr'])) {
  369.                     $choices $em->getRepository(Attribute::class)->findCodesByAttributeName($extraField['arr']);
  370.                 }
  371.                 $settings['extraFields'][$i]['choices'] = $choices;
  372.             }
  373.             $i++;
  374.         }
  375.         return $settings;
  376.     }
  377.     private function getExtraFieldsData(Application $application$settings$form)
  378.     {
  379.         $extraFields $settings['extraFields'];
  380.         $data = [];
  381.         $i 0;
  382.         foreach ($extraFields as $extraField) {
  383.             $data[$extraField['field']] = $form->get($extraField['field'])->getData();
  384.             $i++;
  385.         }
  386.         if ($data) {
  387.             $application->setExtraFields(json_encode($data)) ;
  388.         }
  389.         return $application;
  390.     }
  391.     #[Route('/schnuppermitgliedschaft-buchen/welcome/{id}'name'schnuppermitgliedschaft_buchen_welcome_de')]
  392.     #[Route('/schnuppermitgliedschaft-buchen/{id}'name'schnuppermitgliedschaft_buchen_de')]
  393.     #[Route('/schnuppermitgliedschaft-team-buchen/welcome/{id}'name'schnuppermitgliedschaft_team_buchen_welcome_de')]
  394.     #[Route('/schnuppermitgliedschaft-team-buchen/{id}'name'schnuppermitgliedschaft_team_buchen_de')]
  395.     #[Route('/startup-academy-test-mitgliedschaft-buchen/{id}'name'startup-academy-test-mitgliedschaft_buchen_de')]
  396.     #[Route('/trial-membership-register/{id}'name'schnuppermitgliedschaft_buchen_en')]
  397.     #[Route('/trial-membership-register/{id}'name'schnuppermitgliedschaft_buchen_en')]
  398.     #[Route('/free-token/{id}'name'free-token')]
  399.     #[Route('/apply/{programSlug}/{batchSlug}/{id}'name'apply_program_home')]
  400.     #[Route('/{lang}/apply/{programSlug}/{batchSlug}/{id}'name'apply_program_home_lang')]
  401.     public function applyAction(Request $request$programSlug 'undef'$batchSlug 'undef'$id 'start'$lang null)
  402.     {
  403.         ##apply
  404.         $em $this->entityManager;
  405.         $now = new datetime();
  406.         $pathInfo $request->getPathInfo();
  407.         $host $request->getHost();
  408.         $test $request->get('test');
  409.         $routeName $request->get('_route');
  410.         $routeParameters $request->get('_route_params');
  411.         $isMemberloggedIn false;
  412.         $isEmailRegistered false;
  413.         $product null;
  414.         $landingPageContent "";
  415.         $landingPageTwig "";
  416.         $lang strtoupper($lang ?? 'DE');
  417.         $priceAndDiscount = [];
  418.         $settings = []; // array contains specific definitions in relation to program, batch and template
  419.         // Retrieve the UTM parameters from the URL
  420.         $utmParameters = [
  421.             'utmSource'   => $request->query->get('utm_source'),
  422.             'utmMedium'   => $request->query->get('utm_medium'),
  423.             'utmCampaign' => $request->query->get('utm_campaign'),
  424.             'utmTerm'     => $request->query->get('utm_term'),
  425.             'utmContent'  => $request->query->get('utm_content'),
  426.         ];
  427.         if ($routeName != 'apply_program_home' && $routeName != 'apply_program_home_lang') {
  428.             ## evaluate special routes like 'schnuppermitgliedschaft_buchen_en' ########################
  429.             if (!$response $this->evaluateAliasSlug($routeName)) {
  430.                 $this->addFlash('notice''ERROR url is invalid');
  431.                 return $this->redirect($this->generateUrl('apply_home', []));
  432.             } else {
  433.                 /** @var Program $program */
  434.                 $program $response['data']['program'];
  435.                 /** @var Batch $batch */
  436.                 $batch $response['data']['batch'];
  437.                 $batchSlug $batch->getSlug();
  438.                 $programSlug $program->getSlug();
  439.             }
  440.             ## end of route evaluation
  441.         } else {
  442.             ## find program and batch by the default way ############
  443.             /** @var Program $program */
  444.             if (!$program $em->getRepository(Program::class /*Startup Program*/)->findOneBy(['slug' => $programSlug])) {
  445.                 $this->addFlash('notice''ERROR Sorry, no program found');
  446.                 return $this->redirect($this->generateUrl('apply_home', []));
  447.             }
  448.             if (!$batch $em->getRepository(Batch::class)->findOneBy(['slug' => $batchSlug'program' => $program])) {
  449.                 $this->addFlash('notice''ERROR Sorry, no batch found');
  450.                 return $this->redirect($this->generateUrl('apply_home', []));
  451.             }
  452.         }
  453.         if ($program->getSlug() == 'membership') {
  454.             $productNumber $batch->getBatchNumber();
  455.             $account $this->getAccountBySlug($batchSlug);
  456.             // find product by productNumber, account and agent == monsum
  457.             $product $em->getRepository(Product::class /*Product Member*/)->findOneBy(['account' => $account'productNumber' => $productNumber'agent' => 'monsum']);
  458.         }
  459.         ##-- now we know program and batch (and product if membership) --##
  460.         // check if application is still open
  461.         if ($batch->getStatus() == 'inactive') {
  462.             $this->addFlash('notice''ERROR Sorry, application is currently not active');
  463.             return $this->redirect($this->generateUrl('apply_home', []));
  464.         }
  465.         ## is application open
  466.         ##toBeTested
  467.         $response $em->getRepository(Batch::class)->isApplicationOpen($batch);
  468.         if ($response['status'] == 'error') {
  469.             $this->addFlash('notice'$response['message']);
  470.             return $this->redirect($this->generateUrl('apply_home', []));
  471.         }
  472.         // check if settings contains necessary setters
  473.         $batch $em->getRepository(Batch::class)->checkLegacyData($batch);
  474.         // settings for program and batch will be merged
  475.         $settings $em->getRepository(Application::class)->getSettingsProgram($program$batch);
  476.         // check LoginStatus
  477.         /** @var User $user */
  478.         if ($user $this->getUser()) {
  479.             ## user is logged in. this will be the default case ############
  480.             $adminEmail $user->getEmail();
  481.             $em->getRepository(User::class)->writeActivity($user);
  482.             /** @var Member $member */
  483.             $member $em->getRepository(Member::class)->find($user->getMemberId());
  484.             $isMemberloggedIn true;
  485.         } else {
  486.             ## if user is not logged in - kick her out except it is allowed to access batch without being logged in
  487.             if ($batch->getAccess() != 'anonymous') {
  488.                 // Pass the UTM parameters along with other necessary arguments to the createApplicationByApplyForm method
  489.                 $application $em->getRepository(Application::class)->createApplicationByApplyForm(
  490.                     $program,
  491.                     $batch,
  492.                     $lang,
  493.                     $priceAndDiscount,
  494.                     $utmParameters  // This is the array you created earlier
  495.                 );
  496.                 return $this->render('@StartPlatzRheinlandPitchBundle/Apply/apply.default.html.twig', [
  497.                     'settings' => $settings,
  498.                     'program' => $program,
  499.                     'batch' => $batch,
  500.                     'test' => $test,
  501.                     'application' => $application,
  502.                     'applicationId' => $id,
  503.                     'phrases' => $em->getRepository(Option::class)->getApplicationPhrases($program$batch$product$lang),
  504.                     'redirectUrl' => base64_encode(json_encode(['path' => 'apply_program_home_lang''parameters' => ['id' => $id'programSlug' => $programSlug'batchSlug' => $batchSlug], 'lang' => strtolower($lang)])),
  505.                 ]);
  506.             }
  507.             $member $em->getRepository(Member::class)->setEmptyMemberAccount();
  508.         }
  509.         $settings['isMemberloggedIn'] = $isMemberloggedIn;
  510.         if ($isMemberloggedIn) {
  511.             // check access conditions
  512.             if ($batch->getAccess() == 'hasStartupMembership') {
  513.                 $team $em->getRepository(Team::class)->findOneBy(['id' => $user->getTeamId()]);
  514.                 if (!$team->getHasStartupMembership()) {
  515.                     return $this->redirect($this->generateUrl('access_startup-membership', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => $id]));
  516.                 }
  517.             }
  518.             // check is missing if Community Membership
  519.         }
  520.         ## -- settings -- #############
  521.         // important distinction - is it necessary to bind this application to a team
  522.         // or is it okay to bind it with a person only
  523.         // event are normally person only, applications for accelerator need a team
  524.         // it can be defined via batch (isMultipleApplicationsPerTeam)
  525.         // but in every case an application need to be tied to a member and at least a virtual team
  526.         // we need to keep track is a member team relationship has been set
  527.         // because either member or team can be created during application process
  528.         $_isMemberTeamRelationSet 0;
  529.         // for memberships we need the product type
  530.         $settings['productType'] = 'Applicant';
  531.         if ($product) {
  532.             $settings['productType'] = $product->getType();
  533.         }
  534.         // we set an virtual team as fallback if no new allmeda team is needed to process the request
  535.         $virtualTeam array_key_exists('virtualTeam'$settings) ? $settings['virtualTeam'] : 'applicants';
  536.         // access the relevant virtual team or create that team if it does not exists
  537.         $applicantsTeam $em->getRepository(Team::class)->getVirtualTeamByName($virtualTeam);
  538.         $adminEmail $user $user->getEmail() : "";
  539.         $application null;
  540.         // find application or create new one if id = start
  541.         if ($id == 'start') {
  542.             if ($teamId $request->get('teamId') and $user and $teamId 0) {
  543.                 if (!$em->getRepository(MemberTeam::class)->isMemberOfTeam($user->getMemberId(), $teamId)) {
  544.                     $this->addFlash('notice''ERROR 01 no access to team');
  545.                     return $this->redirect($this->generateUrl('apply_program_home_lang', ['id' => $id'programSlug' => $programSlug'batchSlug' => $batchSlug'lang' => strtolower($lang)]));
  546.                 }
  547.                 if ($application $em->getRepository(Application::class)->findOneBy(['teamId' => $teamId'programSlug' => $programSlug'batchSlug' => $batchSlug])) {
  548.                     $this->addFlash('notice''SUCCESS application for your team found');
  549.                     return $this->redirect($this->generateUrl('apply_program_home_lang', ['id' => $application->getId(), 'programSlug' => $programSlug'batchSlug' => $batchSlug'lang' => strtolower($lang)]));
  550.                 }
  551.             }
  552.             if ($batch->isMultipleApplicationsPerTeam() and $user) {
  553.                 // look up application of that member
  554.                 $application $em->getRepository(Application::class)->findOneBy(['batchId' => $batch->getId(), 'memberId' => $user->getMemberId()]);
  555.             } elseif ($user) {
  556.                 if (!$batch->isMultipleApplicationsPerMember()) {
  557.                     // look up application of that team
  558.                     if (!$application $em->getRepository(Application::class)->findOneBy(['batchId' => $batch->getId(), 'teamId' => $user->getTeamId()])) {
  559.                         // if there is no application bound with the primary team of the member look for an application bound with that member directly
  560.                         $application $em->getRepository(Application::class)->findOneBy(['batchId' => $batch->getId(), 'memberId' => $user->getMemberId()]);
  561.                     }
  562.                 }
  563.             }
  564.             if ($application) {
  565.                 $member $em->getRepository(Member::class)->find($application->getMemberId());
  566.                 $teamId $request->get('teamId') ? $request->get('teamId') : $application->getTeamId();
  567.                 $team $this->setTeam($member$settings$teamId$applicantsTeam);
  568.             } else { // create new application
  569.                 // Pass the UTM parameters along with other necessary arguments to the createApplicationByApplyForm method
  570.                 $application $em->getRepository(Application::class)->createApplicationByApplyForm(
  571.                     $program,
  572.                     $batch,
  573.                     $lang,
  574.                     $priceAndDiscount,
  575.                     $utmParameters  // This is the array you created earlier
  576.                 );
  577.                 if ($program->getSlug() == 'membership') {
  578.                     if ($memberId $request->get('w')) {
  579.                         if ($werber $em->getRepository(Member::class)->find($memberId)) {
  580.                             $application->setRecommendedBy($werber->getEmail());
  581.                         }
  582.                     }
  583.                 }
  584.                 $member $em->getRepository(Application::class)->setMember($program$batch$applicantsTeam$user);
  585.                 $application $em->getRepository(Application::class)->updateApplicationByMember($application$member);
  586.                 if ($request->get('teamId')) {
  587.                     $teamId $request->get('teamId');
  588.                 } elseif ($user) {
  589.                     if ($settings['createAlwaysNewTeam']) {
  590.                         $teamId 0;
  591.                     } else {
  592.                         $teamId $user->getTeamId();
  593.                     }
  594.                 } else {
  595.                     $teamId 0;
  596.                 }
  597.                 $team $this->setTeam($member$settings$teamId$applicantsTeam);
  598.                 if ($settings['isTeamNeeded']) {
  599.                     $application $this->updateApplicationByTeam($application$team);
  600.                 } else {
  601.                     $teamId $applicantsTeam->getId();
  602.                     $application->setTeamId($teamId);
  603.                 }
  604.             }
  605.         } else {
  606.             if (!$application $em->getRepository(Application::class)->find($id)) {
  607.                 $this->addFlash('notice''ERROR apply:01 - Application could not be found. You can create a new one');
  608.                 return $this->redirect($this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => 'start''lang' => strtolower($lang)]));
  609.             }
  610.             if ($application->getProgramSlug() != $programSlug or $application->getBatchSlug() != $batchSlug) {
  611.                 $this->addFlash('notice''ERROR apply:011 - Application could not be found. You can create a new one');
  612.                 return $this->redirect($this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => 'start''lang' => strtolower($lang)]));
  613.             }
  614.             $canPassWithoutLogin = [
  615.                 "error:validateLogin",
  616.                 "error:validateEmail",
  617.             ];
  618.             if (!in_array($application->getEditStatus(), $canPassWithoutLogin)) {
  619.                 if (!$user) {
  620.                     $this->addFlash('notice''ERROR apply:021 - Please Login first');
  621.                     return $this->redirect($this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => 'start''lang' => strtolower($lang)]));
  622.                 } else {
  623.                     if ($application->getMemberId() != $user->getMemberId() and $user) {
  624.                         $this->addFlash('notice''ERROR apply:012 - Application could not be found. You can create a new one');
  625.                         return $this->redirect($this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => 'start''lang' => strtolower($lang)]));
  626.                     }
  627.                 }
  628.             }
  629.             if ($user) {
  630.                 if ($application->getMemberId() != $user->getMemberId()) {
  631.                     if (!$em->getRepository(MemberTeam::class)->isMemberOfTeam($user->getMemberId(), $application->getTeamId())) {
  632.                         $this->addFlash('notice''ERROR apply:013 - No access to this application. You can create a new one');
  633.                         return $this->redirect($this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => 'start''lang' => strtolower($lang)]));
  634.                     }
  635.                 }
  636.             }
  637.             $teamId $request->get('teamId') ? $request->get('teamId') : $application->getTeamId();
  638.             $team $this->setTeam($member$settings$teamId$applicantsTeam);
  639.         }
  640.         ## now in every case there is an application
  641.         ## we need to check the language
  642.         if ($lang) {
  643.             if ($lang != $application->getLang()) {
  644.                 $application->setLang($lang);
  645.             }
  646.         } else {
  647.             $lang $application->getLang() ? $application->getLang() : $batch->getLang();
  648.         }
  649.         ## now in every case the variable $lang is set
  650.         // checkAccessRight for team if found by external teamId
  651.         if ($request->get('teamId') > and !$teamMember $em->getRepository(MemberTeam::class)->findOneBy(['team' => $team'member' => $member])) {
  652.             $this->addFlash('notice''ERROR 02 no access to team');
  653.             return $this->redirect($this->generateUrl('apply_home'));
  654.         }
  655.         if ($adminEmail) {
  656.             $application->setLastChangeUser($adminEmail);
  657.         }
  658.         $action $request->get('action');
  659.         // action can be only set to 'finish' internally
  660.         if ($action == "finish") {
  661.             $action "";
  662.         }
  663.         if ($action == "changeName") {
  664.             $application->setStartupName("copy of " $application->getStartupName());
  665.             $application->setEditStatus("open");
  666.             $action "start";
  667.         }
  668.         if ($action == "shortenIdeaPitch") {
  669.             $application->setEditStatus("open");
  670.             $action "start";
  671.         }
  672.         if (str_contains(strtolower($application->getEditStatus() ?? ''), "error")   and $action and $user) {
  673.             // Zuordnung memberTeam checken bzw. erstellen - falls validate Login - falls keine Zuordnung und isTeamNeeded GF sonst MA
  674.             $response $em->getRepository(Application::class)->validateApplication($application$member$team$settings$action$request->get('code'));
  675.             /** @var Application $application */
  676.             $application $response['data']['application'];
  677.             $action $response['action'];
  678.             /* Gerrit stash membership 11.4.23
  679.             $application = $em->getRepository(Application::class)->setProcessGoToMonsum($application);
  680.             */
  681.             /*
  682.             if ($response['status'] == "success") {
  683.                 $application = $this->setApplicationStatusByTemplate($application);
  684.                 $action = $this->setActionByProgramSlug($application);
  685.             }*/
  686.             /** @var Member $member */
  687.             $member $response['data']['member'];
  688.             /** @var Team $team */
  689.             $team $response['data']['team'];
  690.             $teamId $team->getId();
  691.             if (!$user->getTeamId()) {
  692.                 $em->getRepository(Member::class)->setPrimaryTeam($member$team$this->getUser()->getEmail());
  693.             }
  694.             /*  Gerrit stash membership 11.4.23
  695.              } elseif ($program->getSlug() == 'membership' and $application->getEditStatus() == "success:applied" and $user) {
  696.                  $action = "goToMonsum"; */
  697.         } elseif ($application->getEditStatus() == "success:applied" and $user) {
  698.             //todo find another status for people that have applied long before
  699.             $action "finish";
  700.         } elseif ($application->getEditStatus() == "success:confirmationMailSent" and $user) {
  701.             $action "done";
  702.         } elseif (($application->getEditStatus() == "success:validatedLogin" or $application->getEditStatus() == "success:validatedEmail" or $application->getEditStatus() == "validated") and $user) {
  703.             $action $this->setActionByProgramSlug($application);
  704.         } elseif ($application->getApplicationStatus() == "started" and $user) {
  705.             $action "continue";
  706.         } elseif ($application->getApplicationStatus() == "applied" and $user) {
  707.             if (in_array($application->getTemplate(), ['accelerator''rheinland-pitch'])) {
  708.                 $action "reopen";
  709.             } else {
  710.                 $action "finish";
  711.             }
  712.         }
  713.         $_isMemberTeamRelationSet $em->getRepository(MemberTeam::class)->findOneBy(['team' => $team'member' => $member]) ? 0;
  714.         $form $this->createForm(ApplicationType::class, $application, ['settings' => $settings'program' => $program'batch' => $batch]);
  715.         $form->handleRequest($request);
  716.         ##############################################################
  717.         ##   form validation starts here                            ##
  718.         ##############################################################
  719.         if ($form->isSubmitted() && $form->isValid()) {
  720.             // make email lower case
  721.             $application->setEmail(strtolower($application->getEmail()));
  722.             if (!$application->getPerson() and $application->getFirstName()) {
  723.                 $application->setPerson("{$application->getFirstName()} {$application->getLastName()}");
  724.             }
  725.             if (!$adminEmail) {
  726.                 $adminEmail $application->getEmail();
  727.             }
  728.             if (isset($settings['extraFields'])) {
  729.                 $application $this->getExtraFieldsData($application$settings$form);
  730.             }
  731.             // now we can check if the email of the form already registered within startplatz
  732.             $isEmailRegistered $em->getRepository(Member::class)->isEmailRegistered($application->getEmail());
  733.             if ($isMemberloggedIn or !$isEmailRegistered) {
  734.                 // if settings[isTeamNeeded] is set a corporate team is created otherwise a person team
  735.                 if ($teamId == 'create' or !$team->getId()) {
  736.                     $team $em->getRepository(Team::class)->createTeamByApplication($application$settings$member);
  737.                     $application->setTeamId($team->getId());
  738.                     $teamId $team->getId();
  739.                 }
  740.             }
  741.             ##email validation - only relevant if access == anonymous or login
  742.             $response $this->evaluateApplicationEmail($application$member$team$settings$user);
  743.             $application $response['data']['application'];
  744.             $member $response['data']['member'];
  745.             $hasExistingApplication $response['hasExistingApplication'];
  746.             $_isMemberTeamRelationSet $teamMember $em->getRepository(MemberTeam::class)->findOneBy(['team' => $team'member' => $member]) ? 0;
  747.             // Do we allow multiple applications?
  748.             $allowMultiple $settings['isTeamNeeded']
  749.                 ? $settings['isMultipleApplicationsPerTeam']
  750.                 : $settings['isMultipleApplicationsPerMember'];
  751.             if (!$allowMultiple
  752.                 && $hasExistingApplication
  753.                 && $application->getApplicationStatus() == 'applied'
  754.                 && $program->getSlug() == 'membership'
  755.             ) {
  756.                 $targetUrl strtolower($this->generateUrl('apply_program_home_lang'$routeParameters));
  757.                 $loginLink $this->generateUrl('login', ['targetPath' => $targetUrl]);
  758.                 $this->addFlash('notice'"ERROR: You already applied for this membership with your email address. <a title=\"Login page\" href=\"$loginLink\">You can login here</a>.");
  759.                 $routeParameters['action'] = "";
  760.                 return $this->redirect($targetUrl);
  761.             }
  762.             if (!$application->getApplicationStatus()) {
  763.                 $application->setApplicationStatus('started');
  764.             }
  765.             $application $em->getRepository(Application::class)->setApplication($application);
  766.             // at this point application is set and stored in database
  767.             // and member is set and team is set - now we can do last changes to team
  768.             if ($response['status'] == 'error') {
  769.                 /*
  770.                     $status  = "error";
  771.                     $todo    = "validateLogin";
  772.                  */
  773.                 $routeParameters = [
  774.                     'programSlug' => $programSlug,
  775.                     'batchSlug' => $batchSlug,
  776.                     'id' => $application->getId(),
  777.                     'lang' => $lang,
  778.                     'action' => 'validate'
  779.                 ];
  780.                 if ($test) {
  781.                     $routeParameters['test'] = $test;
  782.                 }
  783.                 if ($response['todo'] == "validateLogin") {
  784.                     $targetPath strtolower($this->generateUrl('apply_program_home_lang'$routeParameters));
  785.                     $loginLink $this->loginService->getLoginLinkByTargetPath($member->getEmail(), $targetPath);
  786.                     $mailTemplate $em->getRepository(MailTemplate::class)->getValidateLoginMailTemplateByBatch($batch$application$loginLink);
  787.                     $feedback Utility::sendAlertMailPerZapier($mailTemplate['recipientEmail'], $mailTemplate['mailText'], $mailTemplate['mailSubject'], $mailTemplate['replyToEmail'], $mailTemplate['fromName'], $mailTemplate['bodyType']);
  788.                     $feedback json_decode($feedback);
  789.                     if ($feedback->status == "success") {
  790.                         $routeParameters['action'] = "needsLoginValidation";
  791.                         $targetUrl strtolower($this->generateUrl('apply_program_home_lang'$routeParameters));
  792.                         return $this->redirect($targetUrl);
  793.                     } else {
  794.                         $this->addFlash('notice''ERROR email is invalid please check your email address!');
  795.                         $routeParameters['action'] = "";
  796.                         $targetUrl strtolower($this->generateUrl('apply_program_home_lang'$routeParameters));
  797.                         return $this->redirect($targetUrl);
  798.                     }
  799.                 }
  800.                 if ($response['todo'] == "validateEmail") {
  801.                     $targetPath strtolower($this->generateUrl('apply_program_home_lang'$routeParameters));
  802.                     $loginLink $this->loginService->getLoginLinkByTargetPath($member->getEmail(), $targetPath);
  803.                     $mailTemplate $em->getRepository(MailTemplate::class)->getValidateEmailMailTemplateByBatch($batch$application$loginLink);
  804.                     $em->persist($application);
  805.                     $em->flush();
  806.                     $feedback Utility::sendAlertMailPerZapier($mailTemplate['recipientEmail'], $mailTemplate['mailText'], $mailTemplate['mailSubject'], $mailTemplate['replyToEmail'], $mailTemplate['fromName'], $mailTemplate['bodyType']);
  807.                     $feedback json_decode($feedback);
  808.                     if ($feedback->status == "success") {
  809.                         $routeParameters['action'] = "needsEmailVerification";
  810.                         $targetUrl strtolower($this->generateUrl('apply_program_home_lang'$routeParameters));
  811.                         return $this->redirect($targetUrl);
  812.                     } else {
  813.                         $this->addFlash('notice''ERROR email is invalid please check your email adress!');
  814.                         $routeParameters['action'] = "";
  815.                         $targetUrl strtolower($this->generateUrl('apply_program_home_lang'$routeParameters));
  816.                         return $this->redirect($targetUrl);
  817.                     }
  818.                 }
  819.                 if ($test) {
  820.                     return $this->redirect($this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => $application->getId(), 'test' => $test'lang' => strtolower($lang)]));
  821.                 } else {
  822.                     return $this->redirect($this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => $application->getId(), 'lang' => strtolower($lang)]));
  823.                 }
  824.             }
  825.             $response $this->checkPlausibility($application$member$team$settings);
  826.             $application $response['data']['application'];
  827.             $application $em->getRepository(Application::class)->setApplication($application);
  828.             if (!$user) {
  829.                 switch ($program->getSlug()) {
  830.                     case "rheinland-pitch":
  831.                     case "accelerator":
  832.                         // make applicant a guest member and login
  833.                         $guestTeam $em->getRepository(Team::class)->getVirtualTeamByName("Guest Membership");
  834.                         $memberTeam $em->getRepository(Member::class)->setTeamAssignment($member$guestTeam"MA"$adminEmail);
  835.                         break;
  836.                     case "nft":
  837.                         // make applicant a guest member and login
  838.                         if (!$isEmailRegistered) {
  839.                             $guestTeam $em->getRepository(Team::class)->getVirtualTeamByName("Guest Membership");
  840.                             $memberTeam $em->getRepository(Member::class)->setTeamAssignment($member$guestTeam"MA"$adminEmail);
  841.                         }
  842.                         $user $em->getRepository(User::class)->findOneBy(['memberId' => $member->getId()]);
  843.                         break;
  844.                     default:
  845.                         break;
  846.                 }
  847.             }
  848.             if ($response['status'] == 'error') {
  849.                 if (!$user) {
  850.                     $targetPath $this->generateUrl('apply_program_home', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => $application->getId(), $action => 'validate']);
  851.                     $loginLink $this->loginService->getLoginLinkByTargetPath($member->getEmail(), $targetPath);
  852.                     return $this->redirect($loginLink);
  853.                 } else {
  854.                     return $this->redirect($this->generateUrl('apply_program_home', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => $application->getId(), $action => 'validate']));
  855.                 }
  856.             }
  857.             if ($settings['isPitchDeckRequired']) {
  858.                 if ($form->get('uploadImage')->isClicked()) {
  859.                     $uploadTag "application/{$application->getId()}";
  860.                     if ($application->getLinkPitchDeck()) {
  861.                         $application->setLinkPitchDeck('');
  862.                         $application->setPublicIdPitchDeck('');
  863.                         $application $em->getRepository(Application::class)->setApplication($application);
  864.                         $result $this->cloudinary->delete_resources_by_tag($uploadTag);
  865.                     }
  866.                     return $this->redirect($this->generateUrl('apply_program_uploadPitchDeck', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => $application->getId(), 'teamId' => $application->getTeamId(), 'memberId' => $application->getMemberId()]));
  867.                 }
  868.             }
  869.             if ($form->get('finish')->isClicked()) {
  870.                 $action "finish";
  871.                 if ($application->getPhone() and !$member->getPhone()) {
  872.                     $member $em->getRepository(Member::class)->setPhone($member$application->getPhone(), $adminEmail);
  873.                 }
  874.                 // relevant only for membership applicants - all applications for membership exit here
  875.                 if ($program->getSlug() == 'membership') {
  876.                     $settings['routeName'] = $routeName;
  877.                     $settings['monsumArticleNumber'] = $product->getMonsumArticleNumber();
  878.                     /* Gerrit stash membership 11.4.23 - exchange with next line
  879.                     return $this->redirect($this->generateUrl('x_membership_monsum-checkout', ['productId' => $product->getProductNumber()]));
  880.                     */
  881.                     return $this->goToMonsum($program$batch$settings$application$member$team$applicantsTeam$user);
  882.                 }
  883.                 // make applicant member of additional virtual team specified in settings
  884.                 $applicantsTeamMember $em->getRepository(Member::class)->setTeamAssignment($member$applicantsTeam"MA"$adminEmail);
  885.                 // final plausibility checks - brauchen wir die überhaupt noch? oder sind das finale Anpassungen der application
  886.                 switch ($program->getSlug()) {
  887.                     case "rheinland-pitch":
  888.                     case "accelerator":
  889.                         if (!$application->getLinkPitchDeck()) {
  890.                             $this->addFlash('notice''ERROR - Your application will not be processed unless you upload a pitch deck!');
  891.                         } else {
  892.                             $wordsCount str_word_count($application->getIdeaPitch() ?? '');
  893.                             if ($wordsCount 1500) {
  894.                                 $this->addFlash('notice'"ERROR - Your idea pitch contains {$wordsCount} words, please reduce the length of your idea pitch!");
  895.                             } else {
  896.                                 $action "finish";
  897.                                 $application->setApplicationStatus('applied');
  898.                                 if ($application->getVotesRegistered() == 0) {
  899.                                     $application->setVotesRegistered($settings['initialVotes']);
  900.                                 }
  901.                                 $em->persist($application);
  902.                                 $em->flush();
  903.                             }
  904.                         }
  905.                         break;
  906.                     default:
  907.                         $application $em->getRepository(Application::class)->setApplicationApplied($application);
  908.                         break;
  909.                 }
  910.             } // end of validation of submit button (finish)
  911.             if ($action != "finish") {
  912.                 $this->addFlash('notice''SUCCESS data saved');
  913.                 if ($id != $application->getId()) {
  914.                     if (!$user) {
  915.                         $targetPath $this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => $application->getId(), 'lang' => strtolower($lang)]);
  916.                         $loginLink $this->loginService->getLoginLinkByTargetPath($member->getEmail(), $targetPath);
  917.                         return $this->redirect($loginLink);
  918.                     } else {
  919.                         return $this->redirect($this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => $application->getId(), 'lang' => strtolower($lang)]));
  920.                     }
  921.                 } else {
  922.                     $id $application->getId();
  923.                 }
  924.             }
  925.         } // end of form validation
  926.         else {
  927.             $errorString $form->getErrors(truefalse);
  928.             // @todo: $errorString ist ein Array -> StringCast in der nächsten Zeile anders behandeln
  929.             if (str_contains((string) $errorString'ERROR:')) {
  930.                 $this->addFlash('notice''ERROR - Data have not been saved, reason: ' $errorString);
  931.             }
  932.         }
  933.         if ($action == "goToMonsum") {
  934.             $settings['routeName'] = $routeName;
  935.             $settings['monsumArticleNumber'] = $product->getMonsumArticleNumber();
  936.             return $this->goToMonsum($program$batch$settings$application$member$team$applicantsTeam$user);
  937.         }
  938.         if ($action == "finish") {
  939.             $batch $em->getRepository(Batch::class)->updateNumbers($batch);
  940.             ##final actions and good bye messages
  941.             switch ($batch->getTemplate()) {
  942.                 case "accelerator":
  943.                 case "rheinland-pitch":
  944.                     $this->addFlash('notice''SUCCESS Thank you for your application. We have sent you a confirmation mail with additional information.');
  945.                     break;
  946.                 case "registration":
  947.                 case "businessclub":
  948.                 case "event":
  949.                     if ($batch->getAccess() == "anonymous") {
  950.                         if (!$user and $member->getId()) {
  951.                             $targetPath $this->generateUrl('apply_program_home', ['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => $application->getId(), 'action' => 'finish']);
  952.                             $loginLink $this->loginService->getLoginLinkByTargetPath($member->getEmail(), $targetPath);
  953.                             $user $em->getRepository(User::class)->findOneBy(['memberId' => $member->getId()]);
  954.                             $this->sendConfirmationMailToApplicant($user$settings$application$batch);
  955.                             return $this->redirect($loginLink);
  956.                         }
  957.                     }
  958.                     break;
  959.                 case "speed-networking":
  960.                     break;
  961.                 case "sign-up":
  962.                     // what follow up should be done after
  963.                     if ($batch->getGoToPage() == 'editMentorsProfile') {
  964.                         $targetPath $this->generateUrl('connect_mentor_edit_profile', ['id' => $member->getId()]);
  965.                         if (!$user and $member->getId()) {
  966.                             $loginLink $this->loginService->getLoginLinkByTargetPath($member->getEmail(), $targetPath);
  967.                             return $this->redirect($loginLink);
  968.                         } else {
  969.                             return $this->redirect($targetPath);
  970.                         }
  971.                     }
  972.                     break;
  973.                 case "startup-tools":
  974.                     $this->addFlash('notice''SUCCESS Thank you for your application. We will come back to you soon');
  975.                     break;
  976.                 default:
  977.                     $view '@StartPlatzRheinlandPitchBundle/Apply/apply.default.html.twig';
  978.                     break;
  979.             }
  980.             //$this->addFlash('notice', 'MESSAGE sendConfirmationMailToApplicant($user, $settings, $application, $batch)');
  981.             if (!$user){
  982.                 $user $em->getRepository(User::class)->findOneBy(['memberId' => $member->getId()]);
  983.             }
  984.             $this->sendConfirmationMailToApplicant($user$settings$application$batch);
  985.             if ($programSlug == 'ai-hub'){
  986.                 $application->setEditStatus("success:confirmationMailSent");
  987.                 $application $em->getRepository(Application::class)->setApplicationDoneWithoutWorkflow($application);
  988.             }
  989.             // additional actions for specific programs
  990.             switch ($batch->getTemplate()) {
  991.                 case "accelerator":
  992.                     // Podio integration removed
  993.                     break;
  994.                 case "rheinland-pitch":
  995.                     break;
  996.             }
  997.             if ($batch->getLandingPageTwig()) {
  998.                 $loader = new ArrayLoader([
  999.                     'landingPageTwig' => $batch->getLandingPageTwig(),
  1000.                 ]);
  1001.                 $twig = new Environment($loader);
  1002.                 //$landingPageTwig = $twig->render('landingPageTwig', ['member' => $member]);
  1003.             }
  1004.         }
  1005.         $editWidget $this->setEditWidgetByTemplate($batch->getTemplate());
  1006.         $phrases $em->getRepository(Option::class)->getApplicationPhrases($program$batch$product$lang);
  1007.         $_isMemberTeamRelationSet $teamMember $em->getRepository(MemberTeam::class)->findOneBy(['team' => $team'member' => $member]) ? 0;
  1008.         $showFooter true// Default to showing the footer
  1009.         if ($request->query->get('iframe') === 'true') {
  1010.             // If the 'iframe' parameter is 'true', always hide the footer
  1011.             $showFooter false;
  1012.         } elseif (isset($settings['showFooter']) && $settings['showFooter'] == 0) {
  1013.             // If the 'iframe' parameter is not 'true' and $setting['showFooter'] exists and is 0, hide the footer
  1014.             $showFooter false;
  1015.         }
  1016.         // Auswahl des Twig-Templates basierend auf programId
  1017.         switch ($batch->getProgramId()) {
  1018.             case 1:
  1019.             case 3:
  1020.             default:
  1021.                 // Fallback auf das zentrale Template, falls programId unbekannt ist
  1022.                 $view '@StartPlatzRheinlandPitchBundle/Apply/apply.default.html.twig';
  1023.                 break;
  1024.         }
  1025.         $landingPageContent $batch->getLandingPageContent();
  1026.         ##view-apply
  1027.         // render specific application form or show landing page
  1028.         return $this->render($view, [
  1029.             'id' => $id,
  1030.             'settings' => $settings,
  1031.             'programSlug' => $programSlug,
  1032.             'batchSlug' => $batchSlug,
  1033.             'program' => $program,
  1034.             'phrases' => $phrases,
  1035.             'batch' => $batch,
  1036.             'lang' => $lang,
  1037.             'product' => $product,
  1038.             'googleCalendarLink' => $em->getRepository(Event::class)->getGoogleCalendardEventByEventId($batch->getEventId(), Utility::getZoomLink($batch->getZoomLink(), $application->getId())),
  1039.             'icsDownloadLink' => $this->generateUrl('event_download',['eventId'=>(int)$batch->getEventId()],UrlGeneratorInterface::ABSOLUTE_URL),
  1040.             'test' => $test,
  1041.             'host' => $host,
  1042.             'pathInfo' => $pathInfo,
  1043.             'view' => $view,
  1044.             'editWidget' => $editWidget,
  1045.             'showFooter' => $showFooter,
  1046.             'member' => $member,
  1047.             'team' => $team,
  1048.             'teamId' => $teamId,
  1049.             'application' => $application,
  1050.             'applicationId' => $id,
  1051.             'form' => $form->createView(),
  1052.             'action' => $action,
  1053.             'landingPageContent' => $landingPageContent,
  1054.             'landingPageTwig' => $landingPageTwig,
  1055.             'targetPathEN' => $this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'lang' => 'en']),
  1056.             'targetPathDE' => $this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'lang' => 'de']),
  1057.             'redirectUrl' => base64_encode(json_encode(['path' => 'apply_program_home_lang''parameters' => ['id' => $id'programSlug' => $programSlug'batchSlug' => $batchSlug'lang' => strtolower($lang)]])),
  1058.             'menuLinksAndPhrases' => $this->menuTranslationService->getMenuLinksAndPhrases($request->server->get('REQUEST_URI'), $lang),
  1059.         ]);
  1060.     }
  1061.     private function goToMonsum($programBatch $batch$settingsApplication $application$member$team$applicantsTeam$user)
  1062.     {
  1063.         $em $this->entityManager;
  1064.         if ($program->getSlug() == 'membership') {
  1065.             // assume that everything went right
  1066.             // save member, assign member to team, save application
  1067.             $data['email'] = $application->getEmail();
  1068.             $data['name'] = $application->getPerson();
  1069.             $adminEmail $application->getEmail();
  1070.             if (!$user) {
  1071.                 $member $em->getRepository(Member::class)->createGuestMemberIfNotExists($data$team$adminEmail);
  1072.             } else {
  1073.                 $applicantsTeamMember $em->getRepository(Member::class)->setTeamAssignment($member$applicantsTeam"MA"$adminEmail);
  1074.             }
  1075.             $account $this->getAccountBySlug($batch->getSlug());
  1076.             if (!$customer $em->getRepository(Customer::class)->findPrimaryMonsumAccount($member$account)) {
  1077.                 $team $em->getRepository(Team::class)->createTeamByMembershipApplicant($member);
  1078.                 $customer $this->setMonsumAccountIfNotExists($member$team$application$account);
  1079.             }
  1080.             $productNumber $batch->getBatchNumber();
  1081.             $customer $em->getRepository(Customer::class)->setCheckoutData($customer$account$productNumber$member->getId());
  1082.             if ($batch->getTemplate() == 'membership-per-api') {
  1083.                 $login $em->getRepository(Customer::class)->getLoginByAccount($customer->getAccount());
  1084.                 $payload json_encode([
  1085.                     'SERVICE' => "subscription.create",
  1086.                     'DATA' => [
  1087.                         'CUSTOMER_ID' => "{$customer->getCustomerId()}",
  1088.                         'ARTICLE_NUMBER' => $settings['monsumArticleNumber'],
  1089.                     ],
  1090.                 ]);
  1091.                 $feedback $this->callbackService->curl_get_monsum_all($payload$login);
  1092.                 $feedback json_decode($feedback);
  1093.                 if (isset($feedback->RESPONSE->STATUS) and $feedback->RESPONSE->STATUS == "success") {
  1094.                     $subscriptionId $feedback->RESPONSE->SUBSCRIPTION_ID;
  1095.                     $application->setEditStatus("sucess:subscriptionId=={$subscriptionId}");
  1096.                     $application $em->getRepository(Application::class)->setHistory($application$application->getEditMessage());
  1097.                     $application->setApplicationStatus('applied');
  1098.                     $em->persist($application);
  1099.                     $em->flush();
  1100.                     ## assign to team ##
  1101.                     $virtualTeam array_key_exists('virtualTeam'$settings) ? $settings['virtualTeam'] : 'applicants';
  1102.                     $funnelTeam $em->getRepository(Team::class)->getVirtualTeamByName($virtualTeam);
  1103.                     $memberTeam $em->getRepository(Member::class)->setTeamAssignment($member$funnelTeam"MA"$adminEmail);
  1104.                     $action "finish";
  1105.                     if ($settings['routeName'] != 'apply_program_home' && $settings['routeName'] != 'apply_program_home_lang') {
  1106.                         $route $settings['routeName'];
  1107.                         if ($route == "schnuppermitgliedschaft_buchen_de") {
  1108.                             $route "schnuppermitgliedschaft_buchen_welcome_de";
  1109.                         } elseif ($route == "schnuppermitgliedschaft_team_buchen_de") {
  1110.                             $route "schnuppermitgliedschaft_team_buchen_welcome_de";
  1111.                         }
  1112.                         $targetPath $this->generateUrl($route, ['id' => $application->getId()]);
  1113.                     } else {
  1114.                         $targetPath $this->generateUrl('apply_program_home', ['programSlug' => $application->getProgramSlug(), 'batchSlug' => $application->getBatchSlug(), 'id' => $application->getId()]);
  1115.                     }
  1116.                     if (!$user) {
  1117.                         $loginLink $this->loginService->getLoginLinkByTargetPath($member->getEmail(), $targetPath);
  1118.                         return $this->redirect($loginLink);
  1119.                     } else {
  1120.                         return $this->redirect($targetPath);
  1121.                     }
  1122.                 } else {
  1123.                     $application->setEditStatus("error:monsum-purchase-failed");
  1124.                     $em->persist($application);
  1125.                     $em->flush();
  1126.                     $action "error";
  1127.                 }
  1128.             } else {
  1129.                 $application $em->getRepository(Application::class)->setProcessGoToMonsum($application);
  1130.                 $application $em->getRepository(Application::class)->setHistory($application$application->getEditMessage());
  1131.                 $application->setApplicationStatus('applied');
  1132.                 $em->persist($application);
  1133.                 $em->flush();
  1134.                 $promocode $application->getRecommendedBy() ? 'welcome-startplatz' '';
  1135.                 return $this->redirect($this->generateUrl('apply_program_monsum-checkout', [
  1136.                     'id' => $application->getId(),
  1137.                     'programSlug' => $program->getSlug(),
  1138.                     'batchSlug' => $batch->getSlug(),
  1139.                     'customerId' => $customer->getHash(),
  1140.                     'promocode' => $promocode,
  1141.                 ]));
  1142.             }
  1143.         }
  1144.     }
  1145.     private function setEditWidgetByTemplate($template)
  1146.     {
  1147.         switch ($template) {
  1148.             case "accelerator":
  1149.                 $editWidget '@StartPlatzRheinlandPitchBundle/Apply/_edit.accelerator.widget.html.twig';
  1150.                 break;
  1151.             case "membership":
  1152.                 $editWidget '@StartPlatzRheinlandPitchBundle/Apply/_edit.membership.widget.html.twig';
  1153.                 break;
  1154.             case "registration":
  1155.             case "businessclub":
  1156.             case "event":
  1157.             case "speed-networking":
  1158.             case "sign-up":
  1159.                 $editWidget '@StartPlatzRheinlandPitchBundle/Apply/_edit.registration.widget.html.twig';
  1160.                 break;
  1161.             case "nft":
  1162.                 $editWidget '@StartPlatzRheinlandPitchBundle/Apply/_edit.nft.widget.html.twig';
  1163.                 break;
  1164.             default:
  1165.                 $editWidget '@StartPlatzRheinlandPitchBundle/Apply/_edit.default.widget.html.twig';
  1166.                 break;
  1167.         }
  1168.         /*
  1169.         these templates are implemented as of 19.10.2021
  1170.         accelerator 25
  1171.         businessclub 8
  1172.         effzeh 1
  1173.         event 37
  1174.         feedback-zu-deiner-startup-idee 46
  1175.         membership 13
  1176.         membership-per-api 2
  1177.         registration 18
  1178.         rheinland-pitch 122
  1179.         sign-up 2
  1180.         speed-networking 161
  1181.         startup-tools 19
  1182.         */
  1183.         return $editWidget;
  1184.     }
  1185.     private function getLandingPageDescription($type)
  1186.     {
  1187.         if ($type == 'default-de') {
  1188.             $description "
  1189.                     <section>
  1190.                         <ul>
  1191.                             <li>Du m&ouml;chtest wissen, wie Du am STARTPLATZ Mitglied werden kannst?
  1192.                             <ul>
  1193.                                 <li>=> <a href=\/tarife/\">Dann informiere Dich auf unserer Mitgliedschafts-Seite</a></li>
  1194.                             </ul>
  1195.                             </li>
  1196.                             <li>Du m&ouml;chtest wissen, welche Konferenzr&auml;ume Du am STARTPLATZ buchen kannst?
  1197.                             <ul>
  1198.                                 <li>=> Dann informiere Dich zu den <a href=\"/koeln-tagungsraeume-und-konferenzraeume/\">Konferenzr&auml;umen in K&ouml;ln</a> oder zu den <a href=\"/duesseldorf-tagungsraeume-und-konferenzraeume/\">Konferenzr&auml;umen in D&uuml;sseldorf</a></li>
  1199.                             </ul>
  1200.                             </li>
  1201.                             <li>Du m&ouml;chtest wissen, welche Workshops oder Events am STARTPLATZ stattfinden?
  1202.                             <ul>
  1203.                                 <li>=> <a href=\"/events/list\">Dann informiere Dich auf unseren Event-Seiten</a></li>
  1204.                             </ul>
  1205.                             </li>
  1206.                         </ul>
  1207.                     </section>
  1208.                     ";
  1209.         } else {
  1210.             $description "
  1211.                     <ul>
  1212.                         <li>Do you want to explore more options within STARTPLATZ?
  1213.                         <ul>
  1214.                             <li>=> <a href=\/tarife/\">go to our Membership Page</a></li>
  1215.                         </ul>
  1216.                         </li>
  1217.                         <li>Do you want to book additional conference rooms at STARTPLATZ?
  1218.                         <ul>
  1219.                             <li>=> Go to <a href=\"/koeln-tagungsraeume-und-konferenzraeume/\">Konferenzr&auml;umen in K&ouml;ln</a> or go to <a href=\"/duesseldorf-tagungsraeume-und-konferenzraeume/\">Konferenzr&auml;umen in D&uuml;sseldorf</a></li>
  1220.                         </ul>
  1221.                         </li>
  1222.                         <li>Do you want to know more about current events at STARTPLATZ?
  1223.                         <ul>
  1224.                             <li>=> <a href=\"/events/list\">Go to our events page</a></li>
  1225.                         </ul>
  1226.                         </li>
  1227.                     </ul>
  1228.                     ";
  1229.         }
  1230.         return $description;
  1231.     }
  1232.     private function setActionByProgramSlug(Application $application)
  1233.     {
  1234.         switch ($application->getTemplate()) {
  1235.             case "rheinland-pitch":
  1236.             case "rheinland-pitch-web3":
  1237.             case "accelerator":
  1238.                 $action "continue";
  1239.                 break;
  1240.             case "membership":
  1241.                 $action "goToMonsum";
  1242.                 break;
  1243.             default:
  1244.                 $action "finish";
  1245.                 break;
  1246.         }
  1247.         // only in case of membership the program slug counts more
  1248.         if ($application->getProgramSlug() == 'membership') {
  1249.             $action "goToMonsum";
  1250.         }
  1251.         return $action;
  1252.     }
  1253.     private function setApplicationStatusByTemplate(Application $application)
  1254.     {
  1255.         $em $this->entityManager;
  1256.         switch ($application->getTemplate()) {
  1257.             case "rheinland-pitch":
  1258.             case "rheinland-pitch-web3":
  1259.             case "accelerator":
  1260.                 $application $em->getRepository(Application::class)->setApplicationStarted($application);
  1261.                 break;
  1262.             default:
  1263.                 $application $em->getRepository(Application::class)->setApplicationApplied($application);
  1264.                 break;
  1265.         }
  1266.         return $application;
  1267.     }
  1268.     private function updateApplicationByTeam(Application $applicationTeam $team)
  1269.     {
  1270.         $em $this->entityManager;
  1271.         $application->setTeamId($team->getId());
  1272.         $application->setStartupName($team->getShortName());
  1273.         $application->setCity($team->getAddressCity());
  1274.         $application->setTeamSize($team->getNEmployees());
  1275.         $application->setWebsiteUrl($team->getHomepage());
  1276.         if ($team->getStartupId()) {
  1277.             $startup $em->getRepository(Startup::class)->find($team->getStartupId());
  1278.             $application->setIdeaPitch($startup->getOneSentencePitch());
  1279.             $application->setIndustry($startup->getIndustry());
  1280.             $application->setStartupId($team->getStartupId());
  1281.         }
  1282.         return $application;
  1283.     }
  1284.     /**
  1285.      * Snapshot member data at registration time for historical analysis.
  1286.      * Captures tags, membership status, UTM source, and KI-Kompetenz at the moment of registration.
  1287.      */
  1288.     private function setMemberSnapshotAtRegistration(Application $applicationMember $member): void
  1289.     {
  1290.         // Capture member tags at registration
  1291.         $application->setMemberTagsAtRegistration($member->getTags());
  1292.         // Capture community membership status
  1293.         $application->setWasCommunityMemberAtRegistration($member->getHasCommunityMembership() ?? false);
  1294.         // Check if member was a physical/coworking member at registration time
  1295.         $isPhysicalMember $member->getPhysicalMembershipStarted() !== null
  1296.             && ($member->getPhysicalMembershipEnded() === null
  1297.                 || $member->getPhysicalMembershipEnded() > new \DateTime());
  1298.         $application->setWasPhysicalMemberAtRegistration($isPhysicalMember);
  1299.         // Capture member's original UTM source (first touch attribution)
  1300.         $application->setMemberUtmSourceAtRegistration($member->getUtmSource());
  1301.         // Capture member's KI-Kompetenz level at registration
  1302.         $application->setKiKompetenzAtRegistration($member->getKiKompetenz());
  1303.     }
  1304.     private function setTeam($member$settings$teamIdTeam $applicantsTeam)
  1305.     {
  1306.         $em $this->entityManager;
  1307.         if ($settings['isTeamNeeded']) {
  1308.             if ($teamId == 'create' or $teamId == 0) {
  1309.                 $team $em->getRepository(Team::class)->setNewTeamForApplication($member$settings);
  1310.             } else {
  1311.                 if ($settings['isSignUp']) {
  1312.                     // in this case virtual teams are okay
  1313.                     $team $em->getRepository(Team::class)->find($teamId);
  1314.                 } else {
  1315.                     $virtualTeams $em->getRepository(Team::class)->findKeysOfVirtualTeams();
  1316.                     if (in_array($member->getTeamId(), $virtualTeams)) {
  1317.                         $team $em->getRepository(Team::class)->setNewTeamForApplication($member$settings);
  1318.                     } else {
  1319.                         $team $em->getRepository(Team::class)->find($teamId);
  1320.                     }
  1321.                 }
  1322.             }
  1323.         } else {
  1324.             // in this case we need only the virtual team related with that batch
  1325.             $team $applicantsTeam;
  1326.         }
  1327.         return $team;
  1328.     }
  1329.     private function evaluateAliasSlug($routeName)
  1330.     {
  1331.         $em $this->entityManager;
  1332.         $status "";
  1333.         $message "";
  1334.         $todo "";
  1335.         $data = ['program' => false'batch' => false];
  1336.         $programSlug 'membership';
  1337.         switch ($routeName) {
  1338.             case "startup-academy-test-mitgliedschaft_buchen_de":
  1339.                 $batchSlug '16127-test-trial-startup-academy-community-membership';
  1340.                 break;
  1341.             case "schnuppermitgliedschaft_buchen_de":
  1342.             case "schnuppermitgliedschaft_buchen_welcome_de":
  1343.             case "schnuppermitgliedschaft_buchen_en":
  1344.                 $batchSlug '16017-cgn-trial-community-membership';
  1345.                 break;
  1346.             case "schnuppermitgliedschaft_team_buchen_de":
  1347.             case "schnuppermitgliedschaft_team_buchen_welcome_de":
  1348.                 $batchSlug '17047-cgn-trial-startup-membership';
  1349.                 break;
  1350.             case "free-token":
  1351.                 $batchSlug 'free-to-own-token-meetup-24112022';
  1352.                 break;
  1353.             default:
  1354.                 $batchSlug '16017-cgn-trial-community-membership';
  1355.                 break;
  1356.         }
  1357.         if (!$batch $em->getRepository(Batch::class)->findOneBy(['slug' => $batchSlug])) {
  1358.             return false;
  1359.         } else {
  1360.             $status "success";
  1361.             $data = ['batch' => $batch'program' => $batch->getProgram()];
  1362.             $response = [
  1363.                 'status' => $status,
  1364.                 'todo' => $todo,
  1365.                 'message' => $message,
  1366.                 'data' => $data,
  1367.             ];
  1368.             return $response;
  1369.         }
  1370.     }
  1371.     private function evaluateApplicationEmail(Application $application$memberTeam $team$settings$user)
  1372.     {
  1373.         $em $this->entityManager;
  1374.         $status "";
  1375.         $message "";
  1376.         $todo "";
  1377.         $data = ['application' => $application'member' => $member];
  1378.         $isEmailRegistered $em->getRepository(Member::class)->isEmailRegistered($application->getEmail());
  1379.         $isMemberloggedIn $user true false;
  1380.         $existingApplication false;
  1381.         if ($isEmailRegistered) {
  1382.             $existingMember $em->getRepository(Member::class)->findOneBy(['email' => $application->getEmail()]);
  1383.             $existingApplication $this->checkForMultipleApplications($team$existingMember$settings);
  1384.         }
  1385.         // ['Anonymous' => 'anonymous', 'Login' => 'login', 'Community Membership'=>'hasCommunityMembership', 'Startup Membership'=>'hasStartupMembership'],'required'=> false])
  1386.         switch ($settings['access']) {
  1387.             case "anonymous":
  1388.                 if ($isEmailRegistered == false and $isMemberloggedIn == false) {
  1389.                     if ($settings['isNeedsEmailValidation']) {
  1390.                         $status "error";
  1391.                         $todo "validateEmail";
  1392.                         $message "Email is not yet registered. Email needs to be validated";
  1393.                         $application $em->getRepository(Application::class)->setErrorValidateEmail($application);
  1394.                     } else {
  1395.                         $status "process";
  1396.                         $todo "notValidatedEmail";
  1397.                         $message "Email will be registered without being validated";
  1398.                         $application $em->getRepository(Application::class)->setEditStatus($application$status$todo$message);
  1399.                     }
  1400.                     $data['email'] = $application->getEmail();
  1401.                     $data['firstName'] = $application->getFirstName();
  1402.                     $data['lastName'] = $application->getLastName();
  1403.                     $data['name'] = $application->getPerson();
  1404.                     $adminEmail $application->getEmail();
  1405.                     if ($settings['isTeamNeeded']) {
  1406.                         $memberType "GF";
  1407.                     } else {
  1408.                         $memberType "MA";
  1409.                     }
  1410.                     $member $em->getRepository(Member::class)->createGuestMemberIfNotExists($data$team$adminEmail$memberType);
  1411.                     $application->setMemberId($member->getId());
  1412.                     $this->setMemberSnapshotAtRegistration($application$member);
  1413.                     $application->setTeamId($team->getId());
  1414.                     $data = ['application' => $application'member' => $member];
  1415.                 }
  1416.                 if ($isEmailRegistered == false and $isMemberloggedIn == true) {
  1417.                     $status "error";
  1418.                     $todo "check2ndAccount";
  1419.                     $message "You are registered at STARTPLATZ with another email address.";
  1420.                     $application->setSecondaryEmail($application->getEmail());
  1421.                     $application->setEmail($member->getEmail());
  1422.                     $data = ['application' => $application'member' => $member];
  1423.                 }
  1424.                 if ($isEmailRegistered == true and $isMemberloggedIn == false) {
  1425.                     // "error"; "validateLogin";
  1426.                     /** @var Member $existingMember */
  1427.                     $isAdmin false;
  1428.                     if ($existingMember) {
  1429.                         // check if member is admin
  1430.                         $user $em->getRepository(User::class)->findOneBy(['memberId' => $existingMember->getId()]);
  1431.                         if ($user->getIsAdmin()) {
  1432.                             $isAdmin true;
  1433.                         }
  1434.                     }
  1435.                     if ($settings['isNeedsLoginValidation'] or $isAdmin) {
  1436.                         $status "error";
  1437.                         $todo "validateLogin";
  1438.                         $message "This email address is already in use. Please login to make your application valid.";
  1439.                     } else {
  1440.                         $status "process";
  1441.                         $todo "notValidatedLogin";
  1442.                         $message "This email address is already in use. Application will be processed without login being validated";
  1443.                     }
  1444.                     if (!$existingApplication) {
  1445.                         $message "This email address is already in use. Please login to make your application valid.";
  1446.                         $application->setMemberId($existingMember->getId());
  1447.                         $this->setMemberSnapshotAtRegistration($application$existingMember);
  1448.                         if (!$team->getId()) {
  1449.                             if ($settings['createAlwaysNewTeam']) {
  1450.                                 $team $em->getRepository(Team::class)->createTeamByApplication($application$settings$member);
  1451.                                 $application->setTeamId($team->getId());
  1452.                                 $em->getRepository(Member::class)->setTeamAssignment($existingMember$team'GF'$application->getEmail());
  1453.                             } else {
  1454.                                 $application->setTeamId($existingMember->getTeamId());
  1455.                             }
  1456.                         }
  1457.                     } else {
  1458.                         $message "This email address is already in use and there is already an application of your team. Please login to edit your application.";
  1459.                         $application $existingApplication;
  1460.                     }
  1461.                     $application $em->getRepository(Application::class)->setEditStatus($application$status$todo$message);
  1462.                     $data = ['application' => $application'member' => $existingMember];
  1463.                 }
  1464.                 if ($isEmailRegistered == true and $isMemberloggedIn == true) {
  1465.                     if ($user->getEmail() != $application->getEmail()) {
  1466.                         // "error"; "validateLogin";
  1467.                         $status "error";
  1468.                         $todo "validateLogin";
  1469.                         $application $em->getRepository(Application::class)->setErrorValidateLogin($application);
  1470.                     } else {
  1471.                         if ($application->getProgramSlug() == "membership") {
  1472.                             $status "process";
  1473.                             $todo "goToMonsum";
  1474.                             $message "You need to check out";
  1475.                         } else {
  1476.                             $status "success";
  1477.                             $todo "loggedIn";
  1478.                             $message "We will register your application";
  1479.                         }
  1480.                         $data = ['application' => $application'member' => $member];
  1481.                     }
  1482.                 }
  1483.                 $application->setEditStatus("{$status}:{$todo}");
  1484.                 $application->setEditMessage($message);
  1485.                 break;
  1486.             case "login":
  1487.             case "hasCommunityMembership":
  1488.             case "hasStartupMembership":
  1489.                 if ($existingApplication) {
  1490.                     $data['application'] = $existingApplication;
  1491.                 }
  1492.                 break;
  1493.             default:
  1494.                 break;
  1495.         }
  1496.         $response = [
  1497.             'status' => $status,
  1498.             'todo' => $todo,
  1499.             'message' => $message,
  1500.             'data' => $data,
  1501.             'hasExistingApplication' => !!$existingApplication,
  1502.         ];
  1503.         return $response;
  1504.     }
  1505.     private function checkForMultipleApplications(Team $teamMember $member$settings)
  1506.     {
  1507.         $em $this->entityManager;
  1508.         $application null;
  1509.         if (!$settings['isMultipleApplicationsPerTeam'] and $team->getId()) {
  1510.             $application $em->getRepository(Application::class)->findOneBy(['teamId' => $team->getId(), 'batchId' => $settings['batchId']]);
  1511.         } else {
  1512.             if (!$settings['isMultipleApplicationsPerMember']) {
  1513.                 $application $em->getRepository(Application::class)->findOneBy(['memberId' => $member->getId(), 'batchId' => $settings['batchId']]);
  1514.             }
  1515.         }
  1516.         return $application;
  1517.     }
  1518.     private function checkPlausibility(Application $applicationMember $memberTeam $team$settings)
  1519.     {
  1520.         $em $this->entityManager;
  1521.         $status "";
  1522.         $message "";
  1523.         $todo "";
  1524.         $data = ['application' => $application];
  1525.         switch ($settings['programSlug']) {
  1526.             case "rheinland-pitch":
  1527.             case "accelerator":
  1528.                 // plausibility checks
  1529.                 if ($em->getRepository(Application::class)->findByCriteriaButNotTeam(['programSlug' => $application->getProgramSlug(), 'batchSlug' => $application->getBatchSlug(), 'startupName' => $application->getStartupName()], $team)) {
  1530.                     $status "error";
  1531.                     $todo "changeName";
  1532.                     $message "An Application with this name already exists. Please change name!";
  1533.                 }
  1534.                 if (!$application->getIdeaPitch()) {
  1535.                     $status "error";
  1536.                     $todo "fillOutIdeaPitch";
  1537.                     $message "Please specify your idea pitch!";
  1538.                 }
  1539.                 $wordsCount str_word_count($application->getIdeaPitch() ?? '');
  1540.                 if ($wordsCount 150) {
  1541.                     $status "error";
  1542.                     $todo "shortenIdeaPitch";
  1543.                     $message "Your idea pitch contains {$wordsCount} words, max words is 150, please reduce the length of your idea pitch!";
  1544.                 }
  1545.                 break;
  1546.             default:
  1547.                 break;
  1548.         }
  1549.         if ($status "") {
  1550.             $application->setEditStatus("{$status}:{$todo}");
  1551.             $application->setEditMessage($message);
  1552.             $data = ['application' => $application];
  1553.         }
  1554.         $response = [
  1555.             'status' => $status,
  1556.             'todo' => $todo,
  1557.             'message' => $message,
  1558.             'data' => $data,
  1559.         ];
  1560.         return $response;
  1561.     }
  1562.     private function setMonsumAccountIfNotExists(Member $memberTeam $teamApplication $application$account)
  1563.     {
  1564.         $em $this->entityManager;
  1565.         $adminEmail $member->getEmail();
  1566.         $responseContent = [];
  1567.         $teamId $team->getId();
  1568.         $customer null;
  1569.         $monsumCustomer null;
  1570.         $settings = [
  1571.             'adminEmail' => $adminEmail,
  1572.             'location' => $em->getRepository(Customer::class)->getLocationByAccount($account),
  1573.             'account' => $account,
  1574.             'accountHash' => $em->getRepository(Customer::class)->getAccountHashByAccount($account),
  1575.         ];
  1576.         $login $em->getRepository(Customer::class)->getLoginByAccount($account);
  1577.         $payload json_encode([
  1578.             'SERVICE' => "customer.get",
  1579.             'FILTER' => [
  1580.                 'CUSTOMER_EXT_UID' => "{$team->getId()}",
  1581.             ],
  1582.         ]);
  1583.         $feedback $this->callbackService->curl_get_monsum_all($payload$login);
  1584.         $feedback json_decode($feedback);
  1585.         if (isset($feedback->RESPONSE->CUSTOMERS[0])) {
  1586.             $responseContent[] = "Team {$teamId} has already account in Monsum";
  1587.             $customer $feedback->RESPONSE->CUSTOMERS[0];
  1588.         } else {
  1589.             $responseContent[] = "New account will be created for team {$teamId} in Monsum";
  1590.             $customerSettings $em->getRepository(Customer::class)->getCustomerSettingsByTeamAndMember($team$member);
  1591.             $payload json_encode([
  1592.                 'SERVICE' => "customer.create",
  1593.                 'DATA' => $customerSettings,
  1594.             ]);
  1595.             $feedback $this->callbackService->curl_get_monsum_all($payload$login);
  1596.             $feedback json_decode($feedback);
  1597.             $monsumResponse $feedback->RESPONSE;
  1598.             if (isset($monsumResponse->ERRORS)) {
  1599.                 $responseContent[] = "ERROR ======== ERROR";
  1600.                 $responseContent[] = $monsumResponse->ERRORS;
  1601.                 $responseContent[] = $feedback;
  1602.             } else {
  1603.                 $responseContent[] = $monsumResponse;
  1604.                 if ($monsumResponse->STATUS == "success") {
  1605.                     $customerId $monsumResponse->CUSTOMER_ID;
  1606.                     $payload $em->getRepository(Customer::class)->getPayloadSingleCustomerByCustomerId($customerId);
  1607.                     $feedback $this->callbackService->curl_get_monsum_all($payload$login);
  1608.                     if ($feedback json_decode($feedback)) {
  1609.                         $customer $feedback->RESPONSE->CUSTOMERS[0];
  1610.                     } else {
  1611.                         $responseContent[] = "ERROR: could not decode feedback from monsum";
  1612.                         $responseContent[] = $feedback;
  1613.                     }
  1614.                 }
  1615.             }
  1616.         }
  1617.         if ($customer) {
  1618.             $monsumCustomer $em->getRepository(Customer::class)->createOrUpdateMonsumCustomerByTeam($customer$settings$team);
  1619.         }
  1620.         return $monsumCustomer;
  1621.     }
  1622.     #[Route('/apply-add-application/{memberId}/{batchId}/'name'apply_add-application')]
  1623.     public function addApplicationAction(Request $request$batchId$memberId)
  1624.     {
  1625.         $em $this->entityManager;
  1626.         $redirect Utility::getRedirectTarget($request);
  1627.         $now = new datetime();
  1628.         $batch $em->getRepository(Batch::class)->findOneBy(['id' => $batchId]);
  1629.         $program $em->getRepository(Program::class /*Startup Program*/)->findOneBy(['id' => $batch->getProgramId()]);
  1630.         $member $em->getRepository(Member::class)->findOneBy(['id' => $memberId]);
  1631.         // check if settings contains necessary setters
  1632.         $batch $em->getRepository(Batch::class)->checkLegacyData($batch);
  1633.         $settings $em->getRepository(Application::class)->getSettingsProgram($program$batch);
  1634.         /** @var User $user */
  1635.         $user $this->getUser();
  1636.         $adminEmail $user->getEmail();
  1637.         $em->getRepository(User::class)->writeActivity($user);
  1638.         // falls member Mitglied in mehreren teams ist, auswählen lassen, ob für bestehendes team einreichen oder für neues team
  1639.         $virtualTeam array_key_exists('virtualTeam'$settings) ? $settings['virtualTeam'] : 'applicants';
  1640.         $applicantsTeam $em->getRepository(Team::class)->getVirtualTeamByName($virtualTeam);
  1641.         // check if $member is part of specified - virtual team
  1642.         if (!$applicantsTeamMember $em->getRepository(MemberTeam::class)->findOneBy(['team' => $applicantsTeam'member' => $member])) {
  1643.             $em->getRepository(Member::class)->setTeamAssignmentByUser($user$member->getId(), $applicantsTeam->getId());
  1644.         }
  1645.         $id $member->getTeamId();
  1646.         $team $em->getRepository(Team::class)->findOneBy(['id' => $id]);
  1647.         $teamMember $em->getRepository(MemberTeam::class)->findOneBy(['team' => $team'member' => $member]);
  1648.         $teamId $team->getId();
  1649.         if ($batch->getIsMultipleApplicationsPerTeam()) {
  1650.             if (!$application $em->getRepository(Application::class)->findOneBy(['programSlug' => $program->getSlug(), 'batchSlug' => $batch->getSlug(), 'memberId' => $member->getId()])) {
  1651.                 $application $em->getRepository(Application::class)->createApplicationIfNotExists($program$batch$team$member$adminEmail);
  1652.             }
  1653.         } else {
  1654.             if (!$application $em->getRepository(Application::class)->findOneBy(['programSlug' => $program->getSlug(), 'batchSlug' => $batch->getSlug(), 'teamId' => $teamId])) {
  1655.                 $application $em->getRepository(Application::class)->createApplicationIfNotExists($program$batch$team$member$adminEmail);
  1656.             }
  1657.         }
  1658.         $application->setBatchStatus('applicant');
  1659.         $application->setApplicationStatus('applied');
  1660.         $em->persist($application);
  1661.         $em->flush();
  1662.         $batch $em->getRepository(Batch::class)->updateNumbers($batch);
  1663.         $this->addFlash('notice''SUCCESS ' "Application created for member {$member->getName()} and batch {$batch->getName()}");
  1664.         return $this->redirect($this->generateUrl($redirect->path, (array)$redirect->parameters));
  1665.     }
  1666.     #[Route('/apply/{programSlug}/{batchSlug}/action/get-access'name'apply_program_get_access')]
  1667.     public function getAccessAction(Request $request$programSlug$batchSlug)
  1668.     {
  1669.         $em $this->entityManager;
  1670.         $data $request->request->all();
  1671.         if (!($data['email'] and $data['firstName'] and $data['lastName'])) {
  1672.             $this->addFlash('notice''ERROR Please fill in your data');
  1673.             return $this->redirect($this->generateUrl('apply_program_home', ['programSlug' => $programSlug'batchSlug' => $batchSlug]));
  1674.         }
  1675.         // https://symfony.com/doc/4.4/validation/raw_values.html
  1676.         $validator Validation::createValidator();
  1677.         $constraint = new Assert\Collection([
  1678.             // the keys correspond to the keys in the input array
  1679.             'firstName' => new Assert\Length(['min' => 3]),
  1680.             'lastName' => new Assert\Length(['min' => 3]),
  1681.             'email' => new Assert\Email(),
  1682.         ]);
  1683.         if ($violations $validator->validate($data$constraint)) {
  1684.             $error false;
  1685.             foreach ($violations as $violation) {
  1686.                 $this->addFlash('notice''ERROR ' $violation->getMessage());
  1687.                 $error true;
  1688.             }
  1689.             if ($error) {
  1690.                 return $this->redirect($this->generateUrl('apply_program_home', ['programSlug' => $programSlug'batchSlug' => $batchSlug]));
  1691.             }
  1692.         }
  1693.         if (!$program $em->getRepository(Program::class /*Startup Program*/)->findOneBy(['slug' => $programSlug])) {
  1694.             $this->addFlash('notice''ERROR Sorry, no program found');
  1695.             return $this->redirect($this->generateUrl('apply_home', []));
  1696.         }
  1697.         if (!$batch $em->getRepository(Batch::class)->findOneBy(['slug' => $batchSlug])) {
  1698.             $this->addFlash('notice''ERROR Sorry, no batch found');
  1699.             return $this->redirect($this->generateUrl('apply_home', []));
  1700.         }
  1701.         $settingsProgram $em->getRepository(Application::class)->getSettingsProgram($program$batch);
  1702.         //$adminEmail = $data['email'];
  1703.         $userEmail $data['email'];
  1704.         $adminEmail "support@startplatz.de";
  1705.         // check if there is the defined virtual team
  1706.         $virtualTeam array_key_exists('virtualTeam'$settingsProgram) ? $settingsProgram['virtualTeam'] : 'applicants';
  1707.         $team $em->getRepository(Team::class)->getVirtualTeamByName($virtualTeam);
  1708.         $member $em->getRepository(Member::class)->createGuestMemberIfNotExists($data$team$userEmail);
  1709.         $loginLink $this->loginService->getLoginLinkByTargetPath($member->getEmail(), $this->generateUrl('apply_program_home', ['programSlug' => $programSlug'batchSlug' => $batchSlug]));
  1710.         $mailSubject "{$settingsProgram['programName']} - Access Code - Application Area";
  1711.         $mailText $this->renderView(
  1712.             '@StartPlatzRheinlandPitchBundle/Apply/_mail.get.access.txt.twig',
  1713.             [
  1714.                 'member' => $member,
  1715.                 'loginLink' => $loginLink,
  1716.                 'settings' => $settingsProgram,
  1717.             ]
  1718.         );
  1719.         $this->callbackService->sendAlertMailPerZapier("{$member->getEmail()}"$mailText$mailSubject$adminEmail);
  1720.         $mailText "
  1721. Es gibt eine Anmeldung von {$data['firstName']} {$data['lastName']}   
  1722. Bewerber im Program {$settingsProgram['programName']} mit der E-Mail-Adresse {$data['email']}
  1723. und der Bitte um Zugang zum internen Bereich
  1724.         ";
  1725.         $this->callbackService->sendAlertMailPerZapier($adminEmail$mailText"{$settingsProgram['programName']} - Registration internal Area"$userEmail);
  1726.         $this->callbackService->setSlackMonitoring($mailText);
  1727.         $this->addFlash('notice''SUCCESS Thank you for your message; we have sent you an access code');
  1728.         return $this->redirect($this->generateUrl('apply_program_home', ['programSlug' => $programSlug'batchSlug' => $batchSlug]));
  1729.     }
  1730.     #[Route('/apply/{programSlug}/{batchSlug}/action/feedback'name'apply_program_feedback')]
  1731.     public function receiveFeedbackAction(Request $request$programSlug$batchSlug)
  1732.     {
  1733.         $em $this->entityManager;
  1734.         $data $request->request->all();
  1735.         if (!array_key_exists('context'$data)) {
  1736.             $data['context'] = "Application Platform";
  1737.         }
  1738.         if (!$data['email']) {
  1739.             $this->addFlash('notice''ERROR Please specify your email address');
  1740.             return $this->redirect($this->generateUrl('apply_program_home', ['programSlug' => $programSlug'batchSlug' => $batchSlug]));
  1741.         }
  1742.         $mailText "
  1743. Es gibt eine Nachricht von {$data['name']}        
  1744. mit der E-Mail-Adresse {$data['email']}
  1745. und dem Betreff: {$data['subject']}
  1746. und dem Inhalt:
  1747. {$data['message']}
  1748.         ";
  1749.         $this->callbackService->sendAlertMailPerZapier($this->alertRecipientService->get('alert.rp_contact'), $mailText$data['context'] . ": " $data['subject'], "support@startplatz.de");
  1750.         $this->callbackService->setSlackMonitoring($mailText);
  1751.         $this->addFlash('notice''SUCCESS Thank you for your message');
  1752.         return $this->redirect($this->generateUrl('apply_program_home', ['programSlug' => $programSlug'batchSlug' => $batchSlug]));
  1753.     }
  1754.     #[Route('/apply/{programSlug}/{batchSlug}/{id}/account'name'apply_program_account')]
  1755.     /**
  1756.      * @IsGranted("ROLE_USER")
  1757.      */
  1758.     public function accountAction(Request $request$programSlug$batchSlug$id)
  1759.     {
  1760.         $em $this->entityManager;
  1761.         if (!$user $this->getUser()) {
  1762.             return $this->redirect($this->generateUrl('apply_home', []));
  1763.         }
  1764.         $em->getRepository(User::class)->writeActivity($user);
  1765.         $form $this->createForm(SetPasswordFormType::class);
  1766.         $form->handleRequest($request);
  1767.         if ($form->isSubmitted() && $form->isValid()) {
  1768.             /** @var User $user */
  1769.             $user $this->getUser();
  1770.             $data $form->getData();
  1771.             $password $data['new_password'];
  1772.             $encodedPassword $this->encoder->encodePassword($user$password);
  1773.             $user->setPassword($encodedPassword);
  1774.             $em->getRepository(User::class)->add($user);
  1775.             $message = new Email();
  1776.             $message->to($user->getEmail());
  1777.             $message->from('info@startplatz.de');
  1778.             $message->subject('Your password for startplatz.de has been changed');
  1779.             $message->text(
  1780.                 $this->renderView(
  1781.                     '@StartPlatzUserBundle/Mails/passwordChangeAlert.txt.twig',
  1782.                     [
  1783.                         'email' => $user->getEmail(),
  1784.                         'password' => $password,
  1785.                     ]
  1786.                 )
  1787.             );
  1788.             $this->mailer->send($message);
  1789.             $this->addFlash('notice''SUCCESS ' "Passwort has been set");
  1790.             return $this->redirect($this->generateUrl('apply_program_home', ['id' => $id'programSlug' => $programSlug'batchSlug' => $batchSlug]));
  1791.         }
  1792.         return $this->render('@StartPlatzRheinlandPitchBundle/Apply/account.html.twig', [
  1793.             'form' => $form->createView(),
  1794.             'redirectUrl' => base64_encode(json_encode(['path' => 'apply_program_home''parameters' => ['programSlug' => $programSlug'batchSlug' => $batchSlug]])),
  1795.         ]);
  1796.     }
  1797.     #[Route('/apply/{programSlug}/{batchSlug}/{id}/uploadPitchDeck'name'apply_program_uploadPitchDeck')]
  1798.     public function uploadPitchDeckAction(Request $request$programSlug$batchSlug$id)
  1799.     {
  1800.         $em $this->entityManager;
  1801.         $now = new datetime();
  1802.         if (!$program $em->getRepository(Program::class /*Startup Program*/)->findOneBy(['slug' => $programSlug])) {
  1803.             $this->addFlash('notice''ERROR Sorry, no program found');
  1804.             return $this->redirect($this->generateUrl('apply_home', []));
  1805.         }
  1806.         if (!$batch $em->getRepository(Batch::class)->findOneBy(['slug' => $batchSlug])) {
  1807.             $this->addFlash('notice''ERROR Sorry, no batch found');
  1808.             return $this->redirect($this->generateUrl('apply_home', []));
  1809.         }
  1810.         $settings $em->getRepository(Application::class)->getSettingsProgram($program$batch);
  1811.         /** @var User $user */
  1812.         if ($user $this->getUser()) {
  1813.             $em->getRepository(User::class)->writeActivity($user);
  1814.         }
  1815.         $isAdminUpload $request->get('isAdminUpload');
  1816.         if (!$application $em->getRepository(Application::class)->findOneBy(['programSlug' => $programSlug'batchSlug' => $batchSlug'id' => $id])) {
  1817.             $this->addFlash('notice''ERROR no application found ');
  1818.             return $this->redirect($this->generateUrl('apply_home', []));
  1819.         }
  1820.         if (!$teamId $application->getTeamId()) {
  1821.             $this->addFlash('notice''ERROR Sorry, no team found');
  1822.             return $this->redirect($this->generateUrl('apply_home', []));
  1823.         }
  1824.         if (!$memberId $application->getMemberId()) {
  1825.             $this->addFlash('notice''ERROR Sorry, no member found');
  1826.             return $this->redirect($this->generateUrl('apply_home', []));
  1827.         }
  1828.         if (!$isAdminUpload) {
  1829.             if (!$em->getRepository(MemberTeam::class)->isMemberOfTeam($memberId$teamId)) {
  1830.                 $this->addFlash('notice''ERROR Sorry, we found a problem with the team access rights');
  1831.                 return $this->redirect($this->generateUrl('apply_home', []));
  1832.             }
  1833.         }
  1834.         $publicId $request->get('PublicId');
  1835.         $uploadTag "application/{$application->getId()}";
  1836.         if (!$isAdminUpload) {
  1837.             $redirectTargetUrl $this->generateUrl('apply_program_home_lang', ['programSlug' => $programSlug'batchSlug' => $batchSlug'lang' => strtolower($application->getLang())]);
  1838.         } else {
  1839.             $redirectTargetUrl $this->generateUrl('allmeda_application_edit', ['id' => $application->getId()]);
  1840.         }
  1841.         return $this->render('@StartPlatzRheinlandPitchBundle/Apply/uploadPitchDeck.html.twig', [
  1842.             'application' => $application,
  1843.             'settings' => $settings,
  1844.             'programSlug' => $programSlug,
  1845.             'batchSlug' => $batchSlug,
  1846.             'program' => $program,
  1847.             'batch' => $batch,
  1848.             'uploadTag' => $uploadTag,
  1849.             'publicId' => $publicId,
  1850.             'isAdminUpload' => $isAdminUpload,
  1851.             'teamId' => $teamId,
  1852.             'memberId' => $memberId,
  1853.             'redirect' => $redirectTargetUrl,
  1854.             'redirectUrl' => base64_encode(json_encode(['path' => 'apply_program_home_lang''parameters' => ['programSlug' => $programSlug'batchSlug' => $batchSlug'lang' => strtolower($application->getLang())]])),
  1855.         ]);
  1856.     }
  1857.     #[Route('/apply/{programSlug}/{batchSlug}/{id}/add-images-by-tag/'name'apply_program_add_images_by_tag')]
  1858.     public function addImagesByTagAction(Request $request$programSlug$batchSlug$id)
  1859.     {
  1860.         $time_start microtime(true);
  1861.         $tag $request->request->get('tag');
  1862.         $redirect Utility::getRedirectTarget($request);
  1863.         $em $this->entityManager;
  1864.         $now = new DateTime();
  1865.         if (!$application $em->getRepository(Application::class)->findOneBy(['id' => $id])) {
  1866.             $response = new Response();
  1867.             $response->setContent(json_encode('ERROR no application found'));
  1868.             $response->headers->set('Content-Type''application/json');
  1869.             return $response;
  1870.         }
  1871.         $result $this->cloudinary->resources_by_tag($tag);
  1872.         $resources $result['resources'];
  1873.         foreach ($resources as $resource) {
  1874.             $publicId $resource['public_id'];
  1875.             $secureUrl $resource['secure_url'];
  1876.             $application->setLinkPitchDeck($secureUrl);
  1877.             $application->setPublicIdPitchDeck($publicId);
  1878.             $application->setEditStatus("feedback:pitchdeckUploaded");
  1879.             $application->setEditMessage("Thank you for uploading your pitch deck.");
  1880.             $em->persist($application);
  1881.             $em->flush();
  1882.         }
  1883.         $response = new Response();
  1884.         $response->setContent(json_encode($result));
  1885.         $response->headers->set('Content-Type''application/json');
  1886.         return $response;
  1887.     }
  1888.     private function getSettingsProgramDefault()
  1889.     {
  1890.         return [
  1891.             "programName" => "Example",
  1892.             "programSlug" => "example",
  1893.             "batchName" => "Batch11",
  1894.             "batchSlug" => "batch11",
  1895.             "applicationStart" => "2019-11-11",
  1896.             "programStart" => "2019-12-11",
  1897.             "programEnd" => "2019-12-11",
  1898.             "applicationStages" => "applied,approved",
  1899.             "programStages" => "applicant,participant,alumni,drop-out,rejected",
  1900.             "programTag" => "example-batch11-participant",
  1901.             "eventId" => "4982",
  1902.             "bgImage" => "https://res.cloudinary.com/startplatz/image/upload/v1573496116/rheinland-pitch/impressions/final-koeln-2017_audience_manor-lux.jpg",
  1903.             "virtualTeam" => "example-team",
  1904.             "status" => "test",
  1905.         ];
  1906.     }
  1907.     #[Route('/apply/administration/batch/test-confirmation-mail/{batchId}'name'apply_test_confirmation-mail')]
  1908.     /**
  1909.      * @IsGranted("ROLE_ADMIN")
  1910.      */
  1911.     public function sendConfirmationTestMail(Request $request$batchId)
  1912.     {
  1913.         $redirect Utility::getRedirectTarget($request);
  1914.         $em $this->entityManager;
  1915.         $reminder null;
  1916.         $sendReminderMail $request->get('sendReminderMail');
  1917.         /** @var User $user */
  1918.         $user $this->getUser();
  1919.         $em->getRepository(User::class)->writeActivity($user);
  1920.         if ($sendReminderMail){
  1921.             $reminder $em->getRepository(Reminder::class)->find($batchId);
  1922.             $batchId $reminder->getBatchId();
  1923.         }
  1924.         /** @var Batch $batch */
  1925.         if (!$batch $em->getRepository(Batch::class)->findOneBy(['id' => $batchId])) {
  1926.             $this->addFlash('notice''ERROR batch not found');
  1927.             return $this->redirect($this->generateUrl($redirect->path, (array)$redirect->parameters));
  1928.         }
  1929.         $member $em->getRepository(Member::class)->find($user->getMemberId());
  1930.         if (!$application $em->getRepository(Application::class)->findOneBy(['memberId'=>$member->getId(), 'batchId'=>$batch->getId()])){
  1931.             $application $em->getRepository(Application::class)->getTemporaryApplicationByBatchAndMember($batch$member);
  1932.             $application $em->getRepository(Application::class)->setApplicationDone($application);
  1933.         }
  1934.         $application->setApplicationStatus('applied');
  1935.         // Start timing
  1936.         $this->stopwatch->start('confirmation_mail');
  1937.         $response $this->sendConfirmationMailToApplicant($user, [], $application$batch$reminder);
  1938.         // Stop timing
  1939.         $stopwatchEvent $this->stopwatch->stop('confirmation_mail');
  1940.         // Get duration and memory usage
  1941.         $duration $stopwatchEvent->getDuration();
  1942.         $memory round($stopwatchEvent->getMemory() / (1024 1024), 2); // Convert to MB and round to 2 decimal places
  1943.         $this->addFlash('notice'"SUCCESS via service: A test confirmation mail has been sent to {$user->getEmail()}. Time: {$duration}ms, Memory: {$memory} MB");
  1944.         return $this->redirect($this->generateUrl($redirect->path, (array)$redirect->parameters));
  1945.     }
  1946.     #[Route('/apply/administration/batch/test-confirmation-mail-service/{batchId}'name'apply_test_confirmation-mail_service')]
  1947.     /**
  1948.      * @IsGranted("ROLE_ADMIN")
  1949.      */
  1950.     public function sendConfirmationTestMailViaService(Request $request$batchId)
  1951.     {
  1952.         $redirect Utility::getRedirectTarget($request);
  1953.         $em $this->entityManager;
  1954.         $reminder null;
  1955.         $sendReminderMail $request->get('sendReminderMail');
  1956.         /** @var User $user */
  1957.         $user $this->getUser();
  1958.         $em->getRepository(User::class)->writeActivity($user);
  1959.         if ($sendReminderMail){
  1960.             $reminder $em->getRepository(Reminder::class)->find($batchId);
  1961.             $batchId $reminder->getBatchId();
  1962.         }
  1963.         /** @var Batch $batch */
  1964.         if (!$batch $em->getRepository(Batch::class)->findOneBy(['id' => $batchId])) {
  1965.             $this->addFlash('notice''ERROR batch not found');
  1966.             return $this->redirect($this->generateUrl($redirect->path, (array)$redirect->parameters));
  1967.         }
  1968.         $member $em->getRepository(Member::class)->find($user->getMemberId());
  1969.         if (!$application $em->getRepository(Application::class)->findOneBy(['memberId'=>$member->getId(), 'batchId'=>$batch->getId()])){
  1970.             $application $em->getRepository(Application::class)->getTemporaryApplicationByBatchAndMember($batch$member);
  1971.             $application $em->getRepository(Application::class)->setApplicationDone($application);
  1972.         }
  1973.         $application->setApplicationStatus('applied');
  1974.         // Start timing
  1975.         $this->stopwatch->start('confirmation_mail');
  1976.         $result $this->confirmationMailService->sendConfirmationMailToApplicant($user$member, [], $application$batch$reminder);
  1977.         // Stop timing
  1978.         $stopwatchEvent $this->stopwatch->stop('confirmation_mail');
  1979.         // Get duration and memory usage
  1980.         $duration $stopwatchEvent->getDuration();
  1981.         $memory round($stopwatchEvent->getMemory() / (1024 1024), 2); // Convert to MB and round to 2 decimal places
  1982.         // Verarbeiten der Nachrichten aus dem Service
  1983.         foreach ($result['messages'] as $message) {
  1984.             $this->addFlash('notice'$message);
  1985.         }
  1986.         // Zusätzliche Flash-Nachricht für Leistungsinformationen
  1987.         $this->addFlash('notice'"Service execution: Time: {$duration}ms, Memory: {$memory} MB");
  1988.         // Status-basierte Nachricht
  1989.         if ($result['status'] === 'success') {
  1990.             $this->addFlash('notice''SUCCESS: Mail sent successfully via service');
  1991.         } else {
  1992.             $this->addFlash('notice''ERROR: Failed to send mail via service');
  1993.         }
  1994.         return $this->redirect($this->generateUrl($redirect->path, (array)$redirect->parameters));
  1995.     }
  1996.     private function sendConfirmationMailToApplicant(User $user$settingsApplication $applicationBatch $batchReminder $reminder null)
  1997.     {
  1998.         $em $this->entityManager;
  1999.         if (!$settings) {
  2000.             $application->setStartupName("Test Startup");
  2001.             $application->setEmail($user->getEmail());
  2002.         }
  2003.         $program $batch->getProgram();
  2004.         $routeParameters = [
  2005.             'programSlug' => $program->getSlug(),
  2006.             'batchSlug' => $batch->getSlug(),
  2007.         ];
  2008.         if (isset($reminder) && $reminder->getType() == 'feedbackMail' && $batch->getSurveyId() > ''){
  2009.             $loginPath = ['path'=>'survey_proceed','parameters'=>['id'=>$batch->getSurveyId(), 'slug'=>"{$program->getSlug()}-{$batch->getSlug()}"]];
  2010.             //$mailTemplate->setLoginPath(json_encode($loginPath));
  2011.             $targetPath $this->generateUrl($loginPath['path'], $loginPath['parameters']);
  2012.         } else {
  2013.             $targetPath $this->generateUrl('apply_program_home'$routeParameters);
  2014.         }
  2015.         $loginLink $this->loginService->getLoginLinkByTargetPath($application->getEmail(), $targetPath);
  2016.         $metaName $batch->getMailDesignTemplate();
  2017.         $designTemplate $em->getRepository(Option::class)->getOptionMetaValuePlain($metaName);
  2018.         if ($reminder){
  2019.             $content $reminder->getReminderMailContent();
  2020.             $subject $reminder->getReminderMailSubject();
  2021.         } else {
  2022.             $content $batch->getConfirmationMailContent();
  2023.             $subject $batch->getConfirmationMailSubject();
  2024.         }
  2025.         $loader = new ArrayLoader([
  2026.             'mailBase' => $designTemplate,
  2027.             'content' => $content,
  2028.             'subject' => $subject,
  2029.         ]);
  2030.         // create new twig object with all twig templates
  2031.         $twig = new Environment($loader);
  2032.         $viewBase 'mailBase';
  2033.         $viewContent 'content';
  2034.         $viewSubject 'subject';
  2035.         $renderedSubject $twig->render(
  2036.             $viewSubject,
  2037.             [
  2038.                 'userId' => $user->getId(),
  2039.                 'loginLink' => $loginLink,
  2040.                 'batch' => $batch,
  2041.                 'program' => $program,
  2042.                 'application' => $application,
  2043.                 'dateEN' => $batch->getPitchDate()->format('Y-m-d'),
  2044.                 'dateDE' => $batch->getPitchDate()->format('d.m.y'),
  2045.                 'timeEN' => $batch->getPitchTime()->format('g:i A'), // English 12-hour format
  2046.                 'timeDE' => $batch->getPitchTime()->format('H:i'),   // German 24-hour format
  2047.                 'zoomLink' => Utility::getZoomLink($batch->getZoomLink(), $application->getId()),
  2048.             ]
  2049.         );
  2050.         $renderedContent $twig->render(
  2051.             $viewContent,
  2052.             [
  2053.                 'userId' => $user->getId(),
  2054.                 'name' => $application->getPerson(),
  2055.                 'firstName' => $application->getFirstName(),
  2056.                 'loginLink' => $loginLink,
  2057.                 'batch' => $batch,
  2058.                 'program' => $program,
  2059.                 'application' => $application,
  2060.                 'dateEN' => $batch->getPitchDate()->format('Y-m-d'),
  2061.                 'dateDE' => $batch->getPitchDate()->format('d.m.y'),
  2062.                 'timeEN' => $batch->getPitchTime()->format('g:i A'), // English 12-hour format
  2063.                 'timeDE' => $batch->getPitchTime()->format('H:i'),   // German 24-hour format
  2064.                 'zoomLink' => Utility::getZoomLink($batch->getZoomLink(), $application->getId()),
  2065.                 'googleCalendarLink' => $em->getRepository(Event::class)->getGoogleCalendardEventByEventId($batch->getEventId(), Utility::getZoomLink($batch->getZoomLink(), $application->getId())),
  2066.                 'icsDownloadLink' => $this->generateUrl('event_download',['eventId'=>(int)$batch->getEventId()],UrlGeneratorInterface::ABSOLUTE_URL),
  2067.             ]
  2068.         );
  2069.         $html $twig->render(
  2070.             $viewBase,
  2071.             [
  2072.                 'userId' => $user->getId(),
  2073.                 'name' => $application->getPerson(),
  2074.                 'firstName' => $application->getFirstName(),
  2075.                 'loginLink' => $loginLink,
  2076.                 'batch' => $batch,
  2077.                 'program' => $program,
  2078.                 'application' => $application,
  2079.                 'dateEN' => $batch->getPitchDate()->format('Y-m-d'),
  2080.                 'dateDE' => $batch->getPitchDate()->format('d.m.y'),
  2081.                 'timeEN' => $batch->getPitchTime()->format('g:i A'), // English 12-hour format
  2082.                 'timeDE' => $batch->getPitchTime()->format('H:i'),   // German 24-hour format
  2083.                 'zoomLink' => Utility::getZoomLink($batch->getZoomLink(), $application->getId()),
  2084.                 'googleCalendarLink' => $em->getRepository(Event::class)->getGoogleCalendardEventByEventId($batch->getEventId(), Utility::getZoomLink($batch->getZoomLink(), $application->getId())),
  2085.                 'icsDownloadLink' => $this->generateUrl('event_download',['eventId'=>(int)$batch->getEventId()],UrlGeneratorInterface::ABSOLUTE_URL),
  2086.                 'content' => $renderedContent,
  2087.             ]
  2088.         );
  2089.         $feedback Utility::sendAlertMailPerZapier($application->getEmail(), $html$renderedSubject$batch->getSenderMail(), $batch->getFromName(), 'html');
  2090.         $this->addFlash('notice'"SUCCESS Confirmation Mail has been sent via Zapier to {$application->getEmail()} with feedback=" print_r($feedbacktrue));
  2091.         $mailSubject "{$batch->getProgram()->getName()} - Application submitted by {$application->getStartupName()}";
  2092.         $mailText $this->renderView(
  2093.             '@StartPlatzRheinlandPitchBundle/Apply/_mail.altert.admin.application.txt.twig',
  2094.             [
  2095.                 'user' => $user,
  2096.                 'batch' => $batch,
  2097.                 'application' => $application,
  2098.             ]
  2099.         );
  2100.         $feedback $this->callbackService->sendAlertMailPerZapier($batch->getRecipientMonitoringMail(), $mailText$mailSubject$application->getEmail());
  2101.         $this->addFlash('notice'"SUCCESS Confirmation Mail has been sent via Zapier to {$application->getEmail()} with feedback=" print_r($feedbacktrue));
  2102.         if ($batch->getSkoolWebhook() > ''){
  2103.             $feedback $this->callbackService->sendPostRequest($batch->getSkoolWebhook(), $application->getEmail());
  2104.             $this->addFlash('notice'"SUCCESS Skool Webhook has been posted with email= {$application->getEmail()} and feedback=" print_r($feedbacktrue));
  2105.         }
  2106.         if ($batch->getZapierWebhook() > ''){
  2107.             $payload json_encode($em->getRepository(Event::class)->setPayloadSingleApplicationAndBatch($application$batch));
  2108.             $callbackUrl $batch->getZapierWebhook();
  2109.             $feedback $this->callbackService->curl_callback($callbackUrl$payload);
  2110.             $this->addFlash('notice'"SUCCESS Zapier webhook {$batch->getZapierWebhook()} called with feedback=" print_r($feedback,true));
  2111.         }
  2112.         if ($reminder && $reminder->getSkoolWebhook() > ''){
  2113.             $feedback $this->callbackService->sendPostRequest($reminder->getSkoolWebhook(), $application->getEmail());
  2114.             $this->addFlash('notice'"SUCCESS Skool Webhook has been posted with email= {$application->getEmail()} and feedback=" print_r($feedbacktrue));
  2115.         }
  2116.         if ($reminder && $reminder->getZapierWebhook() > ''){
  2117.             $payload json_encode($em->getRepository(Event::class)->setPayloadSingleApplicationAndBatch($application$batch));
  2118.             $callbackUrl $reminder->getZapierWebhook();
  2119.             $feedback $this->callbackService->curl_callback($callbackUrl$payload);
  2120.             $this->addFlash('notice'"SUCCESS Zapier webhook {$reminder->getZapierWebhook()} called with feedback=" print_r($feedback,true));
  2121.         }
  2122.         return true;
  2123.     }
  2124. }