public function renderFile($templateName, $data) { $this->ensureLoaded(); $templatePath = PathHelper::getTemplatePath($this->pieCrust, $templateName); $content = file_get_contents($templatePath); $this->renderString($content, $data); }
public function testCreateDefaultCategoryPage() { $app = MockFileSystem::create()->withConfig(array('site' => array('category_url' => 'cat/%category%')))->getApp(); $page = Page::createFromUri($app, '/cat/foo'); $expected = PathHelper::getUserOrThemePath($app, '_category.html'); $this->assertEquals($expected, $page->getPath()); }
/** * Gets the validity information for the cache. * * If $cleanCache is true and the cache is not valid, it will be wiped. */ public function getValidity($cleanCache) { // Things that could make the cache invalid: // - changing the version of PieCrust // - changing the configuration $hashArray = $this->pieCrust->getConfig()->get(); $hashArray['_version'] = PieCrustDefaults::VERSION; $hashString = json_encode($hashArray); $hash = hash('sha1', $hashString); $isCacheValid = false; $cacheInfoFileName = $this->pieCrust->getCacheDir() . PieCrustDefaults::CACHE_INFO_FILENAME; if (file_exists($cacheInfoFileName)) { $previousHash = file_get_contents($cacheInfoFileName); $isCacheValid = $previousHash == $hash; } $cacheValidity = array('is_valid' => $isCacheValid, 'path' => $cacheInfoFileName, 'hash' => $hash, 'was_cleaned' => false); if ($cleanCache && !$isCacheValid) { // Clean the cache! PathHelper::deleteDirectoryContents($this->pieCrust->getCacheDir(), $this->cacheCleaningSkipPatterns); file_put_contents($cacheInfoFileName, $hash); $cacheValidity['is_valid'] = true; $cacheValidity['was_cleaned'] = true; } return $cacheValidity; }
public function getTextFrom($path) { $path = PathHelper::getAbsolutePath($path, $this->pieCrust->getRootDir()); if (!is_file($path)) { throw new PieCrustException("Invalid path for 'text_from': {$path}"); } return file_get_contents($path); }
/** * Returns a path relative to a site's root directory. */ public static function getRelativePath(IPieCrust $pieCrust, $path, $stripExtension = false) { $relativePath = PathHelper::getRelativePath($pieCrust->getRootDir(), $path); if ($stripExtension) { $relativePath = preg_replace('/\\.[a-zA-Z0-9]+$/', '', $relativePath); } return $relativePath; }
public function run(ChefContext $context) { $logger = $context->getLog(); $pieCrust = $context->getApp(); $result = $context->getResult(); // Get some options. $exact = $result->command->options['exact']; $fullPath = $result->command->options['full_path']; // If no type filters are given, return all types. $returnAllTypes = ($result->command->options['pages'] == false and $result->command->options['posts'] == false and $result->command->options['templates'] == false); // Validate the argument. $pattern = $result->command->args['pattern']; if ($exact) { // Check we have a path to match, and get its absolute value. if (!$pattern) { throw new PieCrustException("You need to specify a path when using the `--exact` option."); } $pattern = PathHelper::getAbsolutePath($pattern); } else { // If a pattern was given, get the Regex'd version. if ($pattern) { $pattern = PathHelper::globToRegex($pattern); } } $result->command->args['pattern'] = $pattern; $foundAny = false; // Find pages. if ($returnAllTypes or $result->command->options['pages']) { $pages = PageHelper::getPages($pieCrust); $foundAny |= $this->findPages($context, $pages); } // Find posts. if ($returnAllTypes or $result->command->options['posts']) { $blogKeys = $pieCrust->getConfig()->getValue('site/blogs'); if ($result->command->options['blog']) { $blogKeys = array($result->command->options['blog']); } foreach ($blogKeys as $blogKey) { $pages = PageHelper::getPosts($pieCrust, $blogKey); $pagesIterator = new \ArrayIterator($pages); $sorter = new DateSortIterator($pagesIterator); $pages = iterator_to_array($sorter); $foundAny |= $this->findPages($context, $pages, $blogKey); } } // Find templates. if ($returnAllTypes or $result->command->options['templates']) { $templatesDirs = $pieCrust->getTemplatesDirs(); foreach ($templatesDirs as $dir) { $foundAny |= $this->findTemplates($context, $dir); } } if (!$foundAny) { $pattern = $result->command->args['pattern']; $logger->info("No match found for '{$pattern}'."); } return 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 function run(ChefContext $context) { $cacheDir = $context->getApp()->getCacheDir(); if (!$cacheDir) { throw new PieCrustException("The website seems to have caching disabled."); } if (!is_dir($cacheDir)) { throw new PieCrustException("The cache directory doesn't exist: {$cacheDir}"); } $context->getLog()->info("Purging cache: {$cacheDir}"); PathHelper::deleteDirectoryContents($cacheDir); }
protected function copySubDirectory($context, $destination, $subDir, $cleanFirst = false) { $log = $context->getLog(); if ($cleanFirst) { if (is_dir($destination)) { $log->info("Deleting existing files..."); PathHelper::deleteDirectoryContents($destination); } } $log->info("Copying files..."); $log->debug("{$subDir} -> {$destination}"); PathHelper::copyDirectory($subDir, $destination, ",\\.hg|\\.git|\\.svn,"); }
public function renderFile($templateNames, $data) { $templatePath = null; foreach ($templateNames as $templateName) { $templatePath = PathHelper::getTemplatePath($this->pieCrust, $templateName); if ($templatePath) { break; } } if (!$templatePath) { throw new PieCrustException(sprintf("Couldn't find template(s) '%s' in: %s", implode(', ', $templateNames), implode(', ', $this->pieCrust->getTemplatesDirs()))); } $content = file_get_contents($templatePath); echo $content; }
public function testGlobToRegexExample() { $pattern = PathHelper::globToRegex('blah*.css'); $this->assertTrue(preg_match($pattern, 'dir/blah.css') == 1); $this->assertTrue(preg_match($pattern, 'dir/blah2.css') == 1); $this->assertTrue(preg_match($pattern, 'dir/blahblah.css') == 1); $this->assertTrue(preg_match($pattern, 'dir/blah.blah.css') == 1); $this->assertTrue(preg_match($pattern, 'dir/blah.blah.css/something') == 1); $this->assertFalse(preg_match($pattern, 'blah/something.css') == 1); $pattern = PathHelper::globToRegex('blah?.css'); $this->assertFalse(preg_match($pattern, 'dir/blah.css') == 1); $this->assertTrue(preg_match($pattern, 'dir/blah1.css') == 1); $this->assertTrue(preg_match($pattern, 'dir/blahh.css') == 1); $this->assertFalse(preg_match($pattern, 'dir/blah/yo.css') == 1); }
public static function tearDownAfterClass() { $mockDir = PIECRUST_UNITTESTS_MOCK_DIR; if (is_dir($mockDir)) { // On Windows, it looks like the file-system is a bit "slow". // And by "slow", I mean "retarded". $tries = 3; while ($tries > 0) { try { PathHelper::deleteDirectoryContents($mockDir); rmdir($mockDir); $tries = 0; } catch (\Exception $e) { $tries--; } } } }
/** * Gets the info about all the page files in the website. */ public function getPageFiles() { if (!$this->pagesDir) { return array(); } $pages = array(); $iterator = new \RecursiveIteratorIterator(new PagesRecursiveFilterIterator(new \RecursiveDirectoryIterator($this->pagesDir))); foreach ($iterator as $path) { $pagePath = $path->getPathname(); // Skip files in page asset folders. if (preg_match('#\\-assets[/\\\\]#', $pagePath)) { continue; } $relativePath = PathHelper::getRelativePath($this->pagesDir, $pagePath); $pages[] = array('path' => $pagePath, 'relative_path' => $relativePath); } return $pages; }
/** * Returns a path relative to a site's root directory. */ public static function getRelativePath(IPieCrust $pieCrust, $path, $stripExtension = false) { $basePath = null; $themeDir = $pieCrust->getThemeDir(); if ($themeDir and strncmp($path, $themeDir, strlen($themeDir)) == 0) { // Theme path. $basePath = $themeDir; } else { // Normal website path. $basePath = $pieCrust->getRootDir(); } if (!$basePath) { throw new PieCrustException("Can't get a relative path for '{$path}': it doesn't seem to be either a website, theme or resource path."); } $relativePath = PathHelper::getRelativePath($basePath, $path); if ($stripExtension) { $relativePath = preg_replace('/\\.[a-zA-Z0-9]+$/', '', $relativePath); } return $relativePath; }
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); }
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 bakeCategories() { if ($this->bakeRecord == null) { throw new PieCrustException("Can't bake categories without a bake-record active."); } $blogKeys = $this->pieCrust->getConfig()->getValueUnchecked('site/blogs'); foreach ($blogKeys as $blogKey) { // Check that there is a category listing page to bake. $prefix = ''; if ($blogKey != PieCrustDefaults::DEFAULT_BLOG_KEY) { $prefix = $blogKey . DIRECTORY_SEPARATOR; } $categoryPageName = $prefix . PieCrustDefaults::CATEGORY_PAGE_NAME . '.html'; $categoryPagePath = PathHelper::getUserOrThemeOrResPath($this->pieCrust, $categoryPageName); if ($categoryPagePath === false) { continue; } // Order categories so it looks nicer when we bake. $categoriesToBake = $this->bakeRecord->getCategoriesToBake($blogKey); sort($categoriesToBake); // Bake! $pageRepository = $this->pieCrust->getEnvironment()->getPageRepository(); foreach ($categoriesToBake as $category) { $start = microtime(true); $postInfos = $this->bakeRecord->getPostsInCategory($blogKey, $category); if (count($postInfos) > 0) { $uri = UriBuilder::buildCategoryUri($this->pieCrust->getConfig()->getValue($blogKey . '/category_url'), $category); $page = $pageRepository->getOrCreatePage($uri, $categoryPagePath, IPage::TYPE_CATEGORY, $blogKey, $category); $baker = new PageBaker($this->getBakeDir(), $this->getPageBakerParameters()); $baker->bake($page); $pageCount = $baker->getPageCount(); $this->logger->info(self::formatTimed($start, 'category:' . $category . ($pageCount > 1 ? " [{$pageCount}]" : ""))); } } } }
protected function printProcessingTreeNode($node, $message = null, $recursive = false) { $indent = str_repeat(' ', $node->getLevel() + 1); $processor = $node->getProcessor() ? $node->getProcessor()->getName() : 'n/a'; $path = PathHelper::getRelativePath($this->rootDir, $this->getNodeRootDir($node) . $node->getPath()); if (!$message) { $message = ''; } $this->logger->debug("{$indent}{$path} [{$processor}] {$message}"); if ($recursive) { foreach ($node->getOutputs() as $out) { $this->printProcessingTreeNode($out, true); } } }
public function renderFile($templateName, $data) { $templatePath = PathHelper::getTemplatePath($this->pieCrust, $templateName); $content = file_get_contents($templatePath); echo $content; }
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; }
private static function tryParseCategoryUri(IPieCrust $pieCrust, $blogKey, $uri, array &$pageInfo) { $blogKeyDir = ''; if ($blogKey != PieCrustDefaults::DEFAULT_BLOG_KEY) { $blogKeyDir = $blogKey . '/'; } $categoryPageName = array(); $themeCategoryPageName = array(); $autoFormats = $pieCrust->getConfig()->getValueUnchecked('site/auto_formats'); foreach ($autoFormats as $ext => $format) { $categoryPageName[] = $blogKeyDir . PieCrustDefaults::CATEGORY_PAGE_NAME . '.' . $ext; $themeCategoryPageName[] = PieCrustDefaults::CATEGORY_PAGE_NAME . '.' . $ext; } $path = PathHelper::getUserOrThemePath($pieCrust, $categoryPageName, $themeCategoryPageName); if ($path === false) { return false; } $flags = $pieCrust->getConfig()->getValueUnchecked('site/slugify_flags'); $categoryPattern = UriBuilder::buildCategoryUriPattern($pieCrust->getConfig()->getValueUnchecked($blogKey . '/category_url')); if (preg_match($categoryPattern, $uri, $matches)) { $cat = rawurldecode($matches['cat']); $cat = UriBuilder::slugify($cat, $flags); $pageInfo['type'] = IPage::TYPE_CATEGORY; $pageInfo['blogKey'] = $blogKey; $pageInfo['key'] = $cat; $pageInfo['path'] = $path; $pageInfo['was_path_checked'] = true; return true; } return false; }
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 bakeTaxonomies() { // Get some global stuff we'll need. $slugifyFlags = $this->pieCrust->getConfig()->getValue('site/slugify_flags'); $pageRepository = $this->pieCrust->getEnvironment()->getPageRepository(); // Get the taxonomies. $taxonomies = array('tags' => array('multiple' => true, 'singular' => 'tag', 'page' => PieCrustDefaults::TAG_PAGE_NAME . '.html'), 'category' => array('multiple' => false, 'page' => PieCrustDefaults::CATEGORY_PAGE_NAME . '.html')); // Get which terms we need to bake. $allDirtyTaxonomies = $this->bakeRecord->getDirtyTaxonomies($taxonomies); $allUsedCombinations = $this->bakeRecord->getUsedTaxonomyCombinations($taxonomies); // Get the taxonomy listing pages, if they exist. $taxonomyPages = array(); $blogKeys = $this->pieCrust->getConfig()->getValue('site/blogs'); foreach ($taxonomies as $name => $taxonomyMetadata) { $taxonomyPages[$name] = array(); foreach ($blogKeys as $blogKey) { $prefix = ''; if ($blogKey != PieCrustDefaults::DEFAULT_BLOG_KEY) { $prefix = $blogKey . DIRECTORY_SEPARATOR; } $termPageName = $prefix . $taxonomyMetadata['page']; $themeTermPageName = $taxonomyMetadata['page']; $termPagePath = PathHelper::getUserOrThemePath($this->pieCrust, $termPageName, $themeTermPageName); $taxonomyPages[$name][$blogKey] = $termPagePath; } } foreach ($allDirtyTaxonomies as $name => $dirtyTerms) { $taxonomyMetadata = $taxonomies[$name]; foreach ($dirtyTerms as $blogKey => $dirtyTermsForBlog) { // Check that we have a term listing page to bake. $termPagePath = $taxonomyPages[$name][$blogKey]; if (!$termPagePath) { continue; } // We have the terms that need to be rebaked. $termsToBake = $dirtyTermsForBlog; // Look at the combinations of terms we need to consider. if ($taxonomyMetadata['multiple']) { // User-specified combinations. $forcedCombinations = array(); $forcedCombinationParameters = array($name . '_combinations'); if (isset($taxonomyMetadata['singular'])) { $forcedCombinationParameters[] = $taxonomyMetadata['singular'] . '_combinations'; } foreach ($forcedCombinationParameters as $param) { if (isset($this->parameters[$param])) { $forcedCombinations = $this->parameters[$param]; if (array_key_exists($blogKey, $forcedCombinations)) { $forcedCombinations = $forcedCombinations[$blogKey]; } elseif (count($blogKeys > 1)) { $forcedCombinations = array(); } break; } } // Collected combinations in use. $usedCombinations = array(); if (isset($allUsedCombinations[$name]) && isset($allUsedCombinations[$name][$blogKey])) { $usedCombinations = $allUsedCombinations[$name][$blogKey]; } // Get all the combinations together (forced and used) and keep // those that include a term that we have to rebake. $combinations = array_merge($forcedCombinations, $usedCombinations); if ($combinations) { $combinationsToBake = array(); foreach ($combinations as $comb) { if (count(array_intersect($comb, $termsToBake)) > 0) { $combinationsToBake[] = $comb; } } $termsToBake = array_merge($termsToBake, $combinationsToBake); } } // Order terms so it looks nice when we bake. usort($termsToBake, function ($t1, $t2) { if (is_array($t1)) { $t1 = implode('+', $t1); } if (is_array($t2)) { $t2 = implode('+', $t2); } return strcmp($t1, $t2); }); // Bake! foreach ($termsToBake as $term) { $start = microtime(true); if ($taxonomyMetadata['multiple'] && is_array($term)) { $slugifiedTerm = array_map(function ($t) use($slugifyFlags) { return UriBuilder::slugify($t, $slugifyFlags); }, $term); $formattedTerm = implode('+', array_map('rawurldecode', $term)); } else { $slugifiedTerm = UriBuilder::slugify($term, $slugifyFlags); $formattedTerm = rawurldecode($term); } if ($name == 'tags') { $uri = UriBuilder::buildTagUri($this->pieCrust, $blogKey, $slugifiedTerm, false); $pageType = IPage::TYPE_TAG; } else { if ($name == 'category') { $uri = UriBuilder::buildCategoryUri($this->pieCrust, $blogKey, $slugifiedTerm, false); $pageType = IPage::TYPE_CATEGORY; } } $page = $pageRepository->getOrCreatePage($uri, $termPagePath, $pageType, $blogKey); $page->setPageKey($slugifiedTerm); $this->callAssistants('onPageBakeStart', array($page)); $baker = $this->getPageBaker(); $baker->bake($page); $this->callAssistants('onPageBakeEnd', array($page, new BakeResult(true))); $pageCount = $baker->getPageCount(); $this->logger->info(self::formatTimed($start, "{$name}:{$formattedTerm}" . ($pageCount > 1 ? " [{$pageCount}]" : ""))); } } } }
private static function tryParseCategoryUri(IPieCrust $pieCrust, $blogKey, $uri, array &$pageInfo) { $blogKeyDir = ''; if ($blogKey != PieCrustDefaults::DEFAULT_BLOG_KEY) { $blogKeyDir = $blogKey . '/'; } $relativeTagPage = $blogKeyDir . PieCrustDefaults::CATEGORY_PAGE_NAME . '.html'; $path = PathHelper::getUserOrThemeOrResPath($pieCrust, $relativeTagPage); if ($path === false) { return false; } $categoryPattern = UriBuilder::buildCategoryUriPattern($pieCrust->getConfig()->getValueUnchecked($blogKey . '/category_url')); if (preg_match($categoryPattern, $uri, $matches)) { $pageInfo['type'] = IPage::TYPE_CATEGORY; $pageInfo['blogKey'] = $blogKey; $pageInfo['key'] = $matches['cat']; $pageInfo['path'] = $path; $pageInfo['was_path_checked'] = true; return true; } return false; }
protected function updatePlugins(ChefContext $context) { $app = $context->getApp(); $log = $context->getLog(); $result = $context->getResult(); $pluginName = $result->command->command->args['name']; // Right now we do it the brute force way: update everything. // TODO: keep some metadata on the installed version so we don't overwrite with the exact same. $pluginLoader = $app->getPluginLoader(); foreach ($pluginLoader->getPlugins() as $plugin) { $curName = $plugin->getName(); if ($curName != '__builtin__' && ($curName == $pluginName || !$pluginName)) { $log->info("Updating {$curName}..."); // First, rename the existing directory. $pluginMeta = $pluginLoader->getPluginMeta($curName); $pluginDir = $pluginMeta->directory; $pluginDirBackup = $pluginDir . '__backup'; if (!rename($pluginDir, $pluginDirBackup)) { throw new PieCrustException("Can't rename plugin directory: {$pluginDir}"); } // Then, update. try { $plugin = $this->installPlugin($curName, $context); } catch (\Exception $e) { $log->debug("Error encountered, restoring backup directory."); rename($pluginDirBackup, $pluginDir); throw new PieCrustException("Error updating plugin '{$curName}'.", 0, $e); } // Last, cleanup backup directory. $log->debug("Cleaning up backup directory: {$pluginDirBackup}"); PathHelper::deleteDirectoryContents($pluginDirBackup); rmdir($pluginDirBackup); } } }
public function run(ChefContext $context) { $logger = $context->getLog(); $pieCrust = $context->getApp(); $result = $context->getResult(); // Get some options. $exact = $result->command->options['exact']; $fullPath = $result->command->options['full_path']; // If no type filters are given, return all types. $returnAllTypes = ($result->command->options['pages'] == false and $result->command->options['posts'] == false and $result->command->options['templates'] == false); // Validate the argument. $pattern = $result->command->args['pattern']; if ($exact) { // Check we have a path to match, and get its absolute value. if (!$pattern) { throw new PieCrustException("You need to specify a path when using the `--exact` option."); } $pattern = PathHelper::getAbsolutePath($pattern); } else { // If a pattern was given, get the Regex'd version. if ($pattern) { $pattern = PathHelper::globToRegex($pattern); } } // Get the pages and posts. $pages = array(); if ($returnAllTypes or $result->command->options['pages']) { $pages = PageHelper::getPages($pieCrust); } if ($returnAllTypes or $result->command->options['posts']) { $blogKeys = $pieCrust->getConfig()->getValue('site/blogs'); if ($result->command->options['blog']) { $blogKeys = array($result->command->options['blog']); } foreach ($blogKeys as $blogKey) { $pages = array_merge($pages, PageHelper::getPosts($pieCrust, $blogKey)); } } // Get some other stuff. $returnComponents = $result->command->options['page_components']; // Get a regex for the posts file-naming convention. $fs = FileSystem::create($pieCrust); $pathComponentsRegex = preg_quote($fs->getPostPathFormat(), '/'); $pathComponentsRegex = str_replace(array('%year%', '%month%', '%day%', '%slug%'), array('(\\d{4})', '(\\d{2})', '(\\d{2})', '(.+)'), $pathComponentsRegex); $pathComponentsRegex = '/' . $pathComponentsRegex . '/'; // Print the matching pages. foreach ($pages as $page) { if ($result->command->options['no_special']) { // Skip special pages. if ($page->getUri() == PieCrustDefaults::CATEGORY_PAGE_NAME or $page->getUri() == PieCrustDefaults::TAG_PAGE_NAME) { continue; } } if ($exact) { // Match the path exactly, or pass. if (str_replace('\\', '/', $pattern) != str_replace('\\', '/', $page->getPath())) { continue; } } else { if ($pattern) { // Match the regex, or pass. if (!preg_match($pattern, $page->getUri())) { continue; } } } $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $page->getPath()); if (!$fullPath) { $path = PieCrustHelper::getRelativePath($pieCrust, $path); } if ($returnComponents) { $components = array('path' => $path, 'type' => 'page', 'uri' => $page->getUri(), 'slug' => $page->getUri()); if (PageHelper::isPost($page)) { $matches = array(); if (preg_match($pathComponentsRegex, str_replace('\\', '/', $path), $matches) !== 1) { throw new PieCrustException("Can't extract path components from path: {$path}"); } $components['type'] = 'post'; $components['year'] = $matches[1]; $components['month'] = $matches[2]; $components['day'] = $matches[3]; $components['slug'] = $matches[4]; } $str = ''; foreach ($components as $k => $v) { $str .= $k . ': ' . $v . PHP_EOL; } $logger->info($str); } else { $logger->info($path); } } // Get the template files and print them. if ($returnAllTypes or $result->command->options['templates']) { $templatesDirs = $pieCrust->getTemplatesDirs(); foreach ($templatesDirs as $dir) { $dirIt = new \RecursiveDirectoryIterator($dir); $it = new \RecursiveIteratorIterator($dirIt); foreach ($it as $path) { if ($it->isDot()) { continue; } $relativePath = PieCrustHelper::getRelativePath($pieCrust, $path->getPathname()); if ($exact) { // Match the path exactly, or pass. if (str_replace('\\', '/', $pattern) != str_replace('\\', '/', $path->getPathname())) { continue; } } else { if ($pattern) { // Match the regex, or pass. if (!preg_match($pattern, $relativePath)) { continue; } } } // Get the path to print. $finalPath = $relativePath; if ($fullPath) { $finalPath = $path->getPathname(); } $finalPath = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $finalPath); // Print the information! if ($returnComponents) { $logger->info("path: {$finalPath}"); $logger->info("type: template"); } else { $logger->info($finalPath); } } } } return 0; }
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); }
protected function load() { try { $pieCrust = $this->page->getApp(); $pageRepository = $pieCrust->getEnvironment()->getPageRepository(); $items = array(); $skipNames = array('Thumbs.db'); $it = new FilesystemIterator($this->baseDir); foreach ($it as $item) { $filename = $item->getFilename(); // Skip dot files, Thumbs.db, etc. if (!$filename or $filename[0] == '.') { continue; } if (in_array($filename, $skipNames)) { continue; } if ($item->isDir()) { // Skip "asset" directories. if (preg_match('/\\-assets$/', $filename)) { continue; } $linker = new Linker($this->page, $item->getPathname()); $items[$filename . '_'] = $linker; // We add '_' at the end of the directory name to avoid // collisions with a possibly existing page with the same // name (since we strip out the file extension). // This means the user must access directories with // 'link.dirname_' instead of 'link.dirname' but hey, if // you have a better idea, send me an email! } else { $path = $item->getPathname(); try { // To get the link's page, we need to be careful with the case // where that page is the currently rendering one. This is // because it could be rendering a sub-page -- but we would be // requesting the default first page, which would effectively // change the page number *while* we're rendering, which leads // to all kinds of bad things! // TODO: obviously, there needs to be some design changes to // prevent this kind of chaotic behaviour. if (str_replace('\\', '/', $path) == str_replace('\\', '/', $this->page->getPath())) { $page = $this->page; } else { $relativePath = PathHelper::getRelativePath($pieCrust->getPagesDir(), $path); $uri = UriBuilder::buildUri($pieCrust, $relativePath); $page = $pageRepository->getOrCreatePage($uri, $path); } $key = preg_replace('/\\.[a-zA-Z0-9]+$/', '', $filename); $key = str_replace('.', '_', $key); $items[$key] = new LinkData($page, array('name' => $key, 'is_dir' => false, 'is_self' => $page == $this->page)); } catch (Exception $e) { throw new PieCrustException("Error while loading page '{$path}' for linking from '{$this->page->getUri()}': " . $e->getMessage(), 0, $e); } } } if ($this->sortByName) { if (false === usort($items, array($this, 'sortByCustom'))) { throw new PieCrustException("Error while sorting pages with the specified setting: {$this->sortByName}"); } } return $items; } catch (Exception $e) { throw new PieCrustException("Error while building the links from page '{$this->page->getUri()}': " . $e->getMessage(), 0, $e); } }
protected function createDirectory($rootDir, $dir, $makeWritable = false) { PathHelper::ensureDirectory($rootDir . $dir, $makeWritable); }
public static function serialize($obj, $filename) { PathHelper::ensureDirectory(dirname($filename), true); $data = self::serializeData($obj); file_put_contents($filename, $data); }