Skip to content

Commit 0ba7d89

Browse files
committed
Initial commit
0 parents  commit 0ba7d89

File tree

4 files changed

+866
-0
lines changed

4 files changed

+866
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace Garagist\ContentBox\FusionService\Service;
4+
5+
use Neos\Flow\Mvc\ActionRequest;
6+
use Neos\Flow\Mvc\ActionRequestFactory;
7+
use Neos\Flow\Mvc\ActionResponse;
8+
use Neos\Flow\Mvc\Controller\Arguments;
9+
use Neos\Flow\Mvc\Routing\UriBuilder;
10+
use Neos\Flow\Mvc\Controller\ControllerContext;
11+
use Neos\Http\Factories\ServerRequestFactory;
12+
use Psr\Http\Message\ServerRequestInterface;
13+
14+
/**
15+
* Utility trait to create controller contexts within CLI SAPI
16+
*/
17+
trait DummyControllerContextTrait
18+
{
19+
/**
20+
* Create a dummy controller context
21+
*
22+
* @return ControllerContext
23+
*/
24+
protected function createDummyControllerContext(): ControllerContext
25+
{
26+
$actionRequestFactory = new ActionRequestFactory();
27+
$serverRequestFactory = new ServerRequestFactory();
28+
29+
/** @var ServerRequestInterface */
30+
$httpRequest = $serverRequestFactory->createServerRequest('GET', 'http://neos.io');
31+
32+
/** @var ActionRequest */
33+
$actionRequest = $actionRequestFactory->createActionRequest($httpRequest);
34+
$actionResponse = new ActionResponse();
35+
36+
$arguments = new Arguments([]);
37+
$uriBuilder = new UriBuilder();
38+
$uriBuilder->setRequest($actionRequest);
39+
40+
return new ControllerContext($actionRequest, $actionResponse, $arguments, $uriBuilder);
41+
}
42+
}

Classes/Service/FusionService.php

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
namespace Garagist\ContentBox\FusionService\Service;
4+
5+
use Garagist\ContentBox\Exception\ContentBoxRenderingException;
6+
use Neos\ContentRepository\Domain\Projection\Content\TraversableNodeInterface;
7+
use Neos\Flow\Annotations as Flow;
8+
use Neos\Fusion\Afx\Parser\AfxParserException;
9+
use Neos\Fusion\Afx\Service\AfxService;
10+
use Neos\Fusion\Core\Parser;
11+
use Neos\Fusion\Core\RuntimeFactory as FusionRuntimeFactory;
12+
use Neos\Fusion\Exception\RuntimeException;
13+
use Neos\Neos\Domain\Service\FusionService as NeosFusionService;
14+
use Symfony\Component\Yaml\Yaml;
15+
16+
/**
17+
* Class FusionService
18+
*/
19+
class FusionService extends NeosFusionService
20+
{
21+
use DummyControllerContextTrait;
22+
23+
/**
24+
* @Flow\InjectConfiguration(path="fusion.autoInclude", package="Neos.Neos")
25+
* @var array
26+
*/
27+
protected $autoIncludeConfiguration = array();
28+
29+
/**
30+
* @Flow\Inject
31+
* @var FusionRuntimeFactory
32+
*/
33+
protected $fusionRuntimeFactory;
34+
35+
/**
36+
* Render the given string of AFX and returns it
37+
*
38+
* @param [NodeInterface] $contextNodes
39+
* @param string $html
40+
* @param string|null $props
41+
* @return string
42+
* @throws ContentBoxRenderingException|AfxParserException
43+
*/
44+
public function render(array $contextNodes, string $html, ?string $props = null): string
45+
{
46+
$props = isset($props) ? Yaml::parse($props) : [];
47+
$controllerContext = $this->createDummyControllerContext();
48+
49+
try {
50+
$fusion = AfxService::convertAfxToFusion($html);
51+
$parsedFusion = $this->getMergedFusionObjectTree('html = ' . $fusion, $contextNodes['site'] ?? null);
52+
53+
$fusionRuntime = $this->fusionRuntimeFactory->create($parsedFusion, $controllerContext);
54+
$fusionRuntime->pushContext('props', $props);
55+
if (isset($contextNodes['node'])) {
56+
$fusionRuntime->pushContext('node', $contextNodes['node']);
57+
}
58+
if (isset($contextNodes['documentNode'])) {
59+
$fusionRuntime->pushContext('documentNode', $contextNodes['documentNode']);
60+
}
61+
if (isset($contextNodes['site'])) {
62+
$fusionRuntime->pushContext('site', $contextNodes['site']);
63+
}
64+
$fusionRuntime->setEnableContentCache(false);
65+
66+
return $fusionRuntime->render('html');
67+
} catch (RuntimeException $e) {
68+
throw new ContentBoxRenderingException($e->getPrevious()->getMessage(), 1600950000, $e);
69+
} catch (AfxParserException $e) {
70+
throw new ContentBoxRenderingException($e->getMessage(), 1600960000, $e);
71+
}
72+
}
73+
74+
/**
75+
* @Flow\Inject
76+
* @var Parser
77+
*/
78+
protected $fusionParser;
79+
80+
/**
81+
* Parse all the fusion files the are in the current fusionPathPatterns
82+
*
83+
* @param $fusion
84+
* @param TraversableNodeInterface $startNode
85+
* @return array
86+
*/
87+
public function getMergedFusionObjectTree($fusion, ?TraversableNodeInterface $startNode = null): array
88+
{
89+
$siteRootFusionCode = '';
90+
if ($startNode) {
91+
$siteResourcesPackageKey = $this->getSiteForSiteNode($startNode)->getSiteResourcesPackageKey();
92+
$siteRootFusionPathAndFilename = sprintf('resource://%s/Private/Fusion/Root.fusion', $siteResourcesPackageKey);
93+
$siteRootFusionCode = $this->getFusionIncludes([$siteRootFusionPathAndFilename]);
94+
}
95+
96+
$fusionCode = $this->generateNodeTypeDefinitions();
97+
$fusionCode .= $this->getFusionIncludes($this->prepareAutoIncludeFusion());
98+
$fusionCode .= $this->getFusionIncludes($this->prependFusionIncludes);
99+
$fusionCode .= $siteRootFusionCode;
100+
$fusionCode .= $this->getFusionIncludes($this->appendFusionIncludes);
101+
$fusionCode .= $this->getFusionIncludes(['resource://Garagist.ContentBox/Private/ContentBox/Root.fusion']);
102+
$fusionCode .= $fusion;
103+
104+
return $this->fusionParser->parse($fusionCode, null);
105+
}
106+
}

0 commit comments

Comments
 (0)