Beispiel #1
0
function ensure_cache($cacheDir, $ensureClean = true)
{
    if ($cacheDir == null or $cacheDir == '') {
        throw new Exception('Need a valid cache directory.');
    }
    if ($ensureClean and is_dir($cacheDir)) {
        PathHelper::deleteDirectoryContents($cacheDir);
    }
    PathHelper::ensureDirectory($cacheDir);
}
 public static function unzip($zipfile, $destination, $logger = null)
 {
     $destination = rtrim($destination, '/\\') . '/';
     $zip = zip_open($zipfile);
     if (!is_resource($zip)) {
         throw new PieCrustException("Error opening ZIP file: {$zipfile}");
     }
     while ($entry = zip_read($zip)) {
         zip_entry_open($zip, $entry);
         $entryName = zip_entry_name($entry);
         if ($logger) {
             $logger->debug("Extracting {$entryName}...");
         }
         $path = $destination . $entryName;
         $contents = zip_entry_read($entry, zip_entry_filesize($entry));
         PathHelper::ensureDirectory(dirname($path));
         file_put_contents($path, $contents);
         zip_entry_close($entry);
     }
     zip_close($zip);
 }
Beispiel #3
0
 public function __construct($withDefaultStructure = true, $useRealPath = false)
 {
     $this->isRootReal = (bool) $useRealPath;
     if ($useRealPath) {
         $this->root = PIECRUST_UNITTESTS_MOCK_DIR . 'root_' . rand();
         PathHelper::ensureDirectory($this->root, true);
         if ($withDefaultStructure) {
             mkdir($this->root . '/kitchen');
             mkdir($this->root . '/kitchen/_content');
             file_put_contents($this->root . '/kitchen/_content/config.yml', "site:\n  title: Mock Website");
             mkdir($this->root . '/counter');
         }
     } else {
         $this->root = 'root_' . rand();
         $structure = array();
         if ($withDefaultStructure) {
             $structure['kitchen'] = array('_content' => array('config.yml' => "site:\n  title: Mock Website"));
             $structure['counter'] = array();
         }
         vfsStream::setup($this->root, null, $structure);
     }
 }
 protected function processNode($node)
 {
     // Get the input path.
     $nodeRootDir = $this->getNodeRootDir($node);
     $path = $nodeRootDir . $node->getPath();
     // Get the output directory.
     // (all outputs of a node go to the same directory, so we
     //  can just get the directory of the first output node).
     $nodeOutputs = $node->getOutputs();
     $outputRootDir = $this->getNodeRootDir($nodeOutputs[0]);
     $outputChildDir = dirname($node->getPath());
     if ($outputChildDir == '.') {
         $outputChildDir = '';
     }
     $outputDir = $outputRootDir . $outputChildDir;
     if ($outputChildDir != '') {
         $outputDir .= '/';
     }
     $relativeOutputDir = PathHelper::getRelativePath($this->rootDir, $outputDir);
     PathHelper::ensureDirectory($outputDir, true);
     // If we need to, re-process the node!
     $didBake = false;
     try {
         $start = microtime(true);
         $processor = $node->getProcessor();
         if ($processor->process($path, $outputDir) !== false) {
             $end = microtime(true);
             $processTime = sprintf('%8.1f ms', ($end - $start) * 1000.0);
             $this->printProcessingTreeNode($node, "-> '{$relativeOutputDir}' [{$processTime}].");
             $didBake = true;
         } else {
             $this->printProcessingTreeNode($node, "-> '{$relativeOutputDir}' [clean].");
         }
     } catch (Exception $e) {
         throw new PieCrustException("Error processing '{$node->getPath()}': {$e->getMessage()}", 0, $e);
     }
     return $didBake;
 }
Beispiel #5
0
 protected function bakeSinglePage(PageRenderer $pageRenderer, array $extraData = null)
 {
     $page = $pageRenderer->getPage();
     // Set the extra template data before the page's data is computed.
     if ($extraData != null) {
         $page->setExtraPageData($extraData);
     }
     // This is usually done in the PieCrustBaker, but we'll do it here too
     // because the `PageBaker` could be used on its own.
     if ($this->parameters['copy_assets']) {
         $page->setAssetUrlBaseRemap("%site_root%%uri%");
     }
     // Figure out the output HTML path.
     $bakePath = $this->getOutputPath($page);
     $this->logger->debug("  p{$page->getPageNumber()} -> {$bakePath}");
     // Figure out if we should re-bake this page.
     $doBake = true;
     if ($this->parameters['smart']) {
         // Don't rebake if the output seems up-to-date, and
         // the page isn't known to be using posts.
         $bakePathTime = @filemtime($bakePath);
         if ($bakePathTime !== false && filemtime($page->getPath()) < $bakePathTime) {
             // TODO: rebake if the page is using pagination and pages/posts were baked this time.
             $doBake = false;
         }
     }
     if (!$doBake) {
         $this->logger->debug("Not baking '{$page->getUri()}/{$page->getPageNumber()}' because '{$bakePath}' is up-to-date.");
         return false;
     }
     // If we're using portable URLs, change the site root to a relative
     // path from the page's directory.
     $savedSiteRoot = $this->setPortableSiteRoot($page->getApp(), $bakePath);
     // Render the page.
     $bakedContents = $pageRenderer->get();
     // Get some objects we need.
     $data = $page->getPageData();
     $assetor = $data['assets'];
     $paginator = $data['pagination'];
     // Copy the page.
     PathHelper::ensureDirectory(dirname($bakePath));
     file_put_contents($bakePath, $bakedContents);
     $this->bakedFiles[] = $bakePath;
     // Copy any used assets for the first sub-page.
     if ($page->getPageNumber() == 1 and $this->parameters['copy_assets']) {
         $prettyUrls = PageHelper::getConfigValue($page, 'pretty_urls', 'site');
         if ($prettyUrls) {
             $bakeAssetDir = dirname($bakePath) . '/';
         } else {
             $bakePathInfo = pathinfo($bakePath);
             $bakeAssetDir = $bakePathInfo['dirname'] . '/' . ($page->getUri() == '' ? '' : $bakePathInfo['filename']) . '/';
         }
         $assetPaths = $assetor->getAssetPathnames();
         if ($assetPaths != null) {
             PathHelper::ensureDirectory($bakeAssetDir);
             foreach ($assetPaths as $assetPath) {
                 $destinationAssetPath = $bakeAssetDir . basename($assetPath);
                 if (@copy($assetPath, $destinationAssetPath) == false) {
                     throw new PieCrustException("Can't copy '{$assetPath}' to '{$destinationAssetPath}'.");
                 }
             }
         }
     }
     // Remember a few things.
     $this->paginationDataAccessed = ($this->paginationDataAccessed or $paginator->wasPaginationDataAccessed());
     // Cleanup.
     if ($savedSiteRoot) {
         $page->getApp()->getConfig()->setValue('site/root', $savedSiteRoot);
     }
     return true;
 }
Beispiel #6
0
 protected function createDirectory($rootDir, $dir, $makeWritable = false)
 {
     PathHelper::ensureDirectory($rootDir . $dir, $makeWritable);
 }
Beispiel #7
0
 protected function ensureLevel0Cache()
 {
     PathHelper::ensureDirectory($this->pieCrust->getCacheDir() . 'bake_t/0', true);
 }
Beispiel #8
0
 public static function serialize($obj, $filename)
 {
     PathHelper::ensureDirectory(dirname($filename), true);
     $data = self::serializeData($obj);
     file_put_contents($filename, $data);
 }
 protected function processNode($node)
 {
     // Get the input path.
     $nodeRootDir = $this->getNodeRootDir($node);
     $path = $nodeRootDir . $node->getPath();
     // If the processor for this node wants to bypass structured
     // processing altogether, run it now and exit.
     $processor = $node->getProcessor();
     if ($processor->isBypassingStructuredProcessing()) {
         try {
             $start = microtime(true);
             $processor->process($path, $this->outDir);
             $end = microtime(true);
             $processTime = sprintf('%.1f ms', ($end - $start) * 1000.0);
             $this->printProcessingTreeNode($node, " (bypassing structured processing) [{$processTime}].");
         } catch (Exception $e) {
             throw new PieCrustException("Error processing '{$node->getPath()}'.", 0, $e);
         }
         return true;
     }
     // Get the output directory.
     // (all outputs of a node go to the same directory, so we
     //  can just get the directory of the first output node).
     $nodeOutputs = $node->getOutputs();
     $outputRootDir = $this->getNodeRootDir($nodeOutputs[0]);
     $outputChildDir = dirname($node->getPath());
     if ($outputChildDir == '.') {
         $outputChildDir = '';
     }
     $outputDir = $outputRootDir . $outputChildDir;
     if ($outputChildDir != '') {
         $outputDir .= '/';
     }
     $relativeOutputDir = PathHelper::getRelativePath($this->rootDir, $outputDir);
     PathHelper::ensureDirectory($outputDir, true);
     // Now process the node!
     $didBake = false;
     try {
         $start = microtime(true);
         $processResult = $processor->process($path, $outputDir);
         $end = microtime(true);
         $processTime = sprintf('%.1f ms', ($end - $start) * 1000.0);
         if ($processResult !== false) {
             $this->printProcessingTreeNode($node, "-> '{$relativeOutputDir}' [{$processTime}].");
             $didBake = true;
         } else {
             $this->printProcessingTreeNode($node, "-> '{$relativeOutputDir}' [clean, {$processTime}].");
         }
     } catch (Exception $e) {
         throw new PieCrustException("Error processing '{$node->getPath()}'.", 0, $e);
     }
     return $didBake;
 }
 protected function ensureWebServer()
 {
     if ($this->server != null) {
         return;
     }
     PathHelper::ensureDirectory($this->bakeCacheDir);
     // Set-up the stupid web server.
     $this->server = new StupidHttp_WebServer($this->bakeCacheDir, $this->options['port'], $this->options['address']);
     if ($this->options['log_file']) {
         $this->server->setLog(StupidHttp_PearLog::fromSingleton('file', $this->options['log_file']));
     } elseif ($this->logger != null && !$this->logger instanceof \Log_null) {
         $this->server->setLog(new StupidHttp_PearLog($this->logger));
     } else {
         $this->server->setLog(new StupidHttp_ConsoleLog(StupidHttp_Log::TYPE_INFO));
     }
     foreach ($this->options['mime_types'] as $ext => $mime) {
         $this->server->setMimeType($ext, $mime);
     }
     // Mount the `_content` directory so that we can see page assets.
     $this->server->mount($this->rootDir . DIRECTORY_SEPARATOR . '_content', '_content');
     $self = $this;
     // Workaround for $this not being capturable in closures.
     $this->server->onPattern('GET', '.*')->call(function ($context) use($self) {
         $self->_runPieCrustRequest($context);
     });
     $this->server->setPreprocessor(function ($req) use($self) {
         $self->_preprocessRequest($req);
     });
 }
 protected function extractRepository($context, $destination, $userName, $repoSlug, $rev = 'default')
 {
     $app = $context->getApp();
     $log = $context->getLog();
     $cacheDir = $app->getCacheDir();
     if (!$cacheDir) {
         // If the cache doesn't exist or the application is running
         // with caching disabled, we still need to create a cache directory
         // to download the archive somewhere.
         $cacheDir = $app->getRootDir() . PieCrustDefaults::CACHE_DIR;
         PathHelper::ensureDirectory($cacheDir, true);
     }
     $url = "https://bitbucket.org/{$userName}/{$repoSlug}/get/{$rev}.zip";
     $log->info("Downloading archive...");
     $log->debug("Fetching '{$url}'...");
     $contents = file_get_contents($url);
     $tempZip = $cacheDir . $repoSlug . '.zip';
     file_put_contents($tempZip, $contents);
     $log->info("Extracting...");
     $log->debug("Unzipping into: {$cacheDir}");
     ArchiveHelper::unzip($tempZip, $cacheDir, $log);
     $globbed = glob($cacheDir . $userName . '-' . $repoSlug . '-*', GLOB_ONLYDIR | GLOB_MARK);
     if (count($globbed) != 1) {
         throw new PieCrustException("Can't find extracted directory for downloaded archive!");
     }
     $archiveDir = $globbed[0];
     if (is_dir($destination)) {
         $log->debug("Cleaning destination: {$destination}");
         PathHelper::deleteDirectoryContents($destination);
     }
     if (!is_dir(dirname($destination))) {
         mkdir(dirname($destination));
     }
     $log->debug("Moving extracted files into: {$destination}");
     rename($archiveDir, $destination);
     $log->debug("Cleaning up...");
     unlink($tempZip);
 }
Beispiel #12
0
 protected function bakeSinglePage(PageRenderer $pageRenderer, array $extraData = null)
 {
     $page = $pageRenderer->getPage();
     // Set the extra template data before the page's data is computed.
     if ($extraData != null) {
         $page->setExtraPageData($extraData);
     }
     // This is usually done in the PieCrustBaker, but we'll do it here too
     // because the `PageBaker` could be used on its own.
     if ($this->parameters['copy_assets']) {
         $page->setAssetUrlBaseRemap("%site_root%%uri%");
     }
     // Figure out the output HTML path.
     $bakePath = $this->getOutputPath($page);
     // Figure out if we should re-bake this page.
     $doBake = true;
     if (is_file($bakePath) && $this->parameters['smart']) {
         // Don't rebake if the output seems up-to-date, and
         // the page isn't known to be using posts.
         if (filemtime($page->getPath()) < filemtime($bakePath)) {
             $bakeRecord = $this->parameters['bake_record'];
             if ($bakeRecord) {
                 $relativePath = PageHelper::getRelativePath($page);
                 if (!$bakeRecord->wasAnyPostBaked() || !$bakeRecord->isPageUsingPosts($relativePath)) {
                     $doBake = false;
                 }
             }
         }
     }
     if (!$doBake) {
         $this->logger->debug("Not baking '{$page->getUri()}/{$page->getPageNumber()}' because '{$bakePath}' is up-to-date.");
         return false;
     }
     // Backward compatibility warning and file-copy.
     // [TODO] Remove in a couple of versions.
     $copyToOldPath = false;
     $contentType = $page->getConfig()->getValue('content_type');
     $nativeExtension = pathinfo($page->getPath(), PATHINFO_EXTENSION);
     if ($contentType != 'html' && $nativeExtension == 'html') {
         $copyToOldPath = $this->bakeDir . $page->getUri();
         if ($page->getPageNumber() > 1) {
             $copyToOldPath .= $page->getPageNumber() . '/';
         }
         $copyToOldPath .= '.' . $contentType;
     }
     // If we're using portable URLs, change the site root to a relative
     // path from the page's directory.
     $savedSiteRoot = $this->setPortableSiteRoot($page->getApp(), $bakePath);
     // Render the page.
     $bakedContents = $pageRenderer->get();
     // Get some objects we need.
     $data = $page->getPageData();
     $assetor = $data['asset'];
     $paginator = $data['pagination'];
     // Copy the page.
     PathHelper::ensureDirectory(dirname($bakePath));
     file_put_contents($bakePath, $bakedContents);
     $this->bakedFiles[] = $bakePath;
     // [TODO] See previous TODO.
     if ($copyToOldPath) {
         $this->logger->warning("Page '{$page->getUri()}' has 'content_type' specified but is an HTML file.");
         $this->logger->warning("Changing a baked file's extension using 'content_type' is deprecated and will be removed in a future version.");
         $this->logger->warning("For backwards compatibility, the page will also be baked to: " . substr($copyToOldPath, strlen($this->bakeDir)));
         $this->logger->warning("To fix the problem, change the source file's extension to the desired output extension.");
         $this->logger->warning("Otherwise, just ignore these messages.");
         file_put_contents($copyToOldPath, $bakedContents);
     }
     // Copy any used assets for the first sub-page.
     if ($page->getPageNumber() == 1 and $this->parameters['copy_assets']) {
         $prettyUrls = PageHelper::getConfigValue($page, 'pretty_urls', 'site');
         if ($prettyUrls) {
             $bakeAssetDir = dirname($bakePath) . '/';
         } else {
             $bakePathInfo = pathinfo($bakePath);
             $bakeAssetDir = $bakePathInfo['dirname'] . '/' . ($page->getUri() == '' ? '' : $bakePathInfo['filename']) . '/';
         }
         $assetPaths = $assetor->getAssetPathnames();
         if ($assetPaths != null) {
             PathHelper::ensureDirectory($bakeAssetDir);
             foreach ($assetPaths as $assetPath) {
                 $destinationAssetPath = $bakeAssetDir . basename($assetPath);
                 if (@copy($assetPath, $destinationAssetPath) == false) {
                     throw new PieCrustException("Can't copy '" . $assetPath . "' to '" . $destinationAssetPath . "'.");
                 }
             }
         }
     }
     // Remember a few things.
     $this->paginationDataAccessed = ($this->paginationDataAccessed or $paginator->wasPaginationDataAccessed());
     // Cleanup.
     if ($savedSiteRoot) {
         $page->getApp()->getConfig()->setValue('site/root', $savedSiteRoot);
     }
     return true;
 }