Skip to content

Commit

Permalink
[!!!][FEATURE] Require eliashaeussler/cache-warmup ^4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
eliashaeussler committed Dec 27, 2024
1 parent 38541d6 commit 7332621
Show file tree
Hide file tree
Showing 34 changed files with 367 additions and 728 deletions.
40 changes: 23 additions & 17 deletions Classes/Command/WarmupCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@
use EliasHaeussler\CacheWarmup;
use EliasHaeussler\Typo3SitemapLocator;
use EliasHaeussler\Typo3Warming\Configuration;
use EliasHaeussler\Typo3Warming\Crawler;
use EliasHaeussler\Typo3Warming\Domain;
use EliasHaeussler\Typo3Warming\Http;
use EliasHaeussler\Typo3Warming\Utility;
use Psr\EventDispatcher;
use Symfony\Component\Console;
Expand All @@ -50,9 +48,8 @@ final class WarmupCommand extends Console\Command\Command
private const ALL_SITES = 'all';

public function __construct(
private readonly Http\Client\ClientFactory $clientFactory,
private readonly Configuration\Configuration $configuration,
private readonly Crawler\Strategy\CrawlingStrategyFactory $crawlingStrategyFactory,
private readonly CacheWarmup\Crawler\Strategy\CrawlingStrategyFactory $crawlingStrategyFactory,
private readonly Typo3SitemapLocator\Sitemap\SitemapLocator $sitemapLocator,
private readonly Core\Site\SiteFinder $siteFinder,
private readonly EventDispatcher\EventDispatcherInterface $eventDispatcher,
Expand All @@ -66,9 +63,14 @@ protected function configure(): void
$v = fn(mixed $value) => $value;
$decoratedCrawlingStrategies = \implode(PHP_EOL, array_map(
static fn(string $strategy) => ' │ * <info>' . $strategy . '</info>',
array_keys($this->crawlingStrategyFactory->getAll()),
$this->crawlingStrategyFactory->getAll(),
));

$crawlingStrategy = $this->configuration->getStrategy();
if ($crawlingStrategy !== null) {
$crawlingStrategy = $crawlingStrategy::getName();
}

$this->setDescription('Warm up Frontend caches of single pages and/or whole sites using their XML sitemaps.');
$this->setHelp(
<<<HELP
Expand Down Expand Up @@ -145,7 +147,7 @@ protected function configure(): void
│ It can be defined via the extension configuration <info>strategy</info> or by using the <info>--strategy</info> option.
│ The following strategies are currently available:
{$decoratedCrawlingStrategies}
├─ Default: <info>{$v($this->configuration->getStrategy() ?? 'none')}</info>
├─ Default: <info>{$v($crawlingStrategy)}</info>
└─ Example: <comment>warming:cachewarmup --strategy {$v(CacheWarmup\Crawler\Strategy\SortByPriorityStrategy::getName())}</comment>
* <comment>Format output</comment>
Expand All @@ -162,8 +164,8 @@ protected function configure(): void
├─ Use the extension configuration <info>verboseCrawler</info> to use an alternative crawler for
│ command-line requests. For warmup requests triggered via the TYPO3 backend, you can use the
│ extension configuration <info>crawler</info>.
├─ Currently used default crawler: <info>{$v($this->configuration->getCrawler())}</info>
└─ Currently used verbose crawler: <info>{$v($this->configuration->getVerboseCrawler())}</info>
├─ Currently used default crawler: <info>{$v($this->configuration->getCrawler()::class)}</info>
└─ Currently used verbose crawler: <info>{$v($this->configuration->getVerboseCrawler()::class)}</info>
* <comment>Custom User-Agent header</comment>
├─ When the default crawler is used, each warmup request is executed with a special User-Agent header.
Expand Down Expand Up @@ -209,7 +211,7 @@ protected function configure(): void
null,
Console\Input\InputOption::VALUE_REQUIRED,
'Optional strategy to prepare URLs before crawling them.',
$this->configuration->getStrategy(),
$crawlingStrategy,
);
$this->addOption(
'format',
Expand All @@ -233,12 +235,8 @@ protected function configure(): void
*/
protected function execute(Console\Input\InputInterface $input, Console\Output\OutputInterface $output): int
{
// Initialize client
$clientOptions = $this->configuration->getParserClientOptions();
$client = $this->clientFactory->get($clientOptions);

// Initialize sub command
$subCommand = new CacheWarmup\Command\CacheWarmupCommand($client, $this->eventDispatcher);
$subCommand = new CacheWarmup\Command\CacheWarmupCommand($this->eventDispatcher);
$subCommand->setApplication($this->getApplication() ?? new Console\Application());

// Initialize sub command input
Expand All @@ -261,7 +259,9 @@ protected function execute(Console\Input\InputInterface $input, Console\Output\O

/**
* @return array<string, mixed>
* @throws CacheWarmup\Exception\Exception
* @throws Core\Exception\SiteNotFoundException
* @throws Core\Package\Exception
* @throws \JsonException
* @throws Typo3SitemapLocator\Exception\BaseUrlIsNotSupported
* @throws Typo3SitemapLocator\Exception\SitemapIsMissing
Expand All @@ -276,18 +276,19 @@ private function prepareCommandParameters(Console\Input\InputInterface $input):
$limit = max(0, (int)$input->getOption('limit'));
$strategy = $input->getOption('strategy');
$format = $input->getOption('format');
$excludePatterns = $this->configuration->getExcludePatterns();

// Fetch crawler and crawler options
// Fetch input options from extension configuration
$excludePatterns = $this->configuration->getExcludePatterns();
$crawler = $this->configuration->getVerboseCrawler();
$crawlerOptions = $this->configuration->getVerboseCrawlerOptions();
$parserOptions = $this->configuration->getParserOptions();

// Initialize sub-command parameters
$subCommandParameters = [
'sitemaps' => $sitemaps,
'--urls' => $urls,
'--limit' => $limit,
'--crawler' => $crawler,
'--crawler' => $crawler::class,
'--format' => $format,
];

Expand All @@ -296,6 +297,11 @@ private function prepareCommandParameters(Console\Input\InputInterface $input):
$subCommandParameters['--crawler-options'] = json_encode($crawlerOptions, JSON_THROW_ON_ERROR);
}

// Add parser options to sub-command parameters
if ($parserOptions !== []) {
$subCommandParameters['--parser-options'] = json_encode($parserOptions, JSON_THROW_ON_ERROR);
}

// Add exclude patterns
if ($excludePatterns !== []) {
$subCommandParameters['--exclude'] = $excludePatterns;
Expand Down
95 changes: 56 additions & 39 deletions Classes/Configuration/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,37 +51,44 @@ final class Configuration
public function __construct(
private readonly Core\Configuration\ExtensionConfiguration $configuration,
private readonly CacheWarmup\Crawler\CrawlerFactory $crawlerFactory,
private readonly Crawler\Strategy\CrawlingStrategyFactory $crawlingStrategyFactory,
private readonly CacheWarmup\Crawler\Strategy\CrawlingStrategyFactory $crawlingStrategyFactory,
private readonly CacheWarmup\Config\Component\OptionsParser $optionsParser,
) {
$this->userAgent = $this->generateUserAgent();
}

/**
* @return class-string<CacheWarmup\Crawler\Crawler>
* @throws CacheWarmup\Exception\CrawlerDoesNotExist
* @throws CacheWarmup\Exception\CrawlerIsInvalid
* @throws CacheWarmup\Exception\OptionsAreInvalid
* @throws CacheWarmup\Exception\OptionsAreMalformed
*/
public function getCrawler(): string
public function getCrawler(): CacheWarmup\Crawler\Crawler
{
try {
/** @var class-string<CacheWarmup\Crawler\Crawler>|null $crawler */
$crawler = $this->configuration->get(Extension::KEY, 'crawler');

if (!\is_string($crawler)) {
return self::DEFAULT_CRAWLER;
}
$crawlerOptions = [];

if (!is_a($crawler, CacheWarmup\Crawler\Crawler::class, true)) {
return self::DEFAULT_CRAWLER;
try {
/** @var class-string<CacheWarmup\Crawler\VerboseCrawler>|null $crawlerClass */
$crawlerClass = $this->configuration->get(Extension::KEY, 'crawler');

if (!\is_string($crawlerClass) ||
!\is_a($crawlerClass, CacheWarmup\Crawler\Crawler::class, true)
) {
$crawlerClass = self::DEFAULT_CRAWLER;
} else {
$crawlerOptions = $this->getCrawlerOptions();
}

return $crawler;
} catch (Core\Exception) {
return self::DEFAULT_CRAWLER;
$crawlerClass = self::DEFAULT_VERBOSE_CRAWLER;
}

return $this->crawlerFactory->get($crawlerClass, $crawlerOptions);
}

/**
* @return array<string, mixed>
* @throws CacheWarmup\Exception\CrawlerOptionIsInvalid
* @throws CacheWarmup\Exception\OptionsAreInvalid
* @throws CacheWarmup\Exception\OptionsAreMalformed
*/
public function getCrawlerOptions(): array
{
Expand All @@ -93,38 +100,47 @@ public function getCrawlerOptions(): array
return [];
}

return $this->crawlerFactory->parseCrawlerOptions($json);
return $this->optionsParser->parse($json);
} catch (Core\Exception) {
return [];
}
}

/**
* @return class-string<CacheWarmup\Crawler\VerboseCrawler>
* @throws CacheWarmup\Exception\CrawlerDoesNotExist
* @throws CacheWarmup\Exception\CrawlerIsInvalid
* @throws CacheWarmup\Exception\OptionsAreInvalid
* @throws CacheWarmup\Exception\OptionsAreMalformed
*/
public function getVerboseCrawler(): string
public function getVerboseCrawler(): CacheWarmup\Crawler\VerboseCrawler
{
try {
/** @var class-string<CacheWarmup\Crawler\VerboseCrawler>|null $crawler */
$crawler = $this->configuration->get(Extension::KEY, 'verboseCrawler');
$crawlerOptions = [];

if (!\is_string($crawler)) {
return self::DEFAULT_VERBOSE_CRAWLER;
}

if (!is_a($crawler, CacheWarmup\Crawler\VerboseCrawler::class, true)) {
return self::DEFAULT_VERBOSE_CRAWLER;
try {
/** @var class-string<CacheWarmup\Crawler\VerboseCrawler>|null $crawlerClass */
$crawlerClass = $this->configuration->get(Extension::KEY, 'verboseCrawler');

if (!\is_string($crawlerClass) ||
!is_a($crawlerClass, CacheWarmup\Crawler\VerboseCrawler::class, true)
) {
$crawlerClass = self::DEFAULT_VERBOSE_CRAWLER;
} else {
$crawlerOptions = $this->getVerboseCrawlerOptions();
}

return $crawler;
} catch (Core\Exception) {
return self::DEFAULT_VERBOSE_CRAWLER;
$crawlerClass = self::DEFAULT_VERBOSE_CRAWLER;
}

/** @var CacheWarmup\Crawler\VerboseCrawler $crawler */
$crawler = $this->crawlerFactory->get($crawlerClass, $crawlerOptions);

return $crawler;
}

/**
* @return array<string, mixed>
* @throws CacheWarmup\Exception\CrawlerOptionIsInvalid
* @throws CacheWarmup\Exception\OptionsAreInvalid
* @throws CacheWarmup\Exception\OptionsAreMalformed
*/
public function getVerboseCrawlerOptions(): array
{
Expand All @@ -136,27 +152,28 @@ public function getVerboseCrawlerOptions(): array
return [];
}

return $this->crawlerFactory->parseCrawlerOptions($json);
return $this->optionsParser->parse($json);
} catch (Core\Exception) {
return [];
}
}

/**
* @return array<string, mixed>
* @throws CacheWarmup\Exception\CrawlerOptionIsInvalid
* @throws CacheWarmup\Exception\OptionsAreInvalid
* @throws CacheWarmup\Exception\OptionsAreMalformed
*/
public function getParserClientOptions(): array
public function getParserOptions(): array
{
try {
$json = $this->configuration->get(Extension::KEY, 'parserClientOptions');
$json = $this->configuration->get(Extension::KEY, 'parserOptions');

// Early return if no parser client options are configured
if (!\is_string($json) || $json === '') {
return [];
}

return $this->crawlerFactory->parseCrawlerOptions($json);
return $this->optionsParser->parse($json);
} catch (Core\Exception) {
return [];
}
Expand Down Expand Up @@ -196,7 +213,7 @@ public function getExcludePatterns(): array
}
}

public function getStrategy(): ?string
public function getStrategy(): ?CacheWarmup\Crawler\Strategy\CrawlingStrategy
{
try {
$strategy = $this->configuration->get(Extension::KEY, 'strategy');
Expand All @@ -211,7 +228,7 @@ public function getStrategy(): ?string
return null;
}

return $strategy;
return $this->crawlingStrategyFactory->get($strategy);
} catch (Core\Exception) {
return null;
}
Expand Down
4 changes: 3 additions & 1 deletion Classes/Controller/CacheWarmupController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use EliasHaeussler\CacheWarmup;
use EliasHaeussler\SSE;
use EliasHaeussler\Typo3SitemapLocator;
use EliasHaeussler\Typo3Warming\Configuration;
use EliasHaeussler\Typo3Warming\Crawler;
use EliasHaeussler\Typo3Warming\Http;
use EliasHaeussler\Typo3Warming\Service;
Expand All @@ -47,6 +48,7 @@
final class CacheWarmupController
{
public function __construct(
private readonly Configuration\Configuration $configuration,
private readonly Log\LoggerInterface $logger,
private readonly Valinor\Mapper\TreeMapper $mapper,
private readonly Http\Message\ResponseFactory $responseFactory,
Expand Down Expand Up @@ -91,7 +93,7 @@ public function __invoke(Message\ServerRequestInterface $request): Message\Respo
$eventStream->open();

// Apply event stream to crawler
$crawler = $this->warmupService->getCrawler();
$crawler = $this->configuration->getCrawler();
if ($crawler instanceof Crawler\StreamableCrawler) {
$crawler->setStream($eventStream);
}
Expand Down
9 changes: 5 additions & 4 deletions Classes/Controller/FetchSitesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@

namespace EliasHaeussler\Typo3Warming\Controller;

use EliasHaeussler\CacheWarmup;
use EliasHaeussler\Typo3SitemapLocator;
use EliasHaeussler\Typo3Warming\Configuration;
use EliasHaeussler\Typo3Warming\Crawler;
use EliasHaeussler\Typo3Warming\Http;
use EliasHaeussler\Typo3Warming\Utility;
use EliasHaeussler\Typo3Warming\ValueObject;
Expand All @@ -45,7 +45,7 @@ final class FetchSitesController
{
public function __construct(
private readonly Configuration\Configuration $configuration,
private readonly Crawler\Strategy\CrawlingStrategyFactory $crawlingStrategyFactory,
private readonly CacheWarmup\Crawler\Strategy\CrawlingStrategyFactory $crawlingStrategyFactory,
private readonly Core\Imaging\IconFactory $iconFactory,
private readonly Http\Message\ResponseFactory $responseFactory,
private readonly Core\Site\SiteFinder $siteFinder,
Expand All @@ -58,6 +58,7 @@ public function __construct(
*/
public function __invoke(): Message\ResponseInterface
{
$crawlingStrategy = $this->configuration->getStrategy();
$siteGroups = [];

foreach (array_filter($this->siteFinder->getAllSites(), Utility\AccessUtility::canWarmupCacheOfSite(...)) as $site) {
Expand All @@ -79,9 +80,9 @@ public function __invoke(): Message\ResponseInterface
'userAgent' => $this->configuration->getUserAgent(),
'configuration' => [
'limit' => $this->configuration->getLimit(),
'strategy' => $this->configuration->getStrategy(),
'strategy' => $crawlingStrategy !== null ? $crawlingStrategy::getName() : null,
],
'availableStrategies' => array_keys($this->crawlingStrategyFactory->getAll()),
'availableStrategies' => $this->crawlingStrategyFactory->getAll(),
'isAdmin' => Utility\BackendUtility::getBackendUser()->isAdmin(),
]);
}
Expand Down
Loading

0 comments on commit 7332621

Please sign in to comment.