silverstripe-frameworktest/code/tasks/FTPageMakerTask.php

218 lines
7.2 KiB
PHP
Raw Permalink Normal View History

2012-02-29 15:49:37 +01:00
<?php
2020-11-03 05:48:30 +01:00
use DNADesign\Elemental\Models\ElementContent;
use SilverStripe\Assets\File;
use SilverStripe\Dev\BuildTask;
use SilverStripe\Core\ClassInfo;
2020-11-03 05:48:30 +01:00
use SilverStripe\ElementalBannerBlock\Block\BannerBlock;
use SilverStripe\ElementalFileBlock\Block\FileBlock;
use SilverStripe\CMS\Model\SiteTree;
use DNADesign\Elemental\Extensions\ElementalPageExtension;
use SilverStripe\PolyExecution\PolyOutput;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
2012-02-29 15:49:37 +01:00
/**
* Creates sample page structure, useful to test tree performance,
* UI behaviour on deeply nested pages etc.
2020-11-03 05:48:30 +01:00
*
2012-02-29 15:49:37 +01:00
* @todo Allow passing in counts
*/
2015-12-17 21:20:49 +01:00
class FTPageMakerTask extends BuildTask
{
2020-11-03 05:48:30 +01:00
/**
* Defaults create 2,000 pages
*/
protected $pageCountByDepth = [
5,
100,
1,
1,
2020-11-03 05:48:30 +01:00
];
/**
* @var array Range of blocks to add (in case elemental is installed).
* Will create between X and Y blocks randomly.
*/
protected $blockCountRange = [
1,
10
];
/**
* @var array
* @config
*/
private static $block_generators = [
2024-06-05 06:30:08 +02:00
'DNADesign\Elemental\Models\ElementContent' => [FTPageMakerTask::class, 'generateContentBlock'],
'SilverStripe\ElementalBannerBlock\Block\BannerBlock' => [FTPageMakerTask::class, 'generateBannerBlock'],
'SilverStripe\ElementalFileBlock\Block\FileBlock' => [FTPageMakerTask::class, 'generateFileBlock'],
];
2012-02-29 15:49:37 +01:00
protected function execute(InputInterface $input, PolyOutput $output): int
2015-12-17 21:20:49 +01:00
{
2020-11-03 05:48:30 +01:00
// Optionally add blocks
$withBlocks = (bool)$input->getOption('withBlocks');
2020-11-03 05:48:30 +01:00
if ($withBlocks && !class_exists('DNADesign\Elemental\Models\BaseElement')) {
throw new \LogicException('withBlocks requested, but BaseElement class not found');
}
// Allow pageCountByDepth to be passed as comma-separated value, e.g. pageCounts=5,100,1,1
$pageCounts = $input->getOption('pageCounts');
if ($pageCounts) {
2022-04-13 00:31:07 +02:00
$counts = explode(',', $pageCounts ?? '');
$this->pageCountByDepth = array_map(function ($int) {
2022-04-13 00:31:07 +02:00
return (int) trim($int ?? '');
}, $counts ?? []);
}
$this->generatePages($output, 0, "", 0, $withBlocks);
return Command::SUCCESS;
2015-12-17 21:20:49 +01:00
}
protected function generatePages(PolyOutput $output, $depth = 0, $prefix = "", $parentID = 0, $withBlocks = false)
2015-12-17 21:20:49 +01:00
{
2022-04-13 00:31:07 +02:00
$maxDepth = count($this->pageCountByDepth ?? []);
$pageCount = $this->pageCountByDepth[$depth];
$testPageClasses = ClassInfo::implementorsOf('TestPageInterface');
for ($i=1; $i<=$pageCount; $i++) {
$fullPrefix = $prefix ? "{$prefix}-{$i}" : $i;
2022-04-13 00:31:07 +02:00
$randomIndex = array_rand($testPageClasses ?? []);
$pageClass = $testPageClasses[$randomIndex];
$page = new $pageClass();
2015-12-17 21:20:49 +01:00
$page->ParentID = $parentID;
$page->Title = "Test page {$fullPrefix}";
2015-12-17 21:20:49 +01:00
$page->write();
$page->copyVersionToStage('Stage', 'Live');
2012-02-29 15:49:37 +01:00
$output->writeln("Created '$page->Title' ($page->ClassName)");
2020-11-03 05:48:30 +01:00
if ($withBlocks) {
$this->generateBlocksForPage($output, $page);
2020-11-03 05:48:30 +01:00
}
$pageID = $page->ID;
2020-11-03 05:48:30 +01:00
unset($page);
if ($depth < $maxDepth-1) {
$this->generatePages($output, $depth+1, $fullPrefix, $pageID, $withBlocks);
2015-12-17 21:20:49 +01:00
}
}
}
2020-11-03 05:48:30 +01:00
protected function generateBlocksForPage(PolyOutput $output, Page $page)
2020-11-03 05:48:30 +01:00
{
2022-04-13 00:31:07 +02:00
$classes = array_filter($this->config()->get('block_generators') ?? [], function ($callable, $class) {
return class_exists($class ?? '');
2020-11-03 05:48:30 +01:00
}, ARRAY_FILTER_USE_BOTH);
// Generate a random amount of blocks in the preferred range
$range = $this->blockCountRange;
foreach(range($range[0], array_rand(range($range[0], $range[1]))) as $i) {
2022-04-13 00:31:07 +02:00
$class = array_rand($classes ?? []);
2020-11-03 05:48:30 +01:00
$callable = $classes[$class];
$block = call_user_func($callable, $page);
2020-11-03 05:48:30 +01:00
// Add block to page
$page->ElementalArea()->Elements()->add($block);
// 50% chance of block being published
if (rand(0,1) === 0) {
$block->publishRecursive();
}
$output->writeln(sprintf(" Added '%s' block #%d to page #%d", $class, $block->ID, $page->ID));
2020-11-03 05:48:30 +01:00
}
}
/**
* @param SiteTree&ElementalPageExtension|null $page
* @return ElementContent
* @throws \SilverStripe\Core\Validation\ValidationException
*/
public static function generateContentBlock(?SiteTree $page = null)
2020-11-03 05:48:30 +01:00
{
$count = $page ? $page->ElementalArea()->Elements()->count() : '';
$content = $page ? "Page {$page->Title}" : "Page";
2020-11-03 05:48:30 +01:00
$block = new ElementContent([
'Title' => sprintf('Block #%s (Content Block)', $count),
'ShowTitle' => rand(0,1) === 1,
'HTML' => sprintf('Content block for <bold>%s</bold>', $content),
2020-11-03 05:48:30 +01:00
]);
$block->write();
return $block;
}
/**
* @param SiteTree&ElementalPageExtension|null $page
* @return FileBlock
* @throws \SilverStripe\Core\Validation\ValidationException
*/
public static function generateFileBlock(?SiteTree $page = null): FileBlock
2020-11-03 05:48:30 +01:00
{
$count = $page ? $page->ElementalArea()->Elements()->count() : '';
2020-11-03 05:48:30 +01:00
// Supports both images and files
$file = File::get()->shuffle()->First();
if (!$file) {
throw new \LogicException('No files found to associate with FileBlock');
}
$block = new FileBlock([
'Title' => sprintf('Block #%s (File Block)', $count),
'ShowTitle' => rand(0,1) === 1,
]);
2020-11-03 05:48:30 +01:00
$block->FileID = $file->ID;
$block->write();
return $block;
}
/**
* @param SiteTree&ElementalPageExtension|null $page
* @return BannerBlock
* @throws \SilverStripe\Core\Validation\ValidationException
*/
public static function generateBannerBlock(?SiteTree $page = null): BannerBlock
2020-11-03 05:48:30 +01:00
{
$count = $page ? $page->ElementalArea()->Elements()->count() : '';
$content = $page ? "Page {$page->Title}" : "Page";
2020-11-03 05:48:30 +01:00
$block = new BannerBlock([
'Title' => sprintf('Block #%s (Banner Block)', $count),
'ShowTitle' => rand(0,1) === 1,
'Content' => sprintf('Banner block for <bold>%s</bold>', $content),
'CallToActionLink' => json_encode([
'PageID' => SiteTree::get()->shuffle()->first()->ID,
'Text' => sprintf('Link for page %s', $page->Title),
]),
2020-11-03 05:48:30 +01:00
]);
$block->write();
return $block;
}
public function getOptions(): array
{
return [
new InputOption(
'withBlocks',
null,
InputOption::VALUE_NONE,
'Include elemental blocks on the page',
),
new InputOption(
'pageCounts',
null,
InputOption::VALUE_REQUIRED,
'Comma separated string'
),
];
}
2015-12-17 21:20:49 +01:00
}