Source of file FilesystemPublisher.php
Size: 7,308 Bytes - Last Modified: 2021-12-23T10:34:48+00:00
/var/www/docs.ssmods.com/process/src/src/Publisher/FilesystemPublisher.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 | <?php namespace SilverStripe\StaticPublishQueue\Publisher; use SilverStripe\Assets\Filesystem; use SilverStripe\Control\HTTPResponse; use SilverStripe\Core\Config\Config; use SilverStripe\Security\SecurityToken; use SilverStripe\StaticPublishQueue\Publisher; use function SilverStripe\StaticPublishQueue\PathToURL; use function SilverStripe\StaticPublishQueue\URLtoPath; class FilesystemPublisher extends Publisher { /** * @var string */ protected $destFolder = 'cache'; /** * @var string */ protected $fileExtension = 'php'; /** * @return string */ public function getDestPath() { $base = defined('PUBLIC_PATH') ? PUBLIC_PATH : BASE_PATH; return $base . DIRECTORY_SEPARATOR . $this->getDestFolder(); } public function setDestFolder($destFolder) { $this->destFolder = $destFolder; return $this; } public function getDestFolder() { return $this->destFolder; } public function setFileExtension($fileExtension) { $fileExtension = strtolower($fileExtension); if (!in_array($fileExtension, ['html', 'php'], true)) { throw new \InvalidArgumentException( sprintf( 'Bad file extension "%s" passed to %s::%s', $fileExtension, static::class, __FUNCTION__ ) ); } $this->fileExtension = $fileExtension; return $this; } public function getFileExtension() { return $this->fileExtension; } public function purgeURL($url) { if (!$url) { user_error('Bad url:' . var_export($url, true), E_USER_WARNING); return; } if ($path = $this->URLtoPath($url)) { $success = $this->deleteFromPath($path . '.html') && $this->deleteFromPath($path . '.php'); return [ 'success' => $success, 'url' => $url, 'path' => $this->getDestPath() . DIRECTORY_SEPARATOR . $path, ]; } return [ 'success' => false, 'url' => $url, 'path' => false, ]; } public function purgeAll() { Filesystem::removeFolder($this->getDestPath()); return file_exists($this->getDestPath()) ? false : true; } /** * @param string $url * @param bool $forcePublish * @return array A result array */ public function publishURL($url, $forcePublish = false) { if (!$url) { user_error('Bad url:' . var_export($url, true), E_USER_WARNING); return; } $success = false; $response = $this->generatePageResponse($url); $statusCode = $response->getStatusCode(); $doPublish = ($forcePublish && $this->getFileExtension() === 'php') || $statusCode < 400; if ($statusCode >= 300 && $statusCode < 400) { // publish redirect response $success = $this->publishRedirect($response, $url); } elseif ($doPublish) { $success = $this->publishPage($response, $url); } return [ 'published' => $doPublish, 'success' => $success, 'responsecode' => $statusCode, 'url' => $url, ]; } /** * @param HTTPResponse $response * @param string $url * @return bool */ protected function publishRedirect($response, $url) { $success = true; if ($path = $this->URLtoPath($url)) { $location = $response->getHeader('Location'); if ($this->getFileExtension() === 'php') { $phpContent = $this->generatePHPCacheFile($response); $success = $this->saveToPath($phpContent, $path . '.php'); } return $this->saveToPath($this->generateHTMLCacheRedirection($location), $path . '.html') && $success; } return false; } /** * @param HTTPResponse $response * @param string $url * @return bool */ protected function publishPage($response, $url) { $success = true; if ($path = $this->URLtoPath($url)) { $body = $response->getBody(); if ($this->config()->get('lazy_form_recognition')) { $id = Config::inst()->get(SecurityToken::class, 'default_name') ?: 'SecurityID'; // little hack to make sure we do not include pages with live forms. if (stripos($body, '<input type="hidden" name="' . $id . '"') !== false) { return false; } } if ($this->getFileExtension() === 'php') { $phpContent = $this->generatePHPCacheFile($response); $success = $this->saveToPath($phpContent, $path . '.php'); } return $this->saveToPath($body, $path . '.html') && $success; } return false; } /** * returns true on success and false on failure * * @param string $content * @param string $filePath * @return bool */ protected function saveToPath($content, $filePath) { if (empty($content)) { return false; } // Write to a temporary file first $temporaryPath = tempnam(TEMP_PATH, 'filesystempublisher_'); if (file_put_contents($temporaryPath, $content) === false) { return false; } // Move the temporary file to the desired location (prevents unlocked files from being read during write) $publishPath = $this->getDestPath() . DIRECTORY_SEPARATOR . $filePath; Filesystem::makeFolder(dirname($publishPath)); return rename($temporaryPath, $publishPath); } protected function deleteFromPath($filePath) { $deletePath = $this->getDestPath() . DIRECTORY_SEPARATOR . $filePath; if (file_exists($deletePath)) { $success = unlink($deletePath); } else { $success = true; } return $success; } protected function URLtoPath($url) { return URLtoPath($url, BASE_URL, FilesystemPublisher::config()->get('domain_based_caching')); } protected function pathToURL($path) { return PathToURL($path, $this->getDestPath(), FilesystemPublisher::config()->get('domain_based_caching')); } public function getPublishedURLs($dir = null, &$result = []) { if ($dir === null) { $dir = $this->getDestPath(); } $root = scandir($dir); foreach ($root as $fileOrDir) { if (strpos($fileOrDir, '.') === 0) { continue; } $fullPath = $dir . DIRECTORY_SEPARATOR . $fileOrDir; // we know html will always be generated, this prevents double ups if (is_file($fullPath) && pathinfo($fullPath, PATHINFO_EXTENSION) === 'html') { $result[] = $this->pathToURL($fullPath); continue; } if (is_dir($fullPath)) { $this->getPublishedURLs($fullPath, $result); } } return $result; } } |