/** * @param RequestResponseEvent $event */ public function listen(RequestResponseEvent $event) { $exception = $event->getData(); if ($exception instanceof CmsException) { $response = new SupraJsonResponse(null); $response->setStatus(0); $response->setErrorMessage($exception->getMessageKey() ? '{#' . $exception->getMessageKey() . '#}' : $exception->getMessage()); $event->setResponse($response); } }
/** * Returns localization properties, inner html and placeholder contents. * * @return SupraJsonResponse */ public function getAction() { $localization = $this->getPageLocalization(); $pageRequest = $this->createPageRequest(); $pageController = $this->getPageController(); $templateException = $response = $internalHtml = null; try { $response = $pageController->execute($pageRequest); } catch (\Twig_Error_Loader $e) { $templateException = $e; } catch (LayoutNotFound $e) { $templateException = $e; } catch (\Exception $e) { throw $e; } $localizationData = $this->getLocalizationData($localization); if ($templateException) { $internalHtml = '<h1>Page template or layout not found.</h1> <p>Please make sure the template is assigned and the template is published in this locale and it has layout assigned.</p>'; } elseif ($response instanceof Response) { $internalHtml = $response->getContent(); } $localizationData['internal_html'] = $internalHtml; $placeHolders = $pageRequest->getPlaceHolderSet()->getFinalPlaceHolders(); $blocks = $pageRequest->getBlockSet(); $placeHoldersData =& $localizationData['contents']; foreach ($placeHolders as $placeHolder) { $blocksData = array(); foreach ($blocks->getPlaceHolderBlockSet($placeHolder) as $block) { /* @var $block Block */ $blocksData[] = $this->getBlockData($block); } $placeHolderData = array('id' => $placeHolder->getName(), 'title' => $placeHolder->getTitle(), 'locked' => $placeHolder->isLocked(), 'closed' => !$localization->isPlaceHolderEditable($placeHolder), 'contents' => $blocksData, 'type' => 'list'); $placeHoldersData[] = $placeHolderData; } $jsonResponse = new SupraJsonResponse($localizationData); // @FIXME: dummy. when needed, move to prefilter. $jsonResponse->setPermissions(array(array('edit_page' => true, 'supervise_page' => true))); return $jsonResponse; }
/** * File upload action */ public function uploadAction(Request $request) { $postRequest = $request->request; $files = $request->files; if (!$files->has('file') || !$files->get('file') instanceof UploadedFile || !$files->get('file')->isValid()) { $message = 'Error uploading the file'; throw new CmsException(null, $message); } $file = $files->get('file'); /* @var $file UploadedFile */ $em = $this->container->getDoctrine()->getManager(); $em->beginTransaction(); $repository = $em->getRepository(FileAbstraction::CN()); /* @var $repository FileNestedSetRepository */ $repository->getNestedSetRepository()->lock(); // Permission check $uploadPermissionCheckFolder = null; if ($postRequest->get('folder')) { $uploadPermissionCheckFolder = $this->getFolder('folder'); } else { $uploadPermissionCheckFolder = new SlashFolder(); } $this->checkActionPermission($uploadPermissionCheckFolder, FileAbstraction::PERMISSION_UPLOAD_NAME); try { // getting the folder to upload in $folder = null; if ($postRequest->get('folder')) { $folder = $this->getFolder('folder'); } // Will return the top folder created/found from folderPath string $firstSubFolder = null; // Create/get folder by path provided $folderPath = $postRequest->get('folderPath', ''); $folderPath = trim(str_replace('\\', '/', $folderPath), '/'); if (!empty($folderPath)) { $folderPathParts = explode('/', $folderPath); foreach ($folderPathParts as $part) { $folderFound = false; $children = null; if ($folder instanceof Folder) { $children = $folder->getChildren(); } elseif (is_null($folder)) { $children = $repository->getRootNodes(); } else { throw new \LogicException("Not supported folder type: " . gettype($folder) . ', class: ' . get_class($folder)); } foreach ($children as $child) { if ($child instanceof Folder) { $_name = $child->getTitle(); if (strcasecmp($_name, $part) === 0) { $folderFound = $child; break; } } } if ($folderFound) { $folder = $folderFound; } else { $folder = $this->createFolder($part, $folder); } if (empty($firstSubFolder)) { $firstSubFolder = $folder; } } } // checking for replace action if ($postRequest->has('file_id')) { $fileToReplace = $this->getFile('file_id'); $this->getFileStorage()->replaceFile($fileToReplace, $file); // close transaction and unlock the nested set $em->commit(); $repository->getNestedSetRepository()->unlock(); return new SupraJsonResponse($this->imageAndFileOutput($fileToReplace)); } $fileEntity = null; if ($this->getFileStorage()->isSupportedImageFormat($file->getPathname())) { $fileEntity = new Image(); } else { $fileEntity = new File(); } $em->persist($fileEntity); $fileEntity->setFileName($file->getClientOriginalName()); $fileEntity->setSize($file->getSize()); $fileEntity->setMimeType($file->getMimeType()); // additional jobs for images if ($fileEntity instanceof Image) { // store original size $imageProcessor = $this->getFileStorage()->getImageResizer(); $imageInfo = $imageProcessor->getImageInfo($file->getPathname()); $fileEntity->setWidth($imageInfo->getWidth()); $fileEntity->setHeight($imageInfo->getHeight()); } if (!empty($folder)) { // get parent folder private/public status $publicStatus = $folder->isPublic(); $fileEntity->setPublic($publicStatus); // Flush before nested set UPDATE $em->flush(); $folder->addChild($fileEntity); } // when "force" set to true, then we need to ignore duplicate // filename exception, so postfix will be added to filename if ($fileEntity instanceof File) { if ($postRequest->has('force') && $postRequest->filter('force', null, false, FILTER_VALIDATE_BOOLEAN)) { try { $this->getFileStorage()->validateFileUpload($fileEntity, $file['tmp_name']); } catch (DuplicateFileNameException $e) { $siblings = $fileEntity->getSiblings(); $existingNames = array(); foreach ($siblings as $siblingEntity) { if (!$siblingEntity->equals($fileEntity)) { $existingNames[] = $siblingEntity->getFileName(); } } $extension = $fileEntity->getExtension(); $fileNamePart = $fileEntity->getFileNameWithoutExtension(); $possibleName = null; // assume that 1000 iterations is enough, to create unique name // if not, well... duplicate file name exception will be thrown for ($i = 1; $i < 1000; $i++) { $possibleName = sprintf(self::DUPLICATE_NAME_PATTERN, $fileNamePart, $i, $extension); if (!in_array($possibleName, $existingNames)) { $fileEntity->setFileName($possibleName); break; } } } } } // when it is not enough available memory to complete Image resize/crop // file will be uploaded as simple File entity if ($fileEntity instanceof Image) { try { $this->getFileStorage()->validateFileUpload($fileEntity, $file->getPathname()); } catch (InsufficientSystemResources $e) { // Removing image $em->remove($fileEntity); $em->flush(); $fileEntity = new File(); $em->persist($fileEntity); $fileEntity->setFileName($file->getClientOriginalName()); $fileEntity->setSize($file->getSize()); $fileEntity->setMimeType($file->getType()); if (!is_null($folder)) { $publicStatus = $folder->isPublic(); $fileEntity->setPublic($publicStatus); // Flush before nested set UPDATE $em->flush(); $folder->addChild($fileEntity); } $message = "Amount of memory required for image [{$file['name']}] resizing exceeds available, it will be uploaded as a document"; $responseWarning = $message; } } $em->flush(); // trying to upload file $this->getFileStorage()->storeFileData($fileEntity, $file->getPathname()); } catch (\Exception $e) { try { // close transaction and unlock the nested set $em->flush(); $em->rollback(); $repository->getNestedSetRepository()->unlock(); } catch (\Exception $e) { $this->container->getLogger()->error("Failure on rollback/unlock: " . $e->__toString()); } throw new CmsException(null, $e->getMessage(), $e); } // close transaction and unlock the nested set $em->commit(); $repository->getNestedSetRepository()->unlock(); // generating output $output = $this->imageAndFileOutput($fileEntity); if (!empty($firstSubFolder)) { $firstSubFolderOutput = $this->entityToArray($firstSubFolder); $output['folder'] = $firstSubFolderOutput; } $response = new SupraJsonResponse(); $response->setData($output); if (isset($responseWarning)) { $response->setWarningMessage($responseWarning); } return $response; }
/** * Sends confirmation message to JavaScript or returns answer if already received * @param string $question * @param string $id * @param boolean $answer by default next request is made only when "Yes" * is pressed. Setting to null will make callback for both answers. */ protected function getConfirmation($question, $id = '0', $answer = true) { $request = $this->container->getRequest(); $confirmationPool = $request->get(self::CONFIRMATION_ANSWER_CONTEXT, array()); if (isset($confirmationPool[$id])) { $userAnswer = filter_var($confirmationPool[$id], FILTER_VALIDATE_BOOLEAN); // Any answer is OK if (is_null($answer)) { return $userAnswer; } // Match if ($userAnswer === $answer) { return $userAnswer; // Wrong answer, in fact JS didn't need to do this request anymore } else { throw new CmsException(null, "Wrong answer"); } } $response = new SupraJsonResponse(); $response->addPart('confirmation', array('id' => $id, 'question' => $question, 'answer' => $answer)); return $response; }