Skip to content

Commit 3258215

Browse files
committed
Enhancing how images are copied
1 parent 10dfa59 commit 3258215

File tree

8 files changed

+127
-43
lines changed

8 files changed

+127
-43
lines changed

src/BuildContext.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,16 @@ public function __construct(
3333

3434
public function initializeRuntimeConfig(string $sourceDir, string $outputDir, ?string $parseSubPath = null, bool $disableCache = false, string $theme = Configuration::THEME_DEFAULT)
3535
{
36-
$this->sourceDir = $sourceDir;
37-
$this->outputDir = $outputDir;
36+
if (!file_exists($sourceDir)) {
37+
throw new \Exception(sprintf('Source directory "%s" does not exist', $sourceDir));
38+
}
39+
40+
if (!file_exists($outputDir)) {
41+
throw new \Exception(sprintf('Output directory "%s" does not exist', $outputDir));
42+
}
43+
44+
$this->sourceDir = realpath($sourceDir);
45+
$this->outputDir = realpath($outputDir);
3846
$this->parseSubPath = $parseSubPath;
3947
$this->disableCache = $disableCache;
4048
$this->theme = $theme;

src/Command/BuildDocsCommand.php

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
use Doctrine\Common\EventManager;
66
use Doctrine\RST\Builder;
77
use Doctrine\RST\Configuration;
8+
use Doctrine\RST\ErrorManager;
89
use Doctrine\RST\Event\PostBuildRenderEvent;
10+
use Doctrine\RST\Event\PreNodeRenderEvent;
911
use Doctrine\RST\Meta\Metas;
1012
use Symfony\Component\Console\Command\Command;
1113
use Symfony\Component\Console\Input\InputArgument;
@@ -21,7 +23,7 @@
2123
use SymfonyDocsBuilder\KernelFactory;
2224
use SymfonyDocsBuilder\Listener\AssetsCopyListener;
2325
use SymfonyDocsBuilder\Listener\BuildProgressListener;
24-
use SymfonyDocsBuilder\Listener\CopyImagesDirectoryListener;
26+
use SymfonyDocsBuilder\Listener\CopyImagesListener;
2527

2628
class BuildDocsCommand extends Command
2729
{
@@ -96,6 +98,8 @@ protected function initialize(InputInterface $input, OutputInterface $output)
9698
$filesystem->remove($htmlOutputDir);
9799
}
98100

101+
$filesystem->mkdir($htmlOutputDir);
102+
99103
$parseSubPath = $input->getOption('parse-sub-path');
100104
if ($parseSubPath && $input->getOption('output-json')) {
101105
throw new \InvalidArgumentException('Cannot pass both --parse-sub-path and --output-json options.');
@@ -120,7 +124,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
120124
KernelFactory::createKernel($this->buildContext, $this->urlChecker ?? null)
121125
);
122126

123-
$this->initializeListeners($builder->getConfiguration()->getEventManager());
127+
$this->addProgressListener($builder->getConfiguration()->getEventManager());
124128

125129
$builder->build(
126130
$this->buildContext->getSourceDir(),
@@ -175,20 +179,8 @@ private function renderDocForPDF(Metas $metas)
175179
$htmlForPdfGenerator->generateHtmlForPdf();
176180
}
177181

178-
private function initializeListeners(EventManager $eventManager)
182+
private function addProgressListener(EventManager $eventManager)
179183
{
180-
$eventManager->addEventListener(
181-
PostBuildRenderEvent::POST_BUILD_RENDER,
182-
new CopyImagesDirectoryListener($this->buildContext)
183-
);
184-
185-
if (!$this->buildContext->getParseSubPath()) {
186-
$eventManager->addEventListener(
187-
[PostBuildRenderEvent::POST_BUILD_RENDER],
188-
new AssetsCopyListener($this->buildContext->getOutputDir())
189-
);
190-
}
191-
192184
$progressListener = new BuildProgressListener($this->io);
193185
$progressListener->attachListeners($eventManager);
194186
}

src/DocsKernel.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace SymfonyDocsBuilder;
4+
5+
use Doctrine\Common\EventManager;
6+
use Doctrine\RST\Builder;
7+
use Doctrine\RST\Configuration;
8+
use Doctrine\RST\ErrorManager;
9+
use Doctrine\RST\Event\PostBuildRenderEvent;
10+
use Doctrine\RST\Event\PreNodeRenderEvent;
11+
use Doctrine\RST\Kernel;
12+
use SymfonyDocsBuilder\Listener\AssetsCopyListener;
13+
use SymfonyDocsBuilder\Listener\CopyImagesListener;
14+
15+
class DocsKernel extends Kernel
16+
{
17+
private $buildContext;
18+
19+
public function __construct(?Configuration $configuration = null, $directives = [], $references = [], BuildContext $buildContext)
20+
{
21+
parent::__construct($configuration, $directives, $references);
22+
23+
$this->buildContext = $buildContext;
24+
}
25+
26+
public function initBuilder(Builder $builder): void
27+
{
28+
$this->initializeListeners(
29+
$builder->getConfiguration()->getEventManager(),
30+
$builder->getErrorManager()
31+
);
32+
}
33+
34+
private function initializeListeners(EventManager $eventManager, ErrorManager $errorManager)
35+
{
36+
$eventManager->addEventListener(
37+
PreNodeRenderEvent::PRE_NODE_RENDER,
38+
new CopyImagesListener($this->buildContext, $errorManager)
39+
);
40+
41+
if (!$this->buildContext->getParseSubPath()) {
42+
$eventManager->addEventListener(
43+
[PostBuildRenderEvent::POST_BUILD_RENDER],
44+
new AssetsCopyListener($this->buildContext->getOutputDir())
45+
);
46+
}
47+
}
48+
}

src/KernelFactory.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ static function (string $path) use ($parseSubPath) : bool {
4848
$twig = $configuration->getTemplateEngine();
4949
$twig->addExtension(new AssetsExtension($buildContext->getOutputDir()));
5050

51-
return new Kernel(
51+
return new DocsKernel(
5252
$configuration,
5353
self::getDirectives(),
54-
self::getReferences($buildContext)
54+
self::getReferences($buildContext),
55+
$buildContext
5556
);
5657
}
5758

src/Listener/CopyImagesDirectoryListener.php

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/Listener/CopyImagesListener.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace SymfonyDocsBuilder\Listener;
4+
5+
use Doctrine\RST\ErrorManager;
6+
use Doctrine\RST\Event\PreNodeRenderEvent;
7+
use Doctrine\RST\Nodes\ImageNode;
8+
use Symfony\Component\Filesystem\Filesystem;
9+
use SymfonyDocsBuilder\BuildContext;
10+
11+
class CopyImagesListener
12+
{
13+
private $buildContext;
14+
private $errorManager;
15+
16+
public function __construct(BuildContext $buildContext, ErrorManager $errorManager)
17+
{
18+
$this->buildContext = $buildContext;
19+
$this->errorManager = $errorManager;
20+
}
21+
22+
public function preNodeRender(PreNodeRenderEvent $event)
23+
{
24+
$node = $event->getNode();
25+
if (!$node instanceof ImageNode) {
26+
return;
27+
}
28+
29+
$sourceImage = $node->getEnvironment()->absoluteRelativePath($node->getUrl());
30+
31+
if (!file_exists($sourceImage)) {
32+
$this->errorManager->error(sprintf(
33+
'Missing image file "%s" in "%s"',
34+
$node->getUrl(),
35+
$node->getEnvironment()->getCurrentFileName()
36+
));
37+
38+
return;
39+
}
40+
41+
$fileInfo = new \SplFileInfo($sourceImage);
42+
$fs = new Filesystem();
43+
44+
// the /_images path is currently hardcoded here and respected
45+
// in the overridden image node template
46+
$newPath = '/_images/'.$fileInfo->getFilename();
47+
$fs->copy($sourceImage, $this->buildContext->getOutputDir().$newPath, true);
48+
49+
$node->setValue($node->getEnvironment()->relativeUrl(
50+
'/_images/' . $fileInfo->getFilename()
51+
));
52+
}
53+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{#
2+
Overridden so we can control the path to the image based on our copying logic.
3+
See CopyImagesListener.
4+
#}
5+
<img src="{{ imageNode.value }}" {% for key, value in imageNode.options %}{{ key }}="{{ value }}" {% endfor %}/>

tests/IntegrationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public function testIntegration(string $folder)
3333
{
3434
$fs = new Filesystem();
3535
$fs->remove(__DIR__.'/_output');
36+
$fs->mkdir(__DIR__.'/_output');
3637

3738
$buildContext = $this->createBuildContext(sprintf('%s/fixtures/source/%s', __DIR__, $folder));
3839

0 commit comments

Comments
 (0)