vendor/pimcore/pimcore/bundles/CoreBundle/Controller/PublicServicesController.php line 187

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Bundle\CoreBundle\Controller;
  15. use function date;
  16. use function fstat;
  17. use function is_array;
  18. use Pimcore\Config;
  19. use Pimcore\Controller\Controller;
  20. use Pimcore\File;
  21. use Pimcore\Logger;
  22. use Pimcore\Model\Asset;
  23. use Pimcore\Model\Site;
  24. use Pimcore\Model\Tool\TmpStore;
  25. use Pimcore\Tool\Storage;
  26. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  27. use Symfony\Component\HttpFoundation\Cookie;
  28. use Symfony\Component\HttpFoundation\RedirectResponse;
  29. use Symfony\Component\HttpFoundation\Request;
  30. use Symfony\Component\HttpFoundation\Response;
  31. use Symfony\Component\HttpFoundation\StreamedResponse;
  32. use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
  33. use function time;
  34. /**
  35.  * @internal
  36.  */
  37. class PublicServicesController extends Controller
  38. {
  39.     /**
  40.      * @param Request $request
  41.      *
  42.      * @return BinaryFileResponse|StreamedResponse
  43.      */
  44.     public function thumbnailAction(Request $request)
  45.     {
  46.         $assetId $request->get('assetId');
  47.         $thumbnailName $request->get('thumbnailName');
  48.         $filename $request->get('filename');
  49.         $requestedFileExtension strtolower(File::getFileExtension($filename));
  50.         $asset Asset::getById($assetId);
  51.         $prefix preg_replace('@^cache-buster\-[\d]+\/@'''$request->get('prefix'));
  52.         if ($asset && $asset->getPath() === ('/' $prefix)) {
  53.             // we need to check the path as well, this is important in the case you have restricted the public access to
  54.             // assets via rewrite rules
  55.             try {
  56.                 $imageThumbnail null;
  57.                 $thumbnailStream null;
  58.                 // just check if the thumbnail exists -> throws exception otherwise
  59.                 $thumbnailConfig Asset\Image\Thumbnail\Config::getByName($thumbnailName);
  60.                 if (!$thumbnailConfig) {
  61.                     // check if there's an item in the TmpStore
  62.                     // remove an eventually existing cache-buster prefix first (eg. when using with a CDN)
  63.                     $pathInfo preg_replace('@^/cache-buster\-[\d]+@'''$request->getPathInfo());
  64.                     $deferredConfigId 'thumb_' $assetId '__' md5(urldecode($pathInfo));
  65.                     if ($thumbnailConfigItem TmpStore::get($deferredConfigId)) {
  66.                         $thumbnailConfig $thumbnailConfigItem->getData();
  67.                         TmpStore::delete($deferredConfigId);
  68.                         if (!$thumbnailConfig instanceof Asset\Image\Thumbnail\Config) {
  69.                             throw new \Exception("Deferred thumbnail config file doesn't contain a valid \\Asset\\Image\\Thumbnail\\Config object");
  70.                         }
  71.                     }
  72.                 }
  73.                 if (!$thumbnailConfig) {
  74.                     throw $this->createNotFoundException("Thumbnail '" $thumbnailName "' file doesn't exist");
  75.                 }
  76.                 if (strcasecmp($thumbnailConfig->getFormat(), 'SOURCE') === 0) {
  77.                     $formatOverride $requestedFileExtension;
  78.                     if (in_array($requestedFileExtension, ['jpg''jpeg'])) {
  79.                         $formatOverride 'pjpeg';
  80.                     }
  81.                     $thumbnailConfig->setFormat($formatOverride);
  82.                 }
  83.                 if ($asset instanceof Asset\Video) {
  84.                     $time 1;
  85.                     if (preg_match("|~\-~time\-(\d+)\.|"$filename$matchesThumbs)) {
  86.                         $time = (int)$matchesThumbs[1];
  87.                     }
  88.                     $imageThumbnail $asset->getImageThumbnail($thumbnailConfig$time);
  89.                     $thumbnailStream $imageThumbnail->getStream();
  90.                 } elseif ($asset instanceof Asset\Document) {
  91.                     $page 1;
  92.                     if (preg_match("|~\-~page\-(\d+)\.|"$filename$matchesThumbs)) {
  93.                         $page = (int)$matchesThumbs[1];
  94.                     }
  95.                     $thumbnailConfig->setName(preg_replace("/\-[\d]+/"''$thumbnailConfig->getName()));
  96.                     $thumbnailConfig->setName(str_replace('document_'''$thumbnailConfig->getName()));
  97.                     $imageThumbnail $asset->getImageThumbnail($thumbnailConfig$page);
  98.                     $thumbnailStream $imageThumbnail->getStream();
  99.                 } elseif ($asset instanceof Asset\Image) {
  100.                     //check if high res image is called
  101.                     preg_match("@([^\@]+)(\@[0-9.]+x)?\.([a-zA-Z]{2,5})@"$filename$matches);
  102.                     if (empty($matches) || !isset($matches[1])) {
  103.                         throw $this->createNotFoundException('Requested asset does not exist');
  104.                     }
  105.                     if (array_key_exists(2$matches) && $matches[2]) {
  106.                         $highResFactor = (float) str_replace(['@''x'], ''$matches[2]);
  107.                         $thumbnailConfig->setHighResolution($highResFactor);
  108.                     }
  109.                     // check if a media query thumbnail was requested
  110.                     if (preg_match("#~\-~media\-\-(.*)\-\-query#"$matches[1], $mediaQueryResult)) {
  111.                         $thumbnailConfig->selectMedia($mediaQueryResult[1]);
  112.                     }
  113.                     $imageThumbnail $asset->getThumbnail($thumbnailConfig);
  114.                     $thumbnailStream $imageThumbnail->getStream();
  115.                 }
  116.                 if ($imageThumbnail && $thumbnailStream) {
  117.                     $pathReference $imageThumbnail->getPathReference();
  118.                     $actualFileExtension File::getFileExtension($pathReference['src']);
  119.                     if ($actualFileExtension !== $requestedFileExtension) {
  120.                         // create a copy/symlink to the file with the original file extension
  121.                         // this can be e.g. the case when the thumbnail is called as foo.png but the thumbnail config
  122.                         // is set to auto-optimized format so the resulting thumbnail can be jpeg
  123.                         $requestedFile preg_replace('/\.' $actualFileExtension '$/''.' $requestedFileExtension$pathReference['src']);
  124.                         Storage::get('thumbnail')->writeStream($requestedFile$thumbnailStream);
  125.                     }
  126.                     // set appropriate caching headers
  127.                     // see also: https://github.com/pimcore/pimcore/blob/1931860f0aea27de57e79313b2eb212dcf69ef13/.htaccess#L86-L86
  128.                     $lifetime 86400 7// 1 week lifetime, same as direct delivery in .htaccess
  129.                     $headers = [
  130.                         'Cache-Control' => 'public, max-age=' $lifetime,
  131.                         'Expires' => date('D, d M Y H:i:s T'time() + $lifetime),
  132.                         'Content-Type' => $imageThumbnail->getMimeType(),
  133.                     ];
  134.                     $stats fstat($thumbnailStream);
  135.                     if (is_array($stats)) {
  136.                         $headers['Content-Length'] = $stats['size'];
  137.                     }
  138.                     $headers[AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER] = true;
  139.                     return new StreamedResponse(function () use ($thumbnailStream) {
  140.                         fpassthru($thumbnailStream);
  141.                     }, 200$headers);
  142.                 }
  143.                 throw new \Exception('Unable to generate thumbnail, see logs for details.');
  144.             } catch (\Exception $e) {
  145.                 Logger::error($e->getMessage());
  146.                 return new BinaryFileResponse(PIMCORE_WEB_ROOT '/bundles/pimcoreadmin/img/filetype-not-supported.svg'200);
  147.             }
  148.         }
  149.         throw $this->createNotFoundException('Asset not found');
  150.     }
  151.     /**
  152.      * @param Request $request
  153.      *
  154.      * @return Response
  155.      */
  156.     public function robotsTxtAction(Request $request)
  157.     {
  158.         // check for site
  159.         $domain \Pimcore\Tool::getHostname();
  160.         $site Site::getByDomain($domain);
  161.         $config Config::getRobotsConfig()->toArray();
  162.         $siteId 'default';
  163.         if ($site instanceof Site) {
  164.             $siteId $site->getId();
  165.         }
  166.         // send correct headers
  167.         header('Content-Type: text/plain; charset=utf8');
  168.         while (@ob_end_flush()) ;
  169.         // check for configured robots.txt in pimcore
  170.         $content '';
  171.         if (array_key_exists($siteId$config)) {
  172.             $content $config[$siteId];
  173.         }
  174.         if (empty($content)) {
  175.             // default behavior, allow robots to index everything
  176.             $content "User-agent: *\nDisallow:";
  177.         }
  178.         return new Response($contentResponse::HTTP_OK, [
  179.             'Content-Type' => 'text/plain',
  180.         ]);
  181.     }
  182.     /**
  183.      * @param Request $request
  184.      *
  185.      * @return Response
  186.      */
  187.     public function commonFilesAction(Request $request)
  188.     {
  189.         return new Response("HTTP/1.1 404 Not Found\nFiltered by common files filter"404);
  190.     }
  191.     /**
  192.      * @param Request $request
  193.      *
  194.      * @return \Symfony\Component\HttpFoundation\RedirectResponse
  195.      */
  196.     public function customAdminEntryPointAction(Request $request)
  197.     {
  198.         $params $request->query->all();
  199.         if (isset($params['token'])) {
  200.             $url $this->generateUrl('pimcore_admin_login_check'$params);
  201.         } else {
  202.             $url $this->generateUrl('pimcore_admin_login'$params);
  203.         }
  204.         $redirect = new RedirectResponse($url);
  205.         $customAdminPathIdentifier $this->getParameter('pimcore_admin.custom_admin_path_identifier');
  206.         if (!empty($customAdminPathIdentifier) && $request->cookies->get('pimcore_custom_admin') != $customAdminPathIdentifier) {
  207.             $redirect->headers->setCookie(new Cookie('pimcore_custom_admin'$customAdminPathIdentifierstrtotime('+1 year'), '/'nullfalsetrue));
  208.         }
  209.         return $redirect;
  210.     }
  211. }