public function execute(Request $request, WorkingFolder $workingFolder, EventDispatcher $dispatcher, CacheManager $cache, ResizedImageRepository $resizedImageRepository, ThumbnailRepository $thumbnailRepository, Acl $acl) { $fileName = (string) $request->query->get('fileName'); $editedImage = new EditedImage($fileName, $this->app); $saveAsNew = false; if (!$editedImage->exists()) { $saveAsNew = true; $editedImage->saveAsNew(true); } else { // If file exists check for FILE_DELETE permission $resourceTypeName = $workingFolder->getResourceType()->getName(); $path = $workingFolder->getClientCurrentFolder(); if (!$acl->isAllowed($resourceTypeName, $path, Permission::FILE_DELETE)) { throw new UnauthorizedException(sprintf('Unauthorized: no FILE_DELETE permission in %s:%s', $resourceTypeName, $path)); } } if (!Image::isSupportedExtension($editedImage->getExtension())) { throw new InvalidExtensionException('Unsupported image type or not image file'); } $imageFormat = Image::mimeTypeFromExtension($editedImage->getExtension()); $uploadedData = (string) $request->get('content'); if (null === $uploadedData || strpos($uploadedData, 'data:image/png;base64,') !== 0) { throw new InvalidUploadException('Invalid upload. Expected base64 encoded PNG image.'); } $data = explode(',', $uploadedData); $data = isset($data[1]) ? base64_decode($data[1]) : false; if (!$data) { throw new InvalidUploadException(); } try { $uploadedImage = Image::create($data); } catch (\Exception $e) { // No need to check if secureImageUploads is enabled - image must be valid here throw new InvalidUploadException('Invalid upload: corrupted image', Error::UPLOADED_CORRUPT, array(), $e); } $editedImage->setNewContents($uploadedImage->getData($imageFormat)); $editedImage->setNewDimensions($uploadedImage->getWidth(), $uploadedImage->getHeight()); if (!$editedImage->isValid()) { throw new InvalidUploadException('Invalid file provided'); } $editFileEvent = new EditFileEvent($this->app, $editedImage); $cache->set(Path::combine($workingFolder->getResourceType()->getName(), $workingFolder->getClientCurrentFolder(), $fileName), $uploadedImage->getInfo()); $dispatcher->dispatch(CKFinderEvent::SAVE_IMAGE, $editFileEvent); $saved = false; if (!$editFileEvent->isPropagationStopped()) { $saved = $editedImage->save($editFileEvent->getNewContents()); //Remove thumbnails and resized images in case if file is overwritten if (!$saveAsNew && $saved) { $resourceType = $workingFolder->getResourceType(); $thumbnailRepository->deleteThumbnails($resourceType, $workingFolder->getClientCurrentFolder(), $fileName); $resizedImageRepository->deleteResizedImages($resourceType, $workingFolder->getClientCurrentFolder(), $fileName); } } return array('saved' => (int) $saved, 'date' => Utils::formatDate(time())); }
/** * Renames current working folder * * @param string $newName new folder name * * @return array containing newName and newPath * * @throws \Exception if rename failed */ public function rename($newName) { $disallowUnsafeCharacters = $this->app['config']->get('disallowUnsafeCharacters'); if (!Folder::isValidName($newName, $disallowUnsafeCharacters) || $this->backend->isHiddenFolder($newName)) { throw new InvalidNameException('Invalid folder name'); } $newBackendPath = dirname($this->getPath()) . '/' . $newName; if ($this->backend->has($newBackendPath)) { throw new AlreadyExistsException('File already exists'); } $newClientPath = Path::normalize(dirname($this->getClientCurrentFolder()) . '/' . $newName); $dispatcher = $this->app['dispatcher']; $renameFolderEvent = new RenameFolderEvent($this->app, $this, $newName); $dispatcher->dispatch(CKFinderEvent::RENAME_FOLDER, $renameFolderEvent); $newName = $renameFolderEvent->getNewFolderName(); if (!$renameFolderEvent->isPropagationStopped()) { if (!$this->getBackend()->rename($this->getPath(), $newBackendPath)) { throw new AccessDeniedException(); } /* @var OperationManager $currentRequestOperation */ $currentRequestOperation = $this->app['operation']; if ($currentRequestOperation->isAborted()) { // Don't continue in this case, no need to touch thumbs and cache entries return array('aborted' => true); } // Delete related thumbs path $this->thumbnailRepository->deleteThumbnails($this->resourceType, $this->getClientCurrentFolder()); $this->app['cache']->changePrefix(Path::combine($this->resourceType->getName(), $this->getClientCurrentFolder()), Path::combine($this->resourceType->getName(), $newClientPath)); } return array('newName' => $newName, 'newPath' => $newClientPath); }
public function execute(Request $request, WorkingFolder $workingFolder, EventDispatcher $dispatcher, CacheManager $cache, ResizedImageRepository $resizedImageRepository, ThumbnailRepository $thumbnailRepository) { $fileName = $request->query->get('fileName'); $editedFile = new EditedFile($fileName, $this->app); $saveAsNew = false; if (!$editedFile->exists()) { $saveAsNew = true; $editedFile->saveAsNew(true); } if (!$editedFile->isValid()) { throw new InvalidUploadException('Invalid file provided'); } if (!Image::isSupportedExtension($editedFile->getExtension())) { throw new InvalidExtensionException('Unsupported image type or not image file'); } $imageFormat = Image::mimeTypeFromExtension($editedFile->getExtension()); $uploadedData = $request->get('content'); if (null === $uploadedData || strpos($uploadedData, 'data:image/png;base64,') !== 0) { throw new InvalidUploadException('Invalid upload. Expected base64 encoded PNG image.'); } $data = explode(',', $uploadedData); $data = isset($data[1]) ? base64_decode($data[1]) : false; if (!$data) { throw new InvalidUploadException(); } $uploadedImage = Image::create($data); $newContents = $uploadedImage->getData($imageFormat); $editFileEvent = new EditFileEvent($this->app, $editedFile, $newContents); $cache->set(Path::combine($workingFolder->getResourceType()->getName(), $workingFolder->getClientCurrentFolder(), $fileName), $uploadedImage->getInfo()); $dispatcher->dispatch(CKFinderEvent::SAVE_IMAGE, $editFileEvent); $saved = false; if (!$editFileEvent->isPropagationStopped()) { $saved = $editedFile->setContents($editFileEvent->getNewContents()); //Remove thumbnails and resized images in case if file is overwritten if (!$saveAsNew && $saved) { $resourceType = $workingFolder->getResourceType(); $thumbnailRepository->deleteThumbnails($resourceType, $workingFolder->getClientCurrentFolder(), $fileName); $resizedImageRepository->deleteResizedImages($resourceType, $workingFolder->getClientCurrentFolder(), $fileName); } } return array('saved' => (int) $saved, 'date' => Utils::formatDate(time())); }
public function execute(Request $request, WorkingFolder $workingFolder, Config $config, ThumbnailRepository $thumbnailRepository) { if (!$config->get('thumbnails.enabled')) { throw new CKFinderException('Thumbnails feature is disabled', Error::THUMBNAILS_DISABLED); } $fileName = $request->get('fileName'); $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); if (!Image::isSupportedExtension($ext, $thumbnailRepository->isBitmapSupportEnabled())) { throw new InvalidNameException('Invalid source file name'); } if (null === $fileName || !File::isValidName($fileName, $config->get('disallowUnsafeCharacters'))) { throw new InvalidRequestException('Invalid file name'); } list($requestedWidth, $requestedHeight) = Image::parseSize($request->get('size')); $thumbnail = $thumbnailRepository->getThumbnail($workingFolder->getResourceType(), $workingFolder->getClientCurrentFolder(), $fileName, $requestedWidth, $requestedHeight); /** * This was added on purpose to reset any Cache-Control headers set * for example by session_start(). Symfony Session has a workaround, * but but we can't rely on this as application may not use Symfony * components to handle sessions. */ header('Cache-Control:'); $response = new Response(); $response->setPublic(); $response->setEtag(dechex($thumbnail->getTimestamp()) . "-" . dechex($thumbnail->getSize())); $lastModificationDate = new \DateTime(); $lastModificationDate->setTimestamp($thumbnail->getTimestamp()); $response->setLastModified($lastModificationDate); if ($response->isNotModified($request)) { return $response; } $thumbnailsCacheExpires = (int) $config->get('cache.thumbnails'); if ($thumbnailsCacheExpires > 0) { $response->setMaxAge($thumbnailsCacheExpires); $expireTime = new \DateTime(); $expireTime->modify('+' . $thumbnailsCacheExpires . 'seconds'); $response->setExpires($expireTime); } $response->headers->set('Content-Type', $thumbnail->getMimeType() . '; name="' . $thumbnail->getFileName() . '"'); $response->setContent($thumbnail->getImageData()); return $response; }
public function execute(Request $request, WorkingFolder $workingFolder, Config $config, ThumbnailRepository $thumbnailRepository) { if (!$config->get('thumbnails.enabled')) { throw new CKFinderException('Thumbnails feature is disabled', Error::THUMBNAILS_DISABLED); } $fileName = (string) $request->get('fileName'); $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); if (!Image::isSupportedExtension($ext, $thumbnailRepository->isBitmapSupportEnabled())) { throw new InvalidNameException('Invalid source file name'); } if (null === $fileName || !File::isValidName($fileName, $config->get('disallowUnsafeCharacters'))) { throw new InvalidRequestException('Invalid file name'); } if (!$workingFolder->containsFile($fileName)) { throw new FileNotFoundException(); } list($requestedWidth, $requestedHeight) = Image::parseSize((string) $request->get('size')); $thumbnail = $thumbnailRepository->getThumbnail($workingFolder->getResourceType(), $workingFolder->getClientCurrentFolder(), $fileName, $requestedWidth, $requestedHeight); Utils::removeSessionCacheHeaders(); $response = new Response(); $response->setPublic(); $response->setEtag(dechex($thumbnail->getTimestamp()) . "-" . dechex($thumbnail->getSize())); $lastModificationDate = new \DateTime(); $lastModificationDate->setTimestamp($thumbnail->getTimestamp()); $response->setLastModified($lastModificationDate); if ($response->isNotModified($request)) { return $response; } $thumbnailsCacheExpires = (int) $config->get('cache.thumbnails'); if ($thumbnailsCacheExpires > 0) { $response->setMaxAge($thumbnailsCacheExpires); $expireTime = new \DateTime(); $expireTime->modify('+' . $thumbnailsCacheExpires . 'seconds'); $response->setExpires($expireTime); } $response->headers->set('Content-Type', $thumbnail->getMimeType() . '; name="' . $thumbnail->getFileName() . '"'); $response->setContent($thumbnail->getImageData()); return $response; }
/** * Creates a thumbnail * * @return bool * * @throws \Exception */ public function create() { $sourceBackend = $this->sourceFileResourceType->getBackend(); $sourceFilePath = Path::combine($this->sourceFileResourceType->getDirectory(), $this->sourceFileDir, $this->sourceFileName); if ($sourceBackend->isHiddenFile($this->sourceFileName) || !$sourceBackend->has($sourceFilePath)) { throw new FileNotFoundException('Thumbnail::create(): Source file not found'); } $image = Image::create($sourceBackend->read($sourceFilePath), $this->thumbnailRepository->isBitmapSupportEnabled()); // Update cached info about image $app = $this->thumbnailRepository->getContainer(); $app['cache']->set(Path::combine($this->sourceFileResourceType->getName(), $this->sourceFileDir, $this->sourceFileName), $image->getInfo()); $image->resize($this->adjustedSizeInfo['width'], $this->adjustedSizeInfo['height'], $this->adjustedSizeInfo['quality']); $this->resizedImageData = $image->getData(); $this->resizedImageSize = $image->getDataSize(); $this->resizedImageMimeType = $image->getMimeType(); unset($image); }
/** * @param Request $request * @param WorkingFolder $workingFolder * @param EventDispatcher $dispatcher * @param Acl $acl * * @return array * * @throws \Exception */ public function execute(Request $request, WorkingFolder $workingFolder, EventDispatcher $dispatcher, Acl $acl, ResizedImageRepository $resizedImageRepository, ThumbnailRepository $thumbnailRepository) { $fileName = (string) $request->get('fileName'); $newFileName = (string) $request->get('newFileName'); $editedImage = new EditedImage($fileName, $this->app, $newFileName); $resourceType = $workingFolder->getResourceType(); if (null === $newFileName) { $resourceTypeName = $resourceType->getName(); $path = $workingFolder->getClientCurrentFolder(); if (!$acl->isAllowed($resourceTypeName, $path, Permission::FILE_DELETE)) { throw new UnauthorizedException(sprintf('Unauthorized: no FILE_DELETE permission in %s:%s', $resourceTypeName, $path)); } } if (!Image::isSupportedExtension($editedImage->getExtension())) { throw new InvalidExtensionException('Unsupported image type or not image file'); } $image = Image::create($editedImage->getContents()); $actions = (array) $request->get('actions'); if (empty($actions)) { throw new InvalidRequestException(); } foreach ($actions as $actionInfo) { if (!isset($actionInfo['action'])) { throw new InvalidRequestException('ImageEdit: action name missing'); } switch ($actionInfo['action']) { case self::OPERATION_CROP: if (!Utils::arrayContainsKeys($actionInfo, array('x', 'y', 'width', 'height'))) { throw new InvalidRequestException(); } $x = $actionInfo['x']; $y = $actionInfo['y']; $width = $actionInfo['width']; $height = $actionInfo['height']; $image->crop($x, $y, $width, $height); break; case self::OPERATION_ROTATE: if (!isset($actionInfo['angle'])) { throw new InvalidRequestException(); } $degrees = $actionInfo['angle']; $bgcolor = isset($actionInfo['bgcolor']) ? $actionInfo['bgcolor'] : 0; $image->rotate($degrees, $bgcolor); break; case self::OPERATION_RESIZE: if (!Utils::arrayContainsKeys($actionInfo, array('width', 'height'))) { throw new InvalidRequestException(); } $width = $actionInfo['width']; $height = $actionInfo['height']; $image->resize($width, $height); break; } } $editFileEvent = new EditFileEvent($this->app, $editedImage); $editedImage->setNewContents($image->getData()); $editedImage->setNewDimensions($image->getWidth(), $image->getHeight()); if (!$editedImage->isValid()) { throw new InvalidUploadException('Invalid file provided'); } $dispatcher->dispatch(CKFinderEvent::EDIT_IMAGE, $editFileEvent); $saved = false; if (!$editFileEvent->isPropagationStopped()) { $saved = $editedImage->save($editFileEvent->getNewContents()); //Remove thumbnails and resized images in case if file is overwritten if ($newFileName === null && $saved) { $thumbnailRepository->deleteThumbnails($resourceType, $workingFolder->getClientCurrentFolder(), $fileName); $resizedImageRepository->deleteResizedImages($resourceType, $workingFolder->getClientCurrentFolder(), $fileName); } } return array('saved' => (int) $saved, 'date' => Utils::formatDate(time())); }
public function execute(Request $request, WorkingFolder $workingFolder, EventDispatcher $dispatcher, Config $config, CacheManager $cache, ThumbnailRepository $thumbsRepository) { // #111 IE9 download JSON issue workaround if ($request->get('asPlainText')) { $uploadEvents = array(CKFinderEvent::AFTER_COMMAND_FILE_UPLOAD, CKFinderEvent::AFTER_COMMAND_QUICK_UPLOAD); foreach ($uploadEvents as $eventName) { $dispatcher->addListener($eventName, function (AfterCommandEvent $event) { $response = $event->getResponse(); $response->headers->set('Content-Type', 'text/plain'); }); } } $uploaded = 0; $warningErrorCode = null; $upload = $request->files->get('upload'); if (null === $upload) { throw new InvalidUploadException(); } $uploadedFile = new UploadedFile($upload, $this->app); if (!$uploadedFile->isValid()) { throw new InvalidUploadException($uploadedFile->getErrorMessage()); } $uploadedFile->sanitizeFilename(); if ($uploadedFile->wasRenamed()) { $warningErrorCode = Error::UPLOADED_INVALID_NAME_RENAMED; } if (!$uploadedFile->hasValidFilename() || $uploadedFile->isHiddenFile()) { throw new InvalidNameException(); } if (!$uploadedFile->hasAllowedExtension()) { throw new InvalidExtensionException(); } // Autorename if required $overwriteOnUpload = $config->get('overwriteOnUpload'); if (!$overwriteOnUpload && $uploadedFile->autorename()) { $warningErrorCode = Error::UPLOADED_FILE_RENAMED; } $fileName = $uploadedFile->getFilename(); if (!$uploadedFile->isAllowedHtmlFile() && $uploadedFile->containsHtml()) { throw new InvalidUploadException('HTML detected in disallowed file type', Error::UPLOADED_WRONG_HTML_FILE); } if ($config->get('secureImageUploads') && $uploadedFile->isImage() && !$uploadedFile->isValidImage()) { throw new InvalidUploadException('Invalid upload: corrupted image', Error::UPLOADED_CORRUPT); } $maxFileSize = $workingFolder->getResourceType()->getMaxSize(); if (!$config->get('checkSizeAfterScaling') && $maxFileSize && $uploadedFile->getSize() > $maxFileSize) { throw new InvalidUploadException('Uploaded file is too big', Error::UPLOADED_TOO_BIG); } if (Image::isSupportedExtension($uploadedFile->getExtension())) { $imagesConfig = $config->get('images'); $image = Image::create($uploadedFile->getContents()); if ($image->getWidth() > $imagesConfig['maxWidth'] || $image->getHeight() > $imagesConfig['maxHeight']) { $image->resize($imagesConfig['maxWidth'], $imagesConfig['maxHeight'], $imagesConfig['quality']); $imageData = $image->getData(); $uploadedFile->setContents($imageData); } $cache->set(Path::combine($workingFolder->getResourceType()->getName(), $workingFolder->getClientCurrentFolder(), $fileName), $image->getInfo()); unset($imageData); unset($image); } if ($maxFileSize && $uploadedFile->getSize() > $maxFileSize) { throw new InvalidUploadException('Uploaded file is too big', Error::UPLOADED_TOO_BIG); } $event = new FileUploadEvent($this->app, $uploadedFile); $dispatcher->dispatch(CKFinderEvent::FILE_UPLOAD, $event); if (!$event->isPropagationStopped()) { $uploadedFileStream = $uploadedFile->getContentsStream(); $uploaded = (int) $workingFolder->putStream($fileName, $uploadedFileStream); if ($overwriteOnUpload) { $thumbsRepository->deleteThumbnails($workingFolder->getResourceType(), $workingFolder->getClientCurrentFolder(), $fileName); } if (!$uploaded) { $warningErrorCode = Error::ACCESS_DENIED; } } $responseData = array('fileName' => $fileName, 'uploaded' => $uploaded); if ($warningErrorCode) { $errorMessage = $this->app['translator']->translateErrorMessage($warningErrorCode, array($fileName)); $responseData['error'] = array('number' => $warningErrorCode, 'message' => $errorMessage); } return $responseData; }