Skip to content

Commit

Permalink
Merge pull request #3826 from mficzel/feature/actionLinkPrototypes
Browse files Browse the repository at this point in the history
FEATURE: Introduce `Neos.Fusion:ActionUri` as replacement for `Neos.Fusion:UriBuilder`
  • Loading branch information
mficzel authored Jul 15, 2022
2 parents 24bf4a6 + db18a52 commit 62bd12a
Show file tree
Hide file tree
Showing 5 changed files with 283 additions and 2 deletions.
209 changes: 209 additions & 0 deletions Classes/FusionObjects/ActionUriImplementation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
<?php
declare(strict_types=1);

namespace Neos\Fusion\FusionObjects;

/*
* This file is part of the Neos.Fusion package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Neos\Flow\Mvc\ActionRequest;
use Neos\Flow\Mvc\Routing\UriBuilder;

/**
* A Fusion ActionUri object
*
* The following Fusion properties are evaluated:
* * package
* * subpackage
* * controller
* * action
* * arguments
* * format
* * section
* * additionalParams
* * addQueryString
* * argumentsToBeExcludedFromQueryString
* * absolute
* * request
*
* See respective getters for descriptions
*/
class ActionUriImplementation extends AbstractFusionObject
{
/**
* @return ActionRequest
*/
public function getRequest(): ActionRequest
{
return $this->fusionValue('request');
}

/**
* Key of the target package
*
* @return string|null
*/
public function getPackage(): ?string
{
return $this->fusionValue('package');
}

/**
* Key of the target sub package
*
* @return string|null
*/
public function getSubpackage(): ?string
{
return $this->fusionValue('subpackage');
}

/**
* Target controller name
*
* @return string|null
*/
public function getController(): ?string
{
return $this->fusionValue('controller');
}

/**
* Target controller action name
*
* @return string|null
*/
public function getAction(): ?string
{
return $this->fusionValue('action');
}

/**
* Controller arguments
*
* @return array|null
*/
public function getArguments(): ?array
{
$arguments = $this->fusionValue('arguments');
return is_array($arguments) ? $arguments: [];
}

/**
* The requested format, for example "html"
*
* @return string|null
*/
public function getFormat(): ?string
{
return $this->fusionValue('format');
}

/**
* The anchor to be appended to the URL
*
* @return string|null
*/
public function getSection(): ?string
{
return $this->fusionValue('section');
}

/**
* Additional query parameters that won't be prefixed like $arguments (overrule $arguments)
*
* @return array|null
*/
public function getAdditionalParams(): ?array
{
return $this->fusionValue('additionalParams');
}

/**
* Arguments to be removed from the URI. Only active if addQueryString = true
*
* @return array|null
*/
public function getArgumentsToBeExcludedFromQueryString(): ?array
{
return $this->fusionValue('argumentsToBeExcludedFromQueryString');
}

/**
* If true, the current query parameters will be kept in the URI
*
* @return boolean
*/
public function isAddQueryString(): bool
{
return (boolean)$this->fusionValue('addQueryString');
}

/**
* If true, an absolute URI is rendered
*
* @return boolean
*/
public function isAbsolute(): bool
{
return (boolean)$this->fusionValue('absolute');
}

/**
* @return string
*/
public function evaluate()
{
$uriBuilder = new UriBuilder();
$uriBuilder->setRequest($this->getRequest());

$format = $this->getFormat();
if ($format !== null) {
$uriBuilder->setFormat($format);
}

$additionalParams = $this->getAdditionalParams();
if ($additionalParams !== null) {
$uriBuilder->setArguments($additionalParams);
}

$argumentsToBeExcludedFromQueryString = $this->getArgumentsToBeExcludedFromQueryString();
if ($argumentsToBeExcludedFromQueryString !== null) {
$uriBuilder->setArgumentsToBeExcludedFromQueryString($argumentsToBeExcludedFromQueryString);
}

$absolute = $this->isAbsolute();
if ($absolute === true) {
$uriBuilder->setCreateAbsoluteUri(true);
}

$section = $this->getSection();
if ($section !== null) {
$uriBuilder->setSection($section);
}

$addQueryString = $this->isAddQueryString();
if ($addQueryString === true) {
$uriBuilder->setAddQueryString(true);
}

try {
return $uriBuilder->uriFor(
$this->getAction(),
$this->getArguments(),
$this->getController(),
$this->getPackage(),
$this->getSubpackage()
);
} catch (\Exception $exception) {
return $this->runtime->handleRenderingException($this->path, $exception);
}
}
}
2 changes: 2 additions & 0 deletions Classes/FusionObjects/UriBuilderImplementation.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
* * absolute
*
* See respective getters for descriptions
*
* @deprecated in favor of ActionUriImplementation
*/
class UriBuilderImplementation extends AbstractFusionObject
{
Expand Down
23 changes: 21 additions & 2 deletions Resources/Private/Fusion/Root.fusion
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,25 @@ prototype(Neos.Fusion:ResourceUri) {
@exceptionHandler = 'Neos\\Fusion\\Core\\ExceptionHandlers\\AbsorbingHandler'
}

# Renders an URI pointing to a controller/action
#
# Usage:
# uri = Neos.Fusion:ActionUri {
# package = 'Some.Package'
# controller = 'Standard'
# action = 'index'
# }
#
prototype(Neos.Fusion:ActionUri) {
@class = 'Neos\\Fusion\\FusionObjects\\ActionUriImplementation'
request = ${request}
additionalParams = Neos.Fusion:DataStructure
arguments = Neos.Fusion:DataStructure
argumentsToBeExcludedFromQueryString = Neos.Fusion:DataStructure

@exceptionHandler = 'Neos\\Fusion\\Core\\ExceptionHandlers\\AbsorbingHandler'
}

# Renders a link pointing to a controller/action
#
# Usage:
Expand All @@ -206,7 +225,7 @@ prototype(Neos.Fusion:ResourceUri) {
# `
#
prototype(Neos.Fusion:Link.Action) < prototype(Neos.Fusion:Component) {
href = Neos.Fusion:UriBuilder
href = Neos.Fusion:ActionUri
content = ''

renderer = Neos.Fusion:Tag {
Expand All @@ -223,7 +242,7 @@ prototype(Neos.Fusion:Link.Action) < prototype(Neos.Fusion:Component) {
#
# Usage:
# link = afx`
# <Neos.Fusion:Link.Resource class="action-link" href.path="resource://Some.Package/Public/Images/SomeImage.png">
# <Neos.Fusion:Link.Resource class="resource-link" href.path="resource://Some.Package/Public/Images/SomeImage.png">
# Some Link
# </Neos.Fusion:Link.Resource>
# `
Expand Down
40 changes: 40 additions & 0 deletions Tests/Functional/FusionObjects/ActionUriTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
namespace Neos\Fusion\Tests\Functional\FusionObjects;

/*
* This file is part of the Neos.Fusion package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

/**
* Testcase for the UriBuilder object
*/
class ActionUriTest extends AbstractFusionObjectTest
{
/**
* @test
*/
public function buildRelativeUriToAction()
{
$this->registerRoute(
'Fusion functional test',
'neos/flow/test/http/foo',
[
'@package' => 'Neos.Flow',
'@subpackage' => 'Tests\Functional\Http\Fixtures',
'@controller' => 'Foo',
'@action' => 'index',
'@format' => 'html'
]
);

$view = $this->buildView();
$view->setFusionPath('actionUri/foo');
self::assertStringContainsString('/neos/flow/test/http/foo', $view->render());
}
}
11 changes: 11 additions & 0 deletions Tests/Functional/FusionObjects/Fixtures/Fusion/ActionUri.fusion
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
prototype(Neos.Fusion:ActionUri) {
@class = 'Neos\\Fusion\\FusionObjects\\ActionUriImplementation'
request = ${request}
}

actionUri.foo = Neos.Fusion:ActionUri {
package = 'Neos.Flow'
subpackage = 'Tests\\Functional\\Http\\Fixtures'
controller = 'Foo'
action = 'index'
}

0 comments on commit 62bd12a

Please sign in to comment.