/** * Constructor. * * @param string $newFileName new file name * @param string $fileName current file name * @param string $folder current file folder * @param ResourceType $resourceType current file resource type * @param CKFinder $app CKFinder app */ public function __construct($newFileName, $fileName, $folder, ResourceType $resourceType, CKFinder $app) { parent::__construct($fileName, $folder, $resourceType, $app); $this->newFileName = static::secureName($newFileName, $this->config->get('disallowUnsafeCharacters')); if ($this->config->get('checkDoubleExtension')) { $this->newFileName = Utils::replaceDisallowedExtensions($this->newFileName, $resourceType); } }
/** * Checks if the current user has any storage quota left. * * @return bool `false` if current user storage quota was exceeded, `true` otherwise. */ protected function isQuotaAvailable() { // Get the user quota in bytes. $quota = Utils::returnBytes($this->app['config']->get('DiskQuota.userQuota')); /** * For documentation purposes it is only a method stub. * * @todo Custom implementation of the current user quota check. */ return true; }
public function execute(Request $request, Config $config, WorkingFolder $workingFolder, ResizedImageRepository $resizedImageRepository, CacheManager $cache) { $fileName = (string) $request->query->get('fileName'); list($requestedWidth, $requestedHeight) = Image::parseSize((string) $request->get('size')); $downloadedFile = new DownloadedFile($fileName, $this->app); $downloadedFile->isValid(); if (!Image::isSupportedExtension(pathinfo($fileName, PATHINFO_EXTENSION), $config->get('thumbnails.bmpSupported'))) { throw new InvalidExtensionException('Unsupported image type or not image file'); } Utils::removeSessionCacheHeaders(); $response = new Response(); $response->setPublic(); $response->setEtag(dechex($downloadedFile->getTimestamp()) . "-" . dechex($downloadedFile->getSize())); $lastModificationDate = new \DateTime(); $lastModificationDate->setTimestamp($downloadedFile->getTimestamp()); $response->setLastModified($lastModificationDate); if ($response->isNotModified($request)) { return $response; } $imagePreviewCacheExpires = (int) $config->get('cache.imagePreview'); if ($imagePreviewCacheExpires > 0) { $response->setMaxAge($imagePreviewCacheExpires); $expireTime = new \DateTime(); $expireTime->modify('+' . $imagePreviewCacheExpires . 'seconds'); $response->setExpires($expireTime); } $cachedInfoPath = Path::combine($workingFolder->getResourceType()->getName(), $workingFolder->getClientCurrentFolder(), $fileName); $cachedInfo = $cache->get($cachedInfoPath); $resultImage = null; // Try to reuse existing resized image if ($cachedInfo && isset($cachedInfo['width']) && isset($cachedInfo['height'])) { // Fix received aspect ratio $size = Image::calculateAspectRatio($requestedWidth, $requestedHeight, $cachedInfo['width'], $cachedInfo['height']); $resizedImage = $resizedImageRepository->getResizedImageBySize($workingFolder->getResourceType(), $workingFolder->getClientCurrentFolder(), $fileName, $size['width'], $size['height']); if ($resizedImage) { $resultImage = Image::create($resizedImage->getImageData()); } } // Fallback - get and resize the original image if (null === $resultImage) { $resultImage = Image::create($downloadedFile->getContents(), $config->get('thumbnails.bmpSupported')); $cache->set($cachedInfoPath, $resultImage->getInfo()); $resultImage->resize($requestedWidth, $requestedHeight); } $mimeType = $resultImage->getMimeType(); if (in_array($mimeType, array('image/bmp', 'image/x-ms-bmp'))) { $mimeType = 'image/jpeg'; // Image::getData() by default converts resized images to JPG } $response->headers->set('Content-Type', $mimeType . '; name="' . $downloadedFile->getFileName() . '"'); $response->setContent($resultImage->getData()); return $response; }
public function execute(WorkingFolder $workingFolder) { $data = new \stdClass(); $files = $workingFolder->listFiles(); $data->files = array(); foreach ($files as $file) { $fileObject = array('name' => $file['basename'], 'date' => Utils::formatDate($file['timestamp']), 'size' => Utils::formatSize($file['size'])); $data->files[] = $fileObject; } // Sort files usort($data->files, function ($a, $b) { return strnatcasecmp($a['name'], $b['name']); }); return $data; }
/** * Consructor * * @param array $backendConfig * * @throws \Exception if root folder is not writable */ public function __construct(array $backendConfig) { $this->backendConfig = $backendConfig; if (!isset($backendConfig['root']) || empty($backendConfig['root'])) { $baseUrl = $backendConfig['baseUrl']; $baseUrl = preg_replace("|^http(s)?://[^/]+|i", "", $baseUrl); $backendConfig['root'] = Path::combine(Utils::getRootPath(), Utils::decodeURLParts($baseUrl)); } if (!is_dir($backendConfig['root'])) { @mkdir($backendConfig['root'], $backendConfig['chmodFolders'], true); if (!is_dir($backendConfig['root'])) { throw new FolderNotFoundException(sprintf('The root folder of backend "%s" not found (%s)', $backendConfig['name'], $backendConfig['root'])); } } if (!is_writable($backendConfig['root'])) { throw new AccessDeniedException(sprintf('The root folder of backend "%s" is not writable (%s)', $backendConfig['name'], $backendConfig['root'])); } parent::__construct($backendConfig['root']); }
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 = (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; }
/** * Detect HTML in the first KB to prevent against potential security issue with * IE/Safari/Opera file type auto detection bug. * Returns true if file contain insecure HTML code at the beginning. * * @return boolean true if uploaded file contains html in first 1024 bytes */ public function containsHtml() { $fp = fopen($this->tempFilePath, 'rb'); $chunk = fread($fp, 1024); fclose($fp); return Utils::containsHtml($chunk); }
public function execute(Request $request, Acl $acl, Config $config, ResourceTypeFactory $resourceTypeFactory) { $data = new \stdClass(); /** * Connector is always enabled here * * @see CKFinder::checkAuth() */ $data->enabled = true; $ln = ''; $lc = str_replace('-', '', ($config->get('licenseKey') ?: $config->get('LicenseKey')) . ' '); $pos = strpos(CKFinder::CHARS, $lc[2]) % 5; if ($pos == 1 || $pos == 2) { $ln = $config->get('licenseName') ?: $config->get('LicenseName'); } $data->s = $ln; $data->c = trim($lc[1] . $lc[8] . $lc[17] . $lc[22] . $lc[3] . $lc[13] . $lc[11] . $lc[20] . $lc[5] . $lc[24] . $lc[27]); // Thumbnails $thumbnailsConfig = $config->get('thumbnails'); $thumbnailsEnabled = (bool) $thumbnailsConfig['enabled']; if ($thumbnailsEnabled) { $sizes = array(); foreach ($thumbnailsConfig['sizes'] as $sizeInfo) { $sizes[] = sprintf("%dx%d", $sizeInfo['width'], $sizeInfo['height']); } $data->thumbs = $sizes; } // Images $imagesConfig = $config->get('images'); $images = array('max' => $imagesConfig['maxWidth'] . 'x' . $imagesConfig['maxHeight']); if (isset($imagesConfig['sizes'])) { $resize = array(); foreach ($imagesConfig['sizes'] as $name => $sizeInfo) { $resize[$name] = $sizeInfo['width'] . 'x' . $sizeInfo['height']; } $images['sizes'] = $resize; } $data->images = $images; $resourceTypesNames = $config->getDefaultResourceTypes() ?: $config->getResourceTypes(); $data->resourceTypes = array(); if (!empty($resourceTypesNames)) { $phpMaxSize = 0; $maxUpload = Utils::returnBytes(ini_get('upload_max_filesize')); if ($maxUpload) { $phpMaxSize = $maxUpload; } $maxPost = Utils::returnBytes(ini_get('post_max_size')); if ($maxPost) { $phpMaxSize = $phpMaxSize ? min($phpMaxSize, $maxPost) : $maxPost; } //ini_get('memory_limit') only works if compiled with "--enable-memory-limit" $memoryLimit = Utils::returnBytes(@ini_get('memory_limit')); if ($memoryLimit && $memoryLimit != -1) { $phpMaxSize = $phpMaxSize ? min($phpMaxSize, $memoryLimit) : $memoryLimit; } $data->uploadMaxSize = $phpMaxSize; $data->uploadCheckImages = !$config->get('checkSizeAfterScaling'); $requestedType = (string) $request->query->get('type'); foreach ($resourceTypesNames as $resourceTypeName) { if ($requestedType && $requestedType !== $resourceTypeName) { continue; } $aclMask = $acl->getComputedMask($resourceTypeName, '/'); if (!(Permission::FOLDER_VIEW & $aclMask)) { continue; } $resourceType = $resourceTypeFactory->getResourceType($resourceTypeName); $resourceTypeObject = array('name' => $resourceTypeName, 'allowedExtensions' => implode(",", $resourceType->getAllowedExtensions()), 'deniedExtensions' => implode(",", $resourceType->getDeniedExtensions()), 'hash' => $resourceType->getHash(), 'acl' => $aclMask, 'maxSize' => $resourceType->getMaxSize() ? min($resourceType->getMaxSize(), $phpMaxSize) : $phpMaxSize); $resourceTypeBackend = $resourceType->getBackend(); if ($resourceType->isLazyLoaded()) { $resourceTypeObject['hasChildren'] = false; $resourceTypeObject['lazyLoad'] = true; } else { $resourceTypeObject['hasChildren'] = $resourceTypeBackend->containsDirectories($resourceType, $resourceType->getDirectory()); } if ($label = $resourceType->getLabel()) { $resourceTypeObject['label'] = $label; } $useProxyCommand = $resourceTypeBackend->usesProxyCommand(); if ($useProxyCommand) { $resourceTypeObject['useProxyCommand'] = true; } else { $baseUrl = $resourceTypeBackend->getBaseUrl(); if ($baseUrl) { $resourceTypeObject['url'] = rtrim(Path::combine($baseUrl, $resourceType->getDirectory()), '/') . '/'; } } $trackedOperations = $resourceTypeBackend->getTrackedOperations(); if (!empty($trackedOperations)) { $resourceTypeObject['trackedOperations'] = $trackedOperations; } $data->resourceTypes[] = $resourceTypeObject; } } $enabledPlugins = $config->get('plugins'); if (!empty($enabledPlugins)) { $data->plugins = $enabledPlugins; } $proxyCacheLifetime = (int) $config->get('cache.proxyCommand'); if ($proxyCacheLifetime) { $data->proxyCache = $proxyCacheLifetime; } return $data; }
/** * Returns a URL to a file. * * If the useProxyCommand option is set for a backend, the returned * URL will point to the CKFinder connector Proxy command. * * @param ResourceType $resourceType the file resource type * @param string $folderPath the resource-type relative folder path * @param string $fileName the file name * @param string|null $thumbnailFileName the thumbnail file name - if the file is a thumbnail * * @return string|null URL to a file or `null` if the backend does not support it. */ public function getFileUrl(ResourceType $resourceType, $folderPath, $fileName, $thumbnailFileName = null) { if (isset($this->backendConfig['useProxyCommand'])) { $connectorUrl = $this->app->getConnectorUrl(); $queryParameters = array('command' => 'Proxy', 'type' => $resourceType->getName(), 'currentFolder' => $folderPath, 'fileName' => $fileName); if ($thumbnailFileName) { $queryParameters['thumbnail'] = $thumbnailFileName; } $proxyCacheLifetime = (int) $this->ckConfig->get('cache.proxyCommand'); if ($proxyCacheLifetime > 0) { $queryParameters['cache'] = $proxyCacheLifetime; } return $connectorUrl . '?' . http_build_query($queryParameters, '', '&'); } $path = $thumbnailFileName ? Path::combine($resourceType->getDirectory(), $folderPath, ResizedImage::DIR, $fileName, $thumbnailFileName) : Path::combine($resourceType->getDirectory(), $folderPath, $fileName); if (isset($this->backendConfig['baseUrl'])) { return Path::combine($this->backendConfig['baseUrl'], Utils::encodeURLParts($path)); } $baseAdapter = $this->getBaseAdapter(); if (method_exists($baseAdapter, 'getFileUrl')) { return $baseAdapter->getFileUrl($path); } return null; }
/** * @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())); }
/** * Processes configuration array */ protected function process() { $this->options['defaultResourceTypes'] = array_filter(array_map('trim', explode(',', $this->options['defaultResourceTypes'])), 'strlen'); $formatToArray = function ($input) { $input = is_array($input) ? $input : explode(',', $input); return array_filter(array_map('strtolower', array_map('trim', $input)), 'strlen'); }; foreach ($this->options['resourceTypes'] as $i => $resourceTypeConfig) { $resourceTypeConfig['allowedExtensions'] = $formatToArray($resourceTypeConfig['allowedExtensions']); $resourceTypeConfig['deniedExtensions'] = $formatToArray($resourceTypeConfig['deniedExtensions']); $resourceTypeConfig['maxSize'] = Utils::returnBytes((string) $resourceTypeConfig['maxSize']); $this->options['resourceTypes'][$resourceTypeConfig['name']] = $resourceTypeConfig; unset($this->options['resourceTypes'][$i]); } $this->options['htmlExtensions'] = $formatToArray($this->options['htmlExtensions']); }
/** * Adds current folder info to the response * * @param FilterResponseEvent $event */ public function addCurrentFolderInfo(FilterResponseEvent $event) { /* @var JsonResponse $response */ $response = $event->getResponse(); if ($response instanceof JsonResponse) { $responseData = (array) $response->getData(); $responseData = array('resourceType' => $this->getResourceTypeName(), 'currentFolder' => array('path' => $this->getClientCurrentFolder(), 'acl' => $this->getAclMask())) + $responseData; $baseUrl = $this->backend->getBaseUrl(); if (null !== $baseUrl) { $folderUrl = Path::combine($baseUrl, Utils::encodeURLParts(Path::combine($this->resourceType->getDirectory(), $this->getClientCurrentFolder()))); $responseData['currentFolder']['url'] = rtrim($folderUrl, '/') . '/'; } $response->setData($responseData); } }
/** * Validates the file * * @return bool true if file passed the validation * * @throws AlreadyExistsException * @throws FileNotFoundException * @throws InvalidExtensionException * @throws InvalidNameException * @throws InvalidRequestException * @throws InvalidUploadException */ public function isValid() { if ($this->newFileName) { if (!File::isValidName($this->newFileName, $this->config->get('disallowUnsafeCharacters'))) { throw new InvalidNameException('Invalid file name'); } if ($this->resourceType->getBackend()->isHiddenFile($this->newFileName)) { throw new InvalidRequestException('New provided file name is hidden'); } if (!$this->resourceType->isAllowedExtension($this->getNewExtension())) { throw new InvalidExtensionException(); } if ($this->config->get('checkDoubleExtension') && !$this->areValidDoubleExtensions($this->newFileName)) { throw new InvalidExtensionException(); } if ($this->workingFolder->containsFile($this->newFileName)) { throw new AlreadyExistsException('File already exists'); } } if (!$this->hasValidFilename() || !$this->hasValidPath()) { throw new InvalidRequestException('Invalid filename or path'); } if ($this->isHidden() || $this->hasHiddenPath()) { throw new InvalidRequestException('Edited file is hidden'); } if ($this->config->get('checkDoubleExtension') && !$this->areValidDoubleExtensions()) { throw new InvalidExtensionException(); } if (!$this->resourceType->isAllowedExtension($this->getExtension())) { throw new InvalidExtensionException(); } if (!$this->saveAsNew && !$this->exists()) { throw new FileNotFoundException(); } if ($this->newContents) { if (Utils::containsHtml(substr($this->newContents, 0, 1024)) && !in_array(strtolower($this->newFileName ? $this->getNewExtension() : $this->getExtension()), $this->config->get('htmlExtensions'))) { throw new InvalidUploadException('HTML detected in disallowed file type', Error::UPLOADED_WRONG_HTML_FILE); } $maxFileSize = $this->resourceType->getMaxSize(); if ($maxFileSize && strlen($this->newContents) > $maxFileSize) { throw new InvalidUploadException('Uploaded file is too big', Error::UPLOADED_TOO_BIG); } } return true; }
/** * Returns a direct url to a file * * @param string $path * * @return string|null direct url to a file or null if backend * doesn't support direct access */ public function getFileUrl($path) { if (method_exists($this->adapter, 'getFileUrl')) { return $this->adapter->getFileUrl($path); } if (isset($this->backendConfig['baseUrl'])) { return Path::combine($this->backendConfig['baseUrl'], Utils::encodeURLParts($path)); } return null; }
/** * @link http://pl.php.net/manual/pl/function.imagecreatefromjpeg.php * function posted by e dot a dot schultz at gmail dot com * * @param $imageWidth * @param $imageHeight * @param $imageBits * @param $imageChannels * * @return bool */ public function setMemory($imageWidth, $imageHeight, $imageBits, $imageChannels) { $MB = 1048576; // number of bytes in 1M $K64 = 65536; // number of bytes in 64K $TWEAKFACTOR = 2.4; // Or whatever works for you $memoryNeeded = round(($imageWidth * $imageHeight * $imageBits * $imageChannels / 8 + $K64) * $TWEAKFACTOR) + 3 * $MB; //ini_get('memory_limit') only works if compiled with "--enable-memory-limit" also //Default memory limit is 8MB so well stick with that. //To find out what yours is, view your php.ini file. $memoryLimit = Utils::returnBytes(@ini_get('memory_limit')) / $MB; // There are no memory limits, nothing to do if ($memoryLimit == -1) { return true; } if (!$memoryLimit) { $memoryLimit = 8; } $memoryLimitMB = $memoryLimit * $MB; if (function_exists('memory_get_usage')) { if (memory_get_usage() + $memoryNeeded > $memoryLimitMB) { $newLimit = $memoryLimit + ceil((memory_get_usage() + $memoryNeeded - $memoryLimitMB) / $MB); if (@ini_set('memory_limit', $newLimit . 'M') === false) { return false; } } } else { if ($memoryNeeded + 3 * $MB > $memoryLimitMB) { $newLimit = $memoryLimit + ceil((3 * $MB + $memoryNeeded - $memoryLimitMB) / $MB); if (false === @ini_set('memory_limit', $newLimit . 'M')) { return false; } } } return true; }
public function execute(Request $request, WorkingFolder $workingFolder, EventDispatcher $dispatcher, Config $config) { $fileName = (string) $request->query->get('fileName'); $thumbnailFileName = (string) $request->query->get('thumbnail'); if (!File::isValidName($fileName, $config->get('disallowUnsafeCharacters'))) { throw new InvalidRequestException(sprintf('Invalid file name: %s', $fileName)); } $cacheLifetime = (int) $request->query->get('cache'); if (!$workingFolder->containsFile($fileName)) { throw new FileNotFoundException(); } if ($thumbnailFileName) { if (!File::isValidName($thumbnailFileName, $config->get('disallowUnsafeCharacters'))) { throw new InvalidRequestException(sprintf('Invalid resized image file name: %s', $fileName)); } if (!$workingFolder->getResourceType()->isAllowedExtension(pathinfo($thumbnailFileName, PATHINFO_EXTENSION))) { throw new InvalidExtensionException(); } $resizedImageRespository = $this->app->getResizedImageRepository(); $file = $resizedImageRespository->getExistingResizedImage($workingFolder->getResourceType(), $workingFolder->getClientCurrentFolder(), $fileName, $thumbnailFileName); $dataStream = $file->readStream(); } else { $file = new DownloadedFile($fileName, $this->app); $file->isValid(); $dataStream = $workingFolder->readStream($file->getFilename()); } $proxyDownload = new ProxyDownloadEvent($this->app, $file); $dispatcher->dispatch(CKFinderEvent::PROXY_DOWNLOAD, $proxyDownload); if ($proxyDownload->isPropagationStopped()) { throw new AccessDeniedException(); } $response = new StreamedResponse(); $response->headers->set('Content-Type', $file->getMimeType()); $response->headers->set('Content-Length', $file->getSize()); $response->headers->set('Content-Disposition', 'inline; filename="' . $fileName . '"'); if ($cacheLifetime > 0) { Utils::removeSessionCacheHeaders(); $response->setPublic(); $response->setEtag(dechex($file->getTimestamp()) . "-" . dechex($file->getSize())); $lastModificationDate = new \DateTime(); $lastModificationDate->setTimestamp($file->getTimestamp()); $response->setLastModified($lastModificationDate); if ($response->isNotModified($request)) { return $response; } $response->setMaxAge($cacheLifetime); $expireTime = new \DateTime(); $expireTime->modify('+' . $cacheLifetime . 'seconds'); $response->setExpires($expireTime); } $chunkSize = 1024 * 100; $response->setCallback(function () use($dataStream, $chunkSize) { if ($dataStream === false) { return false; } while (!feof($dataStream)) { echo fread($dataStream, $chunkSize); flush(); @set_time_limit(8); } return true; }); return $response; }
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())); }