getUser(); $backUrl = $this->resolveBackUrl($request, $model); $organizationParam = $request->query->get('organization'); if (null === $organizationParam) { $template->set('error', 'Ungültiger Aufruf: Parameter "organization" fehlt.'); $template->set('backUrl', $backUrl); return $template->getResponse(); } if (!$user instanceof FrontendUser) { $template->set('error', 'Bitte zuerst als Mitglied einloggen.'); $template->set('backUrl', $backUrl); return $template->getResponse(); } $organizationId = (int) $organizationParam; if ($organizationId <= 0 || !$this->organizationRepository->memberHasOrganization((int) $user->id, $organizationId)) { $template->set('error', 'Keine Berechtigung für diese Organisation oder ungültige ID.'); $template->set('backUrl', $backUrl); return $template->getResponse(); } $organization = $this->organizationRepository->findById($organizationId); $allowedOrganizationTagIds = array_values(array_unique(array_map('intval', StringUtil::deserialize($model->organizationTypeTags ?? null, true)))); if (null === $organization) { $template->set('error', 'Organisation nicht gefunden.'); $template->set('backUrl', $backUrl); return $template->getResponse(); } $formData = [ 'title' => (string) ($organization['title'] ?? ''), 'street' => (string) ($organization['street'] ?? ''), 'postal' => (string) ($organization['postal'] ?? ''), 'city' => (string) ($organization['city'] ?? ''), 'state' => (string) ($organization['state'] ?? ''), 'country' => (string) ($organization['country'] ?? ''), 'phone' => (string) ($organization['phone'] ?? ''), 'email' => (string) ($organization['email'] ?? ''), 'website' => (string) ($organization['website'] ?? ''), 'description' => (string) ($organization['description'] ?? ''), 'tags' => $this->organizationRepository->getTagIdsForOrganization($organizationId), ]; $currentLogoPath = null; if (!empty($organization['logo'])) { $logoModel = FilesModel::findByUuid((string) $organization['logo']); if (null !== $logoModel) { $currentLogoPath = $logoModel->path; } } $form = $this->createForm(OrganizationType::class, $formData, [ 'tag_choices' => $this->organizationRepository->getTagChoicesForOrganizationType($allowedOrganizationTagIds), ]); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $submittedData = (array) $form->getData(); $this->organizationRepository->update($organizationId, $submittedData); $selectedTagIds = array_values(array_unique(array_map('intval', (array) ($submittedData['tags'] ?? [])))); if ([] !== $allowedOrganizationTagIds) { $selectedTagIds = array_values(array_intersect($selectedTagIds, $allowedOrganizationTagIds)); } $this->organizationRepository->assignTagsToOrganization($organizationId, $selectedTagIds); $deleteLogo = '1' === (string) $request->request->get('remove_logo', '0'); $uploadedLogo = $form->get('logoUpload')->getData(); if ($uploadedLogo instanceof UploadedFile) { $newLogoUuid = $this->storeOrganizationLogo( $uploadedLogo, $model, $organizationId, (string) ($submittedData['title'] ?? ''), ); if (null !== $newLogoUuid) { $this->organizationRepository->updateLogo($organizationId, $newLogoUuid); } } elseif ($deleteLogo) { $this->organizationRepository->updateLogo($organizationId, null); } if ($request->request->has('save_back')) { return new RedirectResponse($backUrl); } return new RedirectResponse($request->getUri()); } $template->set('form', $form->createView()); $template->set('backUrl', $backUrl); $template->set('requestToken', $this->container->get('contao.csrf.token_manager')->getDefaultTokenValue()); $template->set('currentLogoPath', $currentLogoPath); return $template->getResponse(); } private function storeOrganizationLogo(UploadedFile $uploadedFile, ModuleModel $model, int $organizationId, string $organizationTitle): ?string { if (empty($model->logoFolder)) { return null; } $folderModel = FilesModel::findByUuid((string) $model->logoFolder); if (null === $folderModel) { return null; } $uploadBasePath = trim((string) $folderModel->path, '/'); if ('' === $uploadBasePath) { return null; } $titleSlug = strtolower(StringUtil::generateAlias($organizationTitle)); $titleSlug = preg_replace('/[^a-z0-9-]+/', '-', $titleSlug ?? '') ?? ''; $titleSlug = trim($titleSlug, '-'); $titleSlug = substr($titleSlug, 0, 12); if ('' === $titleSlug) { $titleSlug = 'organization'; } $targetRelativeDir = sprintf('%s/org-%d-%s', $uploadBasePath, $organizationId, $titleSlug); $projectDir = (string) $this->getParameter('kernel.project_dir'); $targetAbsoluteDir = rtrim($projectDir, '/').'/'.$targetRelativeDir; if (!is_dir($targetAbsoluteDir) && !mkdir($targetAbsoluteDir, 0775, true) && !is_dir($targetAbsoluteDir)) { return null; } $originalName = pathinfo($uploadedFile->getClientOriginalName(), PATHINFO_FILENAME); $safeName = preg_replace('/[^a-zA-Z0-9_-]+/', '-', (string) $originalName); $safeName = trim((string) $safeName, '-'); if ('' === $safeName) { $safeName = 'logo'; } $extension = $uploadedFile->guessExtension() ?: $uploadedFile->getClientOriginalExtension() ?: 'bin'; $filename = sprintf('%s-%s.%s', $safeName, uniqid('', true), strtolower((string) $extension)); $uploadedFile->move($targetAbsoluteDir, $filename); $relativePath = $targetRelativeDir.'/'.$filename; $fileModel = Dbafs::addResource($relativePath); return null !== $fileModel ? (string) $fileModel->uuid : null; } private function resolveBackUrl(Request $request, ModuleModel $model): string { if ((int) ($model->listPage ?? 0) > 0) { $listPage = $this->getContaoAdapter(PageModel::class)->findById((int) $model->listPage); if ($listPage instanceof PageModel) { return $this->generateContentUrl($listPage); } } $ref = (string) $request->query->get('ref', ''); if ('' !== $ref) { $decoded = base64_decode($ref, true); if (false !== $decoded && str_starts_with($decoded, '/')) { return $decoded; } } $page = $this->getPageModel(); return $page instanceof PageModel ? $this->generateContentUrl($page) : '/'; } }