222 lines
8.4 KiB
PHP
222 lines
8.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace MummertMedia\EventManagerBundle\Controller\Frontend;
|
|
|
|
use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController;
|
|
use Contao\CoreBundle\DependencyInjection\Attribute\AsFrontendModule;
|
|
use Contao\CoreBundle\Twig\FragmentTemplate;
|
|
use Contao\Dbafs;
|
|
use Contao\FilesModel;
|
|
use Contao\FrontendUser;
|
|
use Contao\ModuleModel;
|
|
use Contao\PageModel;
|
|
use Contao\StringUtil;
|
|
use MummertMedia\EventManagerBundle\Form\OrganizationType;
|
|
use MummertMedia\EventManagerBundle\Service\OrganizationRepository;
|
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
|
use Symfony\Component\HttpFoundation\RedirectResponse;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
#[AsFrontendModule(type: 'organization_edit', category: 'eventmanager', template: 'frontend/organization_edit')]
|
|
class OrganizationEditController extends AbstractFrontendModuleController
|
|
{
|
|
public function __construct(
|
|
private readonly OrganizationRepository $organizationRepository,
|
|
) {
|
|
}
|
|
|
|
protected function getResponse(FragmentTemplate $template, ModuleModel $model, Request $request): Response
|
|
{
|
|
$user = $this->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'] ?? ''),
|
|
'street2' => (string) ($organization['street2'] ?? ''),
|
|
'postal' => (string) ($organization['postal'] ?? ''),
|
|
'city' => (string) ($organization['city'] ?? ''),
|
|
'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) : '/';
|
|
}
|
|
}
|