canvasSlug = strip_tags((string) ($request->route('canvasSlug') ?? '')); $this->template = $templateRegistry->get($this->canvasSlug); } /** * get - display the create/edit board dialog. * * @param string|null $canvasSlug Canvas type slug from the route (resolved in the constructor) * @param string|null $id Current board id */ #[RequiresPermission(BlueprintsPermissions::VIEW, entityScoped: true)] public function get(?string $canvasSlug = null, ?string $id = null): Response { if ($this->template === null) { return $this->tpl->displayPartial('errors.error404'); } $currentCanvasId = ''; $canvasTitle = ''; if ($id !== null) { // getBoard authorizes VIEW against the board's real project; false = missing / // foreign / unauthorized, in which case we neither expose the title nor switch // the active board (no session poisoning with a foreign id). $singleCanvas = $this->blueprintsService->getBoard((int) $id, $this->template->getDatabaseType()); if ($singleCanvas !== false) { $currentCanvasId = (int) $id; $canvasTitle = $singleCanvas[0]['title'] ?? ''; session([$this->template->getSessionKey() => $currentCanvasId]); } } return $this->renderDialog($currentCanvasId, $canvasTitle); } /** * post - handle create/edit board submissions. * * @param string|null $canvasSlug Canvas type slug from the route (resolved in the constructor) * @param string|null $id Current board id */ #[RequiresPermission(BlueprintsPermissions::EDIT, entityScoped: true)] public function post(?string $canvasSlug = null, ?string $id = null): Response { if ($this->template === null) { return $this->tpl->displayPartial('errors.error404'); } $canvasType = $this->template->getDatabaseType(); $sessionKey = $this->template->getSessionKey(); $basePath = '/blueprints/'.$this->canvasSlug; $currentCanvasId = ($id !== null && $id !== '') ? (int) $id : ''; $canvasTitle = ''; if (is_int($currentCanvasId) && $currentCanvasId > 0) { $singleCanvas = $this->blueprintsService->getBoard($currentCanvasId, $canvasType); if ($singleCanvas !== false) { $canvasTitle = $singleCanvas[0]['title'] ?? ''; session([$sessionKey => $currentCanvasId]); } } // Add Canvas if ($this->request->has('newCanvas')) { if ($this->request->has('canvastitle') && ! empty($this->request->input('canvastitle'))) { if (! $this->blueprintsRepo->existCanvas(session('currentProject'), $this->request->input('canvastitle'), $canvasType)) { $values = [ 'title' => $this->request->input('canvastitle'), 'author' => session('userdata.id'), 'projectId' => session('currentProject'), ]; // createBoard authorizes CREATE against the target (current) project. $currentCanvasId = $this->blueprintsService->createBoard($values, $canvasType); $mailer = app()->make(MailerCore::class); $users = $this->projectService->getUsersToNotify(session('currentProject')); $mailer->setSubject($this->language->__('notification.board_created')); $message = sprintf( $this->language->__('email_notifications.canvas_created_message'), session('userdata.name'), "".strip_tags($values['title']).'' ); $mailer->setHtml($message); $queue = app()->make(QueueRepository::class); $queue->queueMessageToUsers( $users, $message, $this->language->__('notification.board_created'), session('currentProject') ); $this->tpl->setNotification( $this->language->__('notification.board_created'), 'success', $this->canvasSlug.'board_created' ); session([$sessionKey => $currentCanvasId]); return Frontcontroller::redirect(BASE_URL.$basePath.'/boardDialog/'.$currentCanvasId); } $this->tpl->setNotification($this->language->__('notification.board_exists'), 'error'); } else { $this->tpl->setNotification($this->language->__('notification.please_enter_title'), 'error'); } } // Edit Canvas if ($this->request->has('editCanvas') && is_int($currentCanvasId) && $currentCanvasId > 0) { if ($this->request->has('canvastitle') && ! empty($this->request->input('canvastitle'))) { if (! $this->blueprintsRepo->existCanvas(session('currentProject'), $this->request->input('canvastitle'), $canvasType)) { // renameBoard authorizes EDIT against the board's real project. $this->blueprintsService->renameBoard($currentCanvasId, $this->request->input('canvastitle'), $canvasType); $this->tpl->setNotification($this->language->__('notification.board_edited'), 'success'); return Frontcontroller::redirect(BASE_URL.$basePath.'/boardDialog/'.$currentCanvasId); } $this->tpl->setNotification($this->language->__('notification.board_exists'), 'error'); } else { $this->tpl->setNotification($this->language->__('notification.please_enter_title'), 'error'); } } return $this->renderDialog($currentCanvasId, $canvasTitle); } /** * renderDialog - assign shared template variables and render the board dialog. * * @param int|string $currentCanvasId Current board id (empty string when creating) * @param string $canvasTitle Current board title */ private function renderDialog(int|string $currentCanvasId, string $canvasTitle): Response { $this->tpl->assign('currentCanvas', $currentCanvasId); $this->tpl->assign('canvasName', $this->canvasSlug); $this->tpl->assign('canvasSlug', $this->canvasSlug); $this->tpl->assign('canvasTitle', $canvasTitle); $this->tpl->assign('users', $this->projectService->getUsersAssignedToProject(session('currentProject'))); return $this->tpl->displayPartial('blueprints.boardDialog'); } }