Skip to content

Commit

Permalink
TASK: fixes after review
Browse files Browse the repository at this point in the history
  • Loading branch information
Florian Heinze authored and klfman committed May 19, 2022
1 parent cbd26d8 commit 3815d9b
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 104 deletions.
78 changes: 0 additions & 78 deletions Classes/Eel/Helper/ConditionalServiceRendering.php

This file was deleted.

63 changes: 60 additions & 3 deletions Classes/Eel/Helper/CookiePunchConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

namespace Sandstorm\CookiePunch\Eel\Helper;

use Neos\Eel\Helper\ConfigurationHelper;
use Exception;
use Neos\Flow\Annotations as Flow;
use Neos\Eel\ProtectedContextAwareInterface;
use Neos\Flow\I18n\EelHelper\TranslationHelper;
use phpDocumentor\Reflection\Types\Boolean;
use Neos\Eel\Helper\ConfigurationHelper;
use Neos\Eel\ProtectedContextAwareInterface;
use Neos\Eel\Utility as EelUtility;
use Neos\Eel\CompilingEvaluator;
use Neos\ContentRepository\Domain\Model\NodeInterface;

class CookiePunchConfig implements ProtectedContextAwareInterface
{
Expand All @@ -24,6 +27,60 @@ public function translate($path): ?string
}
}

/**
* @Flow\Inject(lazy=false)
* @var CompilingEvaluator
*/
protected CompilingEvaluator $eelEvaluator;

/**
* @Flow\InjectConfiguration(package="Neos.Fusion", path="defaultContext")
* @var array
*/
protected array $defaultContext;

/**
* @param array $services
* @param NodeInterface $siteNode
* @return array
* @throws Exception
*/
public function filterServicesArrayByWhenCondition(array $services, NodeInterface $siteNode): array
{
return array_filter($services, function($service) use(&$siteNode) {
return !isset($service['when']) || $this->evaluateEelExpression($service['when'], $siteNode);
});
}

/**
* @param string $eelExpression
* @param NodeInterface $siteNode
* @return bool
* @throws Exception for invalid eel expressions
*/
public function evaluateEelExpression(string $eelExpression, NodeInterface $siteNode): bool
{
if (preg_match(\Neos\Eel\Package::EelExpressionRecognizer, $eelExpression)) {
$defaultContextVariables = EelUtility::getDefaultContextVariables($this->defaultContext);

$context = [
'site' => $siteNode
];

$contextVariables = array_merge($defaultContextVariables, $context);

$result = EelUtility::evaluateEelExpression($eelExpression, $this->eelEvaluator, $contextVariables);

// hard cast to boolean, only boolean expressions are supported. Other expression types are unsupported
// We do not throw an exception here after checking if (!is_bool($result)), because this would prevent
// often used eel expression shortcuts like ${q(site).property('googleAnalyticsAccountKey')} that are truthy
// or falsy but not strictly of type bool from being used
return (bool) $result;
} else {
throw new Exception("Invalid eel expression in CookiePunch config service block. Given: " . $eelExpression);
}
}

/**
* All methods are considered safe, i.e. can be executed from within Eel
*
Expand Down
1 change: 0 additions & 1 deletion Configuration/Settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ Neos:
defaultContext:
"CookiePunch": Sandstorm\CookiePunch\Eel\Helper\CookiePunch
"CookiePunchConfig": Sandstorm\CookiePunch\Eel\Helper\CookiePunchConfig
"ConditionalRendering": Sandstorm\CookiePunch\Eel\Helper\ConditionalServiceRendering
Sandstorm:
CookiePunch:
consent:
Expand Down
11 changes: 5 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,9 @@ You can override translations
- in the yaml config by providing/overriding a translation key instead of the actual text ( e.g. for the title of service )
- by overriding the corresponding path in the fusion prototypes `Sandstorm.CookiePunch:Config.Translations` or `Sandstorm.CookiePunch:Config`

### Conditional Rendering
### Conditional Rendering of Services in Consent Modal

You can evaluate if a switch in the cookie modal should be rendered at runtime like this (only works for services):
You can evaluate if a switch in the cookie modal should be rendered at runtime like this:

```yaml
Sandstorm:
Expand Down Expand Up @@ -391,8 +391,7 @@ This is useful for multi-site setups and to prevent unnecessary consent switches
1. You need to use an eel expression that evaluates to boolean.
2. If you do not add a when condition the default is `when: ${true}`, meaning there will always be a consent switch rendered for this service
3. When querying the content repository with `q(...)`, only `site` is allowed (`documentNode` and `node` are not available)
4. If all of your when-keys of all your services evaluate to false, the cookie consent is not rendered at all
5. Klaro saves in a cookie, if a consent was given by the user in the past, so when e.g. removing and readding a youtube video, users are not asked again for cookie approval
4. Klaro saves in a cookie, if a consent was given by the user in the past, so when e.g. removing and readding a youtube video, users are not asked again for cookie approval

**Important:**

Expand Down Expand Up @@ -422,8 +421,8 @@ override the prototype like this in your project:

```neosfusion
prototype(Sandstorm.CookiePunch:Consent) {
only render if there is at least one service that has not been filtered out by its 'when' config key
@if.hasActiveServices = ${Array.length(this.activeServices) > 0}
// only render if there is at least one service that has not been filtered out by its 'when' config key
@if.hasServices = ${Array.length(this.servicesRemainingAfterWhenConditions) > 0}
}
```

Expand Down
13 changes: 7 additions & 6 deletions Resources/Private/Fusion/Consent.fusion
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
prototype(Sandstorm.CookiePunch:Consent) < prototype(Neos.Fusion:Component) {
noCSS = false

activeServices = ${ConditionalRendering.filterServicesArrayByWhenCondition(Configuration.setting("Sandstorm.CookiePunch.consent.services"), site)}
servicesRemainingAfterWhenConditions = ${CookiePunchConfig.filterServicesArrayByWhenCondition(Configuration.setting("Sandstorm.CookiePunch.consent.services"), site)}

// If you want to prevent an empty CookieConsent modal for your users if all 'when' config keys evaluate to false,
// override the prototype like this in your project:
//prototype(Sandstorm.CookiePunch:Consent) {
// only render if there is at least one service that has not been filtered out by its 'when' config key
// @if.hasActiveServices = ${Array.length(this.activeServices) > 0}
//}
//
// prototype(Sandstorm.CookiePunch:Consent) {
// only render if there is at least one service that has not been filtered out by its 'when' config key
// @if.hasServices = ${Array.length(this.servicesRemainingAfterWhenConditions) > 0}
// }

renderer = Neos.Fusion:Value {
@context.cookiePunchConfig = Sandstorm.CookiePunch:Config {
services = ${props.activeServices}
services = ${props.servicesRemainingAfterWhenConditions}
}
@context.cookiePunchConfig.@process.toJson = ${Json.stringify(value)}
@context.cookiePunch = Neos.Fusion:Case {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
use Neos\ContentRepository\Domain\Model\Workspace;
use Neos\ContentRepository\Domain\Service\Context;
use Neos\Flow\Tests\FunctionalTestCase;
use Sandstorm\CookiePunch\Eel\Helper\ConditionalServiceRendering;
use Sandstorm\CookiePunch\Eel\Helper\CookiePunchConfig;

/**
* Testcase
*/
class ConditionalServiceRenderingTest extends FunctionalTestCase
class CookiePunchConfigTest extends FunctionalTestCase
{
private Node $dummySiteNode;

Expand Down Expand Up @@ -41,7 +41,7 @@ public function initDummySiteNode() {
*/
public function validEelExpressionIsEvaluatedCorrectly()
{
$conditionalServiceRendering = new ConditionalServiceRendering();
$conditionalServiceRendering = new CookiePunchConfig();

$eelExpression = '${1 + 1 == 2}';
$actual = $conditionalServiceRendering->evaluateEelExpression($eelExpression, $this->dummySiteNode);
Expand All @@ -56,7 +56,7 @@ public function invalidEelExpressionThrowsException()
{
self::expectExceptionMessage('Invalid eel expression in CookiePunch config service block. Given: ${1 + 1 == 2');

$conditionalServiceRendering = new ConditionalServiceRendering();
$conditionalServiceRendering = new CookiePunchConfig();

$eelExpression = '${1 + 1 == 2';
$conditionalServiceRendering->evaluateEelExpression($eelExpression, $this->dummySiteNode);
Expand All @@ -69,7 +69,7 @@ public function eelExpressionThatDoesNotResolveToBoolThrowsException()
{
self::expectExceptionMessage('An eel expression was used in CookiePunch config service block that does not resolve to boolean. Given: ${"hello"}');

$conditionalServiceRendering = new ConditionalServiceRendering();
$conditionalServiceRendering = new CookiePunchConfig();

$eelExpression = '${"hello"}';
$conditionalServiceRendering->evaluateEelExpression($eelExpression, $this->dummySiteNode);
Expand All @@ -82,7 +82,7 @@ public function eelExpressionThatDoesNotResolveToBoolThrowsException()
*/
public function testIfSitenodeIsPutCorrectlyIntoContext()
{
$conditionalServiceRendering = new ConditionalServiceRendering();
$conditionalServiceRendering = new CookiePunchConfig();

$eelExpression = '${site != null}';

Expand All @@ -100,7 +100,7 @@ public function noServicePassedReturnsEmptyArray()

$expected = [];

$actual = (new ConditionalServiceRendering())->filterServicesArrayByWhenCondition($services, $this->dummySiteNode);
$actual = (new CookiePunchConfig())->filterServicesArrayByWhenCondition($services, $this->dummySiteNode);

$this->assertArraysAreEqual($expected, $actual);
}
Expand All @@ -122,7 +122,7 @@ public function aServiceWithWhenEvaluatingToTrueIsKept()
],
];

$actual = (new ConditionalServiceRendering())->filterServicesArrayByWhenCondition($services, $this->dummySiteNode);
$actual = (new CookiePunchConfig())->filterServicesArrayByWhenCondition($services, $this->dummySiteNode);

$this->assertArraysAreEqual($expected, $actual);
}
Expand All @@ -141,7 +141,7 @@ public function aServiceWithWhenEvaluatingToFalseIsRemoved()
$expected = [
];

$actual = (new ConditionalServiceRendering())->filterServicesArrayByWhenCondition($services, $this->dummySiteNode);
$actual = (new CookiePunchConfig())->filterServicesArrayByWhenCondition($services, $this->dummySiteNode);

$this->assertArraysAreEqual($expected, $actual);
}
Expand All @@ -163,7 +163,7 @@ public function aServiceWithoutAWhenExpressionIsKept()
],
];

$actual = (new ConditionalServiceRendering())->filterServicesArrayByWhenCondition($services, $this->dummySiteNode);
$actual = (new CookiePunchConfig())->filterServicesArrayByWhenCondition($services, $this->dummySiteNode);

$this->assertArraysAreEqual($expected, $actual);
}
Expand Down

0 comments on commit 3815d9b

Please sign in to comment.