OrganizationFactory.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. <?php
  2. namespace App\Service\Organization;
  3. use App\ApiResources\Organization\OrganizationCreationRequest;
  4. use App\ApiResources\Organization\OrganizationMemberCreationRequest;
  5. use App\Entity\Access\Access;
  6. use App\Entity\Core\AddressPostal;
  7. use App\Entity\Core\ContactPoint;
  8. use App\Entity\Education\Cycle;
  9. use App\Entity\Network\NetworkOrganization;
  10. use App\Entity\Organization\Organization;
  11. use App\Entity\Organization\OrganizationAddressPostal;
  12. use App\Entity\Organization\Parameters;
  13. use App\Entity\Organization\Settings;
  14. use App\Entity\Organization\Subdomain;
  15. use App\Entity\Person\Person;
  16. use App\Entity\Person\PersonAddressPostal;
  17. use App\Enum\Core\ContactPointTypeEnum;
  18. use App\Enum\Education\CycleEnum;
  19. use App\Enum\Network\NetworkEnum;
  20. use App\Enum\Organization\AddressPostalOrganizationTypeEnum;
  21. use App\Enum\Organization\SettingsProductEnum;
  22. use App\Enum\Person\AddressPostalPersonTypeEnum;
  23. use App\Repository\Core\CountryRepository;
  24. use App\Repository\Organization\OrganizationRepository;
  25. use App\Repository\Person\PersonRepository;
  26. use App\Service\Dolibarr\DolibarrApiService;
  27. use App\Service\Typo3\BindFileService;
  28. use App\Service\Typo3\SubdomainService;
  29. use App\Service\Typo3\Typo3Service;
  30. use App\Service\Utils\DatesUtils;
  31. use Doctrine\ORM\EntityManagerInterface;
  32. use Elastica\Param;
  33. use libphonenumber\NumberParseException;
  34. use libphonenumber\PhoneNumberUtil;
  35. use Psr\Log\LoggerInterface;
  36. use Symfony\Component\HttpFoundation\Response;
  37. use Symfony\Component\String\ByteString;
  38. use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
  39. use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
  40. use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
  41. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  42. use Symfony\Contracts\Service\Attribute\Required;
  43. use Throwable;
  44. use App\Service\Organization\Utils as OrganizationUtils;
  45. class OrganizationFactory
  46. {
  47. private LoggerInterface $logger;
  48. public function __construct(
  49. private readonly SubdomainService $subdomainService,
  50. private readonly OrganizationRepository $organizationRepository,
  51. private readonly CountryRepository $countryRepository,
  52. private readonly OrganizationUtils $organizationUtils,
  53. private readonly Typo3Service $typo3Service,
  54. private readonly DolibarrApiService $dolibarrApiService,
  55. private readonly EntityManagerInterface $entityManager,
  56. private readonly PersonRepository $personRepository,
  57. private readonly BindFileService $bindFileService,
  58. ) {}
  59. #[Required]
  60. /** @see https://symfony.com/doc/current/logging/channels_handlers.html#how-to-autowire-logger-channels */
  61. public function setLoggerInterface(LoggerInterface $adminLogger): void
  62. {
  63. $this->logger = $adminLogger;
  64. }
  65. /**
  66. * Créé une nouvelle organisation à partir des données contenues dans une OrganizationCreationRequest
  67. *
  68. * @param OrganizationCreationRequest $organizationCreationRequest
  69. * @return Organization
  70. * @throws TransportExceptionInterface
  71. * @throws Throwable
  72. */
  73. public function create(OrganizationCreationRequest $organizationCreationRequest): Organization
  74. {
  75. $this->logger->info(
  76. "Start the creation of a new organization named '" . $organizationCreationRequest->getName() . "'"
  77. );
  78. $this->entityManager->beginTransaction();
  79. try {
  80. // On vérifie si cette organisation n'existe pas déjà
  81. if ($this->isExistingOrganization($organizationCreationRequest)) {
  82. throw new \RuntimeException('An organization named ' . $organizationCreationRequest->getName() . ' already exists');
  83. }
  84. // On vérifie la validité et la disponibilité du sous domaine
  85. $this->validateSubdomain($organizationCreationRequest->getSubdomain());
  86. $this->logger->info("Subdomain is valid and available : '" . $organizationCreationRequest->getSubdomain() . "'");
  87. // On construit l'organisation et ses relations
  88. $organization = $this->makeOrganizationWithRelations($organizationCreationRequest);
  89. $this->logger->info("Organization created with all its relations");
  90. // On persiste et on commit, les objets liés seront persistés en cascade
  91. $this->entityManager->persist($organization);
  92. $this->entityManager->flush();
  93. $this->entityManager->commit();
  94. $this->logger->debug(" - New entities committed in DB");
  95. $this->logger->info("Organization persisted in the DB");
  96. } catch (\Exception $e) {
  97. $this->logger->critical("An error happened, operation cancelled\n" . $e);
  98. $this->entityManager->rollback();
  99. throw $e;
  100. }
  101. $withError = false;
  102. // Création de la société Dolibarr
  103. try {
  104. $dolibarrId = $this->dolibarrApiService->createSociety(
  105. $organization,
  106. $organizationCreationRequest->isClient()
  107. );
  108. $this->logger->info("New dolibarr structure created (uid : " . $dolibarrId . ")");
  109. } catch (\Exception $e) {
  110. $this->logger->critical("An error happened while creating the dolibarr society, please proceed manually.");
  111. $this->logger->debug($e);
  112. $withError = true;
  113. }
  114. // Register the subdomain into the BindFile (takes up to 5min to take effect)
  115. try {
  116. $this->bindFileService->registerSubdomain($organizationCreationRequest->getSubdomain());
  117. $this->logger->info("Subdomain registered");
  118. } catch (\Exception $e) {
  119. $this->logger->critical("An error happened while updating the bind file, please proceed manually.");
  120. $this->logger->debug($e);
  121. $withError = true;
  122. }
  123. // Création du site typo3 (on est obligé d'attendre que l'organisation soit persistée en base)
  124. if ($organizationCreationRequest->getCreateWebsite()) {
  125. try {
  126. $this->createTypo3Website($organization);
  127. } catch (\Exception $e) {
  128. $this->logger->critical("An error happened while creating the typo3 website, please proceed manually.");
  129. $this->logger->debug($e);
  130. $withError = true;
  131. }
  132. } else {
  133. $this->logger->warning("Typo3 website creation was not required");
  134. }
  135. if ($withError) {
  136. $organizationCreationRequest->setStatus(OrganizationCreationRequest::STATUS_OK_WITH_ERRORS);
  137. $this->logger->warning("-- Operation ended with errors, check the logs for more information --");
  138. } else {
  139. $organizationCreationRequest->setStatus(OrganizationCreationRequest::STATUS_OK);
  140. }
  141. return $organization;
  142. }
  143. /**
  144. * Une organisation du même nom existe-t-elle déjà à la même adresse ?
  145. *
  146. * @param OrganizationCreationRequest $organizationCreationRequest
  147. * @return bool
  148. */
  149. protected function isExistingOrganization(OrganizationCreationRequest $organizationCreationRequest): bool
  150. {
  151. return $this
  152. ->organizationRepository
  153. ->count(
  154. [
  155. 'name' => $organizationCreationRequest->getName(),
  156. ]
  157. ) > 0;
  158. }
  159. /**
  160. * Vérifie la disponibilité et la validité d'un sous domaine
  161. *
  162. * @param string $subdomainValue
  163. * @return void
  164. * @throws \Exception
  165. */
  166. protected function validateSubdomain(string $subdomainValue): void
  167. {
  168. if (!$this->subdomainService->isValidSubdomain($subdomainValue)) {
  169. throw new \RuntimeException("Not a valid subdomain : " . $subdomainValue);
  170. }
  171. if ($this->subdomainService->isReservedSubdomain($subdomainValue)) {
  172. throw new \RuntimeException("This subdomain is not available : " . $subdomainValue);
  173. }
  174. if ($this->subdomainService->isRegistered($subdomainValue)) {
  175. throw new \RuntimeException("This subdomain is already registered : " . $subdomainValue);
  176. }
  177. }
  178. /**
  179. * Créé une nouvelle instance d'organisation, et toutes les instances liées (paramètres, contact, adresses, ...),
  180. * selon le contenu de la requête de création.
  181. *
  182. * @param OrganizationCreationRequest $organizationCreationRequest
  183. * @return Organization
  184. * @throws Throwable
  185. */
  186. protected function makeOrganizationWithRelations(
  187. OrganizationCreationRequest $organizationCreationRequest
  188. ): Organization
  189. {
  190. // Création de l'organisation
  191. $organization = $this->makeOrganization($organizationCreationRequest);
  192. $this->logger->debug(" - Organization created");
  193. // Création des Parameters
  194. $parameters = $this->makeParameters($organizationCreationRequest);
  195. $organization->setParameters($parameters);
  196. $this->logger->debug(" - Parameters created");
  197. // Création des Settings
  198. $settings = $this->makeSettings($organizationCreationRequest);
  199. $organization->setSettings($settings);
  200. $this->logger->debug(" - Settings created");
  201. // Création de l'adresse postale
  202. $organizationAddressPostal = $this->makePostalAddress($organizationCreationRequest);
  203. $organization->addOrganizationAddressPostal($organizationAddressPostal);
  204. $this->logger->debug(" - OrganizationAddressPostal created");
  205. // Création du point de contact
  206. $contactPoint = $this->makeContactPoint($organizationCreationRequest);
  207. $organization->addContactPoint($contactPoint);
  208. $this->logger->debug(" - ContactPoint created");
  209. // Rattachement au réseau
  210. $networkOrganization = $this->makeNetworkOrganization($organizationCreationRequest);
  211. $organization->addNetworkOrganization($networkOrganization);
  212. $this->logger->debug(" - NetworkOrganization created");
  213. // Créé l'admin
  214. $adminAccess = $this->makeAdminAccess($organizationCreationRequest);
  215. $organization->addAccess($adminAccess);
  216. $this->logger->debug(" - Admin access created");
  217. // Création des cycles
  218. foreach ($this->makeCycles() as $cycle) {
  219. $organization->addCycle($cycle);
  220. }
  221. $this->logger->debug(" - Cycles created");
  222. // Création du président (si renseigné)
  223. $presidentCreationRequest = $organizationCreationRequest->getPresident();
  224. if ($presidentCreationRequest !== null) {
  225. $presidentAccess = $this->makeAccess($presidentCreationRequest);
  226. $organization->addAccess($presidentAccess);
  227. $this->logger->debug(" - President access created");
  228. }
  229. // Création du directeur (si renseigné)
  230. $directorCreationRequest = $organizationCreationRequest->getDirector();
  231. if ($directorCreationRequest !== null) {
  232. $directorAccess = $this->makeAccess($directorCreationRequest);
  233. $organization->addAccess($directorAccess);
  234. $this->logger->debug(" - Director access created");
  235. }
  236. // Création du sous-domaine
  237. $subdomain = $this->makeSubdomain($organizationCreationRequest);
  238. $organization->addSubdomain($subdomain);
  239. // <--- Pour la rétrocompatibilité avec la v1 ; pourra être supprimé lorsque la migration sera achevée
  240. $parameters = $organization->getParameters();
  241. $parameters->setSubDomain($organizationCreationRequest->getSubdomain());
  242. $parameters->setOtherWebsite('https://' . $organizationCreationRequest->getSubdomain() . '.opentalent.fr');
  243. // --->
  244. $this->logger->debug(" - Subdomain created");
  245. return $organization;
  246. }
  247. /**
  248. * Créé une nouvelle instance d'organisation
  249. *
  250. * @param OrganizationCreationRequest $organizationCreationRequest
  251. * @return Organization
  252. */
  253. protected function makeOrganization(OrganizationCreationRequest $organizationCreationRequest): Organization
  254. {
  255. // Création de l'organisation
  256. $organization = new Organization();
  257. $organization->setName($organizationCreationRequest->getName());
  258. $organization->setLegalStatus($organizationCreationRequest->getLegalStatus());
  259. $organization->setPrincipalType($organizationCreationRequest->getPrincipalType());
  260. $organization->setIdentifier($organizationCreationRequest->getIdentifier());
  261. return $organization;
  262. }
  263. /**
  264. * Create a new Parameters object from the data in an OrganizationCreationRequest
  265. *
  266. * @param OrganizationCreationRequest $organizationCreationRequest The organization creation request
  267. * @return Parameters The created Parameters object
  268. * @throws Throwable If there is an error
  269. */
  270. protected function makeParameters(OrganizationCreationRequest $organizationCreationRequest): Parameters
  271. {
  272. $parameters = new Parameters();
  273. return $parameters;
  274. }
  275. /**
  276. * Creates a new instance of the Settings class based on the given OrganizationCreationRequest object.
  277. *
  278. * @param OrganizationCreationRequest $organizationCreationRequest The OrganizationCreationRequest object containing the required data.
  279. *
  280. * @return Settings The newly created instance of the Settings class.
  281. */
  282. protected function makeSettings(OrganizationCreationRequest $organizationCreationRequest): Settings
  283. {
  284. $settings = new Settings();
  285. $settings->setProduct($organizationCreationRequest->getProduct());
  286. return $settings;
  287. }
  288. /**
  289. * Creates a new instance of the OrganizationAddressPostal class based on the given OrganizationCreationRequest object.
  290. *
  291. * @param OrganizationCreationRequest $organizationCreationRequest The OrganizationCreationRequest object containing the required data.
  292. *
  293. * @return OrganizationAddressPostal The newly created instance of the OrganizationAddressPostal class.
  294. */
  295. protected function makePostalAddress(OrganizationCreationRequest $organizationCreationRequest): OrganizationAddressPostal
  296. {
  297. $country = $this->countryRepository->find($organizationCreationRequest->getCountryId());
  298. if (!$country) {
  299. throw new \RuntimeException('No country found for id ' . $organizationCreationRequest->getCountryId());
  300. }
  301. $addressPostal = new AddressPostal();
  302. $addressPostal->setStreetAddress($organizationCreationRequest->getStreetAddress1());
  303. $addressPostal->setStreetAddressSecond($organizationCreationRequest->getStreetAddress2());
  304. $addressPostal->setStreetAddressThird($organizationCreationRequest->getStreetAddress3());
  305. $addressPostal->setPostalCode($organizationCreationRequest->getPostalCode());
  306. $addressPostal->setAddressCity($organizationCreationRequest->getCity());
  307. $addressPostal->setAddressCountry($country);
  308. $organizationAddressPostal = new OrganizationAddressPostal();
  309. $organizationAddressPostal->setAddressPostal($addressPostal);
  310. $organizationAddressPostal->setType(AddressPostalOrganizationTypeEnum::ADDRESS_HEAD_OFFICE);
  311. return $organizationAddressPostal;
  312. }
  313. /**
  314. * Creates a new instance of the ContactPoint class based on the given OrganizationCreationRequest object.
  315. *
  316. * @param OrganizationCreationRequest $organizationCreationRequest The OrganizationCreationRequest object containing the required data.
  317. *
  318. * @return ContactPoint The newly created instance of the ContactPoint class.
  319. * @throws NumberParseException
  320. */
  321. protected function makeContactPoint(OrganizationCreationRequest $organizationCreationRequest): ContactPoint
  322. {
  323. $phoneUtil = PhoneNumberUtil::getInstance();
  324. if (!$phoneUtil->isPossibleNumber($organizationCreationRequest->getPhoneNumber())) {
  325. throw new \RuntimeException("Phone number is invalid or missing");
  326. }
  327. $phoneNumber = $phoneUtil->parse($organizationCreationRequest->getPhoneNumber());
  328. $contactPoint = new ContactPoint();
  329. $contactPoint->setContactType(ContactPointTypeEnum::PRINCIPAL);
  330. $contactPoint->setEmail($organizationCreationRequest->getEmail());
  331. $contactPoint->setTelphone($phoneNumber);
  332. return $contactPoint;
  333. }
  334. /**
  335. * Creates a new instance of the NetworkOrganization class based on the given OrganizationCreationRequest object.
  336. *
  337. * @param OrganizationCreationRequest $organizationCreationRequest The OrganizationCreationRequest object containing the required data.
  338. *
  339. * @return NetworkOrganization The newly created instance of the NetworkOrganization class.
  340. *
  341. * @throws \RuntimeException|\Exception if no parent organization is found for the given parent ID or if no network is found for the given network ID.
  342. */
  343. protected function makeNetworkOrganization(OrganizationCreationRequest $organizationCreationRequest): NetworkOrganization
  344. {
  345. $parent = $this->organizationRepository->find($organizationCreationRequest->getParentId());
  346. if (!$parent) {
  347. throw new \RuntimeException('No parent organization found for id ' . $organizationCreationRequest->getParentId());
  348. }
  349. if ($parent->getSettings()->getProduct() !== SettingsProductEnum::MANAGER) {
  350. throw new \RuntimeException(
  351. "Parent organization must have the product 'manager' (actual product: " .
  352. $organizationCreationRequest->getParentId() . ")"
  353. );
  354. }
  355. $networkOrganization = $this->organizationUtils->getActiveNetworkOrganization($parent);
  356. if (!$networkOrganization) {
  357. throw new \RuntimeException('No network found for parent ' . $organizationCreationRequest->getParentId());
  358. }
  359. $network = $networkOrganization->getNetwork();
  360. // Si réseau CMF, on vérifie que le matricule est valide
  361. if ($network->getId() === NetworkEnum::CMF->value) {
  362. if (!preg_match("/FR\d{12}/", $organizationCreationRequest->getIdentifier())) {
  363. throw new \RuntimeException("CMF identifier is missing or invalid.");
  364. }
  365. if ($this
  366. ->organizationRepository
  367. ->count(
  368. ['identifier' => $organizationCreationRequest->getIdentifier()]
  369. ) > 0) {
  370. throw new \RuntimeException("CMF identifier is already registered : '" . $organizationCreationRequest->getIdentifier() ."'");
  371. }
  372. }
  373. $networkOrganization = new NetworkOrganization();
  374. $networkOrganization->setParent($parent);
  375. $networkOrganization->setNetwork($network);
  376. $networkOrganization->setStartDate(DatesUtils::new());
  377. return $networkOrganization;
  378. }
  379. /**
  380. * Creates a new instance of the Access class with admin access based on the given OrganizationCreationRequest object.
  381. *
  382. * @param OrganizationCreationRequest $organizationCreationRequest The OrganizationCreationRequest object containing the required data.
  383. *
  384. * @return Access The newly created instance of the Access class with admin access.
  385. */
  386. protected function makeAdminAccess(OrganizationCreationRequest $organizationCreationRequest): Access
  387. {
  388. $admin = new Person();
  389. $admin->setUsername('admin' . strtolower($organizationCreationRequest->getSubdomain()));
  390. $randomString = ByteString::fromRandom(32)->toString();
  391. $admin->setPassword($randomString);
  392. $adminAccess = new Access();
  393. $adminAccess->setAdminAccess(true);
  394. $adminAccess->setPerson($admin);
  395. return $adminAccess;
  396. }
  397. /**
  398. * Creates an array of Cycle objects based on a predefined set of data.
  399. *
  400. * @return Cycle[] An array of Cycle objects.
  401. */
  402. protected function makeCycles(): array
  403. {
  404. $cyclesData = [
  405. ['Cycle initiation', 10, CycleEnum::INITIATION_CYCLE],
  406. ['Cycle 1', 20, CycleEnum::CYCLE_1],
  407. ['Cycle 2', 30, CycleEnum::CYCLE_2],
  408. ['Cycle 3', 40, CycleEnum::CYCLE_3],
  409. ['Cycle 4', 50, CycleEnum::CYCLE_4],
  410. ['Hors cycle', 60, CycleEnum::OUT_CYCLE],
  411. ];
  412. $cycles = [];
  413. foreach ($cyclesData as $cycleData) {
  414. $cycle = new Cycle();
  415. $cycle->setLabel($cycleData[0]);
  416. $cycle->setOrder($cycleData[1]);
  417. $cycle->setCycleEnum($cycleData[2]);
  418. $cycle->setIsSystem(false);
  419. $cycles[] = $cycle;
  420. }
  421. return $cycles;
  422. }
  423. /**
  424. * Creates an Access object based on the given OrganizationMemberCreationRequest.
  425. *
  426. * @param int|OrganizationMemberCreationRequest $creationRequestData The request object containing the
  427. * necessary data for creating a Person object,
  428. * or the id of an existing one.
  429. * @return Access The created Access object.
  430. * @throws NumberParseException
  431. */
  432. protected function makeAccess(
  433. int | OrganizationMemberCreationRequest $creationRequestData
  434. ): Access
  435. {
  436. if (is_int($creationRequestData)) {
  437. $person = $this->personRepository->find($creationRequestData);
  438. } else {
  439. $person = new Person();
  440. $person->setUsername($creationRequestData->getUsername());
  441. $person->setPassword(ByteString::fromRandom(32)->toString());
  442. $person->setGender($creationRequestData->getGender());
  443. $person->setName(
  444. ucfirst(strtolower($creationRequestData->getName()))
  445. );
  446. $person->setGivenName(
  447. ucfirst(strtolower($creationRequestData->getGivenName()))
  448. );
  449. $personPostalAddress = $this->makePersonPostalAddress($creationRequestData);
  450. $person->addPersonAddressPostal($personPostalAddress);
  451. $contactPoint = $this->makePersonContactPoint($creationRequestData);
  452. $person->addContactPoint($contactPoint);
  453. }
  454. $access = new Access();
  455. $access->setPerson($person);
  456. return $access;
  457. }
  458. /**
  459. * Creates a PersonAddressPostal object based on the given OrganizationMemberCreationRequest.
  460. *
  461. * @param OrganizationMemberCreationRequest $organizationMemberCreationRequest The request object containing the
  462. * necessary data for creating a
  463. * PersonAddressPostal object.
  464. * @return PersonAddressPostal The created PersonAddressPostal object.
  465. */
  466. protected function makePersonPostalAddress(OrganizationMemberCreationRequest $organizationMemberCreationRequest): PersonAddressPostal
  467. {
  468. $addressPostal = new AddressPostal();
  469. $addressPostal->setStreetAddress($organizationMemberCreationRequest->getStreetAddress1());
  470. $addressPostal->setStreetAddressSecond($organizationMemberCreationRequest->getStreetAddress2());
  471. $addressPostal->setStreetAddressThird($organizationMemberCreationRequest->getStreetAddress3());
  472. $addressPostal->setPostalCode($organizationMemberCreationRequest->getPostalCode());
  473. $addressPostal->setAddressCity($organizationMemberCreationRequest->getCity());
  474. $country = $this->countryRepository->find($organizationMemberCreationRequest->getCountryId());
  475. $addressPostal->setAddressCountry($country);
  476. $personAddressPostal = new PersonAddressPostal();
  477. $personAddressPostal->setAddressPostal($addressPostal);
  478. $personAddressPostal->setType(AddressPostalPersonTypeEnum::ADDRESS_PRINCIPAL);
  479. return $personAddressPostal;
  480. }
  481. /**
  482. * Creates a new instance of the ContactPoint class based on the given OrganizationCreationRequest object.
  483. *
  484. * @param OrganizationMemberCreationRequest $organizationMemberCreationRequest The OrganizationMemberCreationRequest object containing the required data.
  485. *
  486. * @return ContactPoint The newly created instance of the ContactPoint class.
  487. * @throws NumberParseException
  488. */
  489. protected function makePersonContactPoint(OrganizationMemberCreationRequest $organizationMemberCreationRequest): ContactPoint
  490. {
  491. $phoneUtil = PhoneNumberUtil::getInstance();
  492. $phoneNumber = $phoneUtil->parse($organizationMemberCreationRequest->getPhone());
  493. $contactPoint = new ContactPoint();
  494. $contactPoint->setContactType(ContactPointTypeEnum::PRINCIPAL);
  495. $contactPoint->setEmail($organizationMemberCreationRequest->getEmail());
  496. $contactPoint->setTelphone($phoneNumber);
  497. if ($organizationMemberCreationRequest->getMobile() !== null) {
  498. $mobileNumber = $phoneUtil->parse($organizationMemberCreationRequest->getMobile());
  499. $contactPoint->setMobilPhone($mobileNumber);
  500. }
  501. return $contactPoint;
  502. }
  503. protected function makeSubdomain(OrganizationCreationRequest $organizationCreationRequest): Subdomain
  504. {
  505. $subdomain = new Subdomain();
  506. $subdomain->setSubdomain($organizationCreationRequest->getSubdomain());
  507. $subdomain->setActive(true);
  508. return $subdomain;
  509. }
  510. /**
  511. * Créé le site Typo3 et retourne l'id de la page racine du site nouvellement créé, ou null en cas d'erreur
  512. *
  513. * @throws RedirectionExceptionInterface
  514. * @throws ClientExceptionInterface
  515. * @throws TransportExceptionInterface
  516. * @throws ServerExceptionInterface
  517. */
  518. protected function createTypo3Website(Organization $organization): ?int {
  519. $response = $this->typo3Service->createSite($organization->getId());
  520. $rootPageUid = json_decode($response->getContent(), true);
  521. if ($response->getStatusCode() === Response::HTTP_OK && $rootPageUid > 0) {
  522. // TODO: revoir l'utilité du champs cmsId
  523. $organization->setCmsId($rootPageUid);
  524. $this->entityManager->persist($organization);
  525. $this->entityManager->flush();
  526. return $rootPageUid;
  527. } else {
  528. $this->logger->critical("/!\ A critical error happened while creating the Typo3 website");
  529. $this->logger->debug($response->getContent());
  530. }
  531. return null;
  532. }
  533. }