Commit d7b93ccb authored by Dominique Feyer's avatar Dominique Feyer

[TASK] Add support for async sitemap building

parent e6c67bfe
......@@ -2,7 +2,7 @@
namespace Ttree\Neos\Sitemap\Command;
use Ttree\Neos\Sitemap\Domain\Model\SitemapDefinition;
use Ttree\Neos\Sitemap\Service\SitemapBuilder;
use Ttree\Neos\Sitemap\Service\SitemapBuilderInterface;
use TYPO3\Flow\Annotations as Flow;
use TYPO3\Flow\Cli\CommandController;
use TYPO3\Flow\Utility\Files;
......@@ -11,7 +11,7 @@ class SitemapCommandController extends CommandController {
/**
* @Flow\Inject
* @var SitemapBuilder
* @var SitemapBuilderInterface
*/
protected $sitemapBuilder;
......@@ -19,14 +19,19 @@ class SitemapCommandController extends CommandController {
* @param string $siteNodeName
* @param string $baseUrl
* @param string $preset
* @param boolean $async
*/
public function generateCommand($siteNodeName, $baseUrl, $preset = 'default') {
public function generateCommand($siteNodeName, $baseUrl, $preset = 'default', $async = FALSE) {
$definition = new SitemapDefinition($siteNodeName, $baseUrl, $preset);
if ($async === TRUE) {
$definition->queue();
} else {
$sitemap = $this->sitemapBuilder->build($definition);
$pathAndFilename = $definition->getPath();
Files::createDirectoryRecursively(dirname($pathAndFilename));
file_put_contents($pathAndFilename, (string)$sitemap);
}
}
}
\ No newline at end of file
<?php
namespace Ttree\Neos\Sitemap\Domain\Model;
use Ttree\Neos\Sitemap\Job\BuildRequestJob;
use TYPO3\Flow\Annotations as Flow;
use TYPO3\Flow\Exception;
use TYPO3\Jobqueue\Common\Job\JobManager;
/**
* @api
*/
class SitemapDefinition {
/**
* @Flow\Inject
* @var JobManager
*/
protected $jobManager;
/**
* @var string
*/
......@@ -31,7 +39,8 @@ class SitemapDefinition {
protected $presets;
/**
* SitemapDefinition constructor.
* SitemapDefinition constructor
*
* @param string $siteNodeName
* @param string $baseUrl
* @param string $presetName
......@@ -68,6 +77,13 @@ class SitemapDefinition {
return $this->baseUrl;
}
/**
* @return string
*/
public function getPresetName() {
return $this->presetName;
}
/**
* @return array
*/
......@@ -82,4 +98,18 @@ class SitemapDefinition {
return $this->getPreset()['path'];
}
/**
* Queue the current definition
*
* @return void
* @throws Exception
*/
public function queue() {
if (!isset($this->getPreset()['queueName'])) {
throw new Exception('Missing queueName in the current preset', 1442502965);
}
$job = new BuildRequestJob($this);
$this->jobManager->queue($this->getPreset()['queueName'], $job);
}
}
\ No newline at end of file
<?php
namespace Ttree\Neos\Sitemap\Job;
use Ttree\Neos\Sitemap\Domain\Model\SitemapDefinition;
use Ttree\Neos\Sitemap\Service\SitemapBuilderInterface;
use TYPO3\Flow\Annotations as Flow;
use TYPO3\Flow\Log\SystemLoggerInterface;
use TYPO3\Flow\Utility\Algorithms;
use TYPO3\Flow\Utility\Files;
use TYPO3\Jobqueue\Common\Job\JobInterface;
use TYPO3\Jobqueue\Common\Queue\Message;
use TYPO3\Jobqueue\Common\Queue\QueueInterface;
/**
* Build Requested Job
*/
class BuildRequestJob implements JobInterface {
/**
* @Flow\Inject
* @var SitemapBuilderInterface
*/
protected $sitemapBuilder;
/**
* @Flow\Inject
* @var SystemLoggerInterface
*/
protected $logger;
/**
* @var string
*/
protected $identifier;
/**
* @var SitemapDefinition
*/
protected $defintion;
/**
* @param SitemapDefinition $definiton
*/
public function __construct(SitemapDefinition $definiton) {
$this->identifier = Algorithms::generateRandomString(24);
$this->defintion = $definiton;
}
/**
* Execute the job
* A job should finish itself after successful execution using the queue methods.
*
* @param QueueInterface $queue
* @param Message $message The original message
* @return boolean TRUE if the job was executed successfully and the message should be finished
*/
public function execute(QueueInterface $queue, Message $message) {
$sitemap = $this->sitemapBuilder->build($this->defintion);
$pathAndFilename = $this->defintion->getPath();
Files::createDirectoryRecursively(dirname($pathAndFilename));
file_put_contents($pathAndFilename, (string)$sitemap);
$this->logger->log(sprintf('Build Request Job processed with success, preset: %s, path: %s', $this->defintion->getPresetName(), $this->defintion->getPath()));
return TRUE;
}
/**
* Get an optional identifier for the job
*
* @return string A job identifier
*/
public function getIdentifier() {
return $this->identifier;
}
/**
* Get a readable label for the job
*
* @return string A label for the job
*/
public function getLabel() {
return sprintf('Sitemap Build Requested Job (%s)', $this->getIdentifier());
}
}
......@@ -8,4 +8,5 @@ Ttree:
skip:
'TYPO3.Neos:Shortcut': TRUE
type: 'single'
path: '%FLOW_PATH_DATA%/Persistent/Sitemaps/Sitemap.xml'
queueName: 'Default'
path: '%FLOW_PATH_DATA%/Web/sitemap.xml'
\ No newline at end of file
......@@ -36,11 +36,53 @@ FLOW_REWRITEURLS=1 ./flow sitemap:generate --site-node-name architectesch --base
__Warning__: The environnement variable ```FLOW_REWRITEURLS``` is required in CLI to have proper URI building
How to use the Job Queue feature ?
----------------------------------
When you install this package, composer will install automatically ```typo3/jobqueue-common``` so you need one of the Job Queue
adapater, like the ``typo3/jobqueue-beanstalkd```. Once your setup with, you can edit your ```Settings.yaml```:
TYPO3:
Jobqueue:
Common:
queues:
'Default':
className: 'TYPO3\Jobqueue\Beanstalkd\Queue\BeanstalkdQueue'
In this case ```Default``` is the name of the queue, edition your preset:
Ttree:
Neos:
Sitemap:
presets:
default:
queue: 'Default'
include:
'TYPO3.Neos.NodeTypes:Page': TRUE
skip:
'TYPO3.Neos:Shortcut': TRUE
type: 'single'
path: '%FLOW_PATH_DATA%/Persistent/Sitemaps/Sitemap.xml'
And create your first job:
```
FLOW_REWRITEURLS=1 ./flow sitemap:generate --site-node-name architectesch --base-url http://www.architectes.ch/ --preset default --async
# You should see one job in the queue
flow job:list --queue-name Default
# You can now process the job, this command is a long running process, use Ctrl-C to exit
flow job:work --queue-name Default
```
Check your system log at ```Data/Logs/System.log``` or ```Data/Logs/System_Development.log``` depending of your application context,
you should see a log message saying something like: Build Request Job processed with success
What's next ?
-------------
- Implement type: "multiple", to generate multiple sitemap with one index
- Implement asynchronous sitemap generation based on Job Queue
- Integrate with Neos.SEO package for advanced configuration per document
Acknowledgments
......
......@@ -4,8 +4,12 @@
"description": "Add description here",
"require": {
"typo3/neos": "*",
"typo3/jobqueue-common": "*",
"tackk/cartographer": "^1.1"
},
"suggest": {
"typo3/jobqueue-beanstalkd": "Use Beanstalkd for Job Queue handling"
},
"autoload": {
"psr-4": {
"Ttree\\Neos\\Sitemap\\": "Classes"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment