Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
133 changes: 133 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
name: Tests

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

env:
PACKAGE_FOLDER: Shel.CriticalCSS

jobs:
codestyle:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.2

- name: Add additional dependencies
run: |
composer require --no-update --no-interaction neos/contentgraph-doctrinedbaladapter:"~9.0.0"

- name: Cache dependencies
uses: actions/cache@v3
with:
path: ~/.composer/cache
key: dependencies-composer-${{ hashFiles('composer.json') }}

- name: Install dependencies
uses: php-actions/composer@v6
with:
php_version: 8.2
version: 2

- name: PHPStan
uses: php-actions/phpstan@v3
with:
php_version: 8.2
version: 2.1.17
command: analyse
path: 'Classes/'

build:
runs-on: ubuntu-latest

strategy:
matrix:
php-versions:
- '8.2'
neosVersion:
- '9.0'

services:
mariadb:
# see https://mariadb.com/kb/en/mariadb-server-release-dates/
# this should be a current release, e.g. the LTS version
image: mariadb:10.8
env:
MYSQL_USER: neos
MYSQL_PASSWORD: neos
MYSQL_DATABASE: neos_functional_testing
MYSQL_ROOT_PASSWORD: neos
ports:
- "3306:3306"
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

name: 'Shel.CriticalCSS with Neos ${{ matrix.neosVersion }} test'

env:
NEOS_TARGET_VERSION: ${{matrix.neosVersion}}
FLOW_CONTEXT: Testing
FLOW_FOLDER: ../neos-base-distribution

steps:
- uses: actions/checkout@v3

- name: Set package branch name
run: echo "PACKAGE_TARGET_VERSION=${GITHUB_BASE_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_ENV
working-directory: .

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
extensions: mbstring, xml, json, zlib, iconv, intl, pdo_sqlite, mysql
tools: composer:v2

- name: Cache dependencies
uses: actions/cache@v3
with:
path: ~/.composer/cache
key: dependencies-composer-${{ hashFiles('composer.json') }}

- name: Prepare Flow distribution
run: |
git clone https://github.com/neos/neos-base-distribution.git -b ${NEOS_TARGET_VERSION} ${FLOW_FOLDER}
cd ${FLOW_FOLDER}

git -C ../${{ env.PACKAGE_FOLDER }} checkout -b build
composer config repositories.package '{ "type": "path", "url": "../${{ env.PACKAGE_FOLDER }}", "options": { "symlink": false } }'
composer require --no-update --no-interaction shel/critical-css:"dev-build as dev-${PACKAGE_TARGET_VERSION}"
composer require --no-update --no-interaction neos/contentgraph-doctrinedbaladapter:"~9.0.0"

- name: Composer Install
run: |
cd ${FLOW_FOLDER}
composer update --no-interaction --no-progress

- name: Setup Flow configuration
run: |
cd ${FLOW_FOLDER}
rm -f Configuration/Testing/Settings.yaml
cat <<EOF >> Configuration/Testing/Settings.yaml
Neos:
Flow:
persistence:
backendOptions:
host: '127.0.0.1'
driver: pdo_mysql
user: 'neos'
password: 'neos'
dbname: 'neos_functional_testing'
EOF

- name: Run Functional tests
run: |
cd ${FLOW_FOLDER}
bin/phpunit --colors -c Build/BuildEssentials/PhpUnit/FunctionalTests.xml Packages/Plugins/Shel.CriticalCSS/Tests/Functional/
6 changes: 0 additions & 6 deletions .styleci.yml

This file was deleted.

23 changes: 0 additions & 23 deletions .travis.yml

This file was deleted.

35 changes: 7 additions & 28 deletions Classes/Command/StylesCommandController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,18 @@
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Cli\CommandController;
use Neos\Flow\Mvc\ActionRequest;
use Neos\Flow\Mvc\ActionResponse;
use Neos\Flow\Mvc\Controller\Arguments;
use Neos\Flow\Mvc\Controller\ControllerContext;
use Neos\Flow\Mvc\Routing\UriBuilder;
use Neos\Flow\Security\Exception as SecurityException;
use Neos\Neos\Domain\Repository\SiteRepository;
use Shel\CriticalCSS\Fusion\FusionView;
use Shel\CriticalCSS\Service\FusionService;

/**
* The User Command Controller
*
* @Flow\Scope("singleton")
*/
#[Flow\Scope('singleton')]
class StylesCommandController extends CommandController
{
/**
* @Flow\Inject
* @var SiteRepository
*/
protected $siteRepository;

/**
* @Flow\Inject
* @var FusionService
*/
protected $fusionService;
#[Flow\Inject]
protected SiteRepository $siteRepository;

/**
* This command returns all styles for a given site node and prototype name.
Expand All @@ -56,7 +41,7 @@ public function exportCommand(string $siteNodeName, string $basePrototypeName =
}

$fusionView = new FusionView();
$fusionView->setControllerContext($this->createSimpleControllerContext());
$fusionView->assign('request', $this->createSimpleControllerRequest());
$fusionView->setFusionPath('shelCriticalStyles');
$fusionView->setPackageKey($site->getSiteResourcesPackageKey());
$fusionView->assign('site', $site->getNodeName());
Expand All @@ -65,17 +50,11 @@ public function exportCommand(string $siteNodeName, string $basePrototypeName =
}

/**
* Create a simple controller context which can be used to instantiate a Fusion runtime etc.
* Create a simple controller context which can be used to instantiate a Fusion runtime, etc.
*/
protected function createSimpleControllerContext(): ControllerContext
protected function createSimpleControllerRequest(): ActionRequest
{
$httpRequest = new ServerRequest('POST', 'http://localhost');
$request = ActionRequest::fromHttpRequest($httpRequest);
$response = new ActionResponse();
$arguments = new Arguments([]);
$uriBuilder = new UriBuilder();
$uriBuilder->setRequest($request);

return new ControllerContext($request, $response, $arguments, $uriBuilder);
return ActionRequest::fromHttpRequest($httpRequest);
}
}
55 changes: 28 additions & 27 deletions Classes/Fusion/FusionView.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Mvc\Exception;
use Neos\Flow\Security\Exception as SecurityException;
use Neos\FluidAdaptor\View\TemplateView;
use Neos\Fusion\Core\FusionConfiguration;
use Neos\Fusion\Core\FusionGlobals;
use Neos\Fusion\View\FusionView as BaseFusionView;
use Neos\Fusion\Core\Runtime as FusionRuntime;
use Shel\CriticalCSS\Service\FusionService;
Expand All @@ -20,55 +21,52 @@
*/
class FusionView extends BaseFusionView
{
protected $styleRenderPath = 'shelCriticalStyles';
protected string $styleRenderPath = 'shelCriticalStyles';

/**
* @Flow\Inject
* @var FusionService
*/
protected $fusionService;

/**
* @Flow\Inject
* @var TemplateView
*/
protected $fallbackView;
#[Flow\Inject]
protected FusionService $fusionService;

/**
* @inheritDoc
* @throws Exception
*/
protected function loadFusion(): void
{
$fusionAst = [];
try {
$fusionAst = $this->fusionService->getMergedFusionObjectTreeForSitePackage($this->getOption('packageKey'));
} catch (Exception $e) {
}
$fusionAst = $this->fusionService->getFusionConfigurationForSitePackage(
$this->getOption('packageKey')
);
$this->parsedFusion = $fusionAst;
}

/**
* Iterates through the Fusion AST and renders all instantiated
* objects of the given prototype and returns the concatenated results as string.
*
* @param string $stylePrototypeName
* @return string
* @throws SecurityException
*/
public function renderStyles(string $stylePrototypeName): string
{
/** @noinspection PhpConditionAlreadyCheckedInspection */
/** @phpstan-ignore booleanNot.alwaysFalse */
if (!$this->parsedFusion) {
$this->loadFusion();
try {
$this->loadFusion();
} catch (Exception) {
return '';
}
}
$fusionAst = $this->parsedFusion->toArray();
$prototypes = $fusionAst['__prototypes'] ?? [];

if (!$prototypes) {
return '';
}
$fusionAst = $this->parsedFusion;
$prototypes = $fusionAst['__prototypes'];

$arrayIterator = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($fusionAst));
$outputArray = [];
/** @noinspection PhpUnusedLocalVariableInspection */
foreach ($arrayIterator as $sub) {
$subArray = $arrayIterator->getSubIterator();
/** @noinspection PhpParamsInspection */
$subArray = iterator_to_array($arrayIterator->getSubIterator());
if (!array_key_exists('__objectType', $subArray)) {
continue;
}
Expand All @@ -77,7 +75,7 @@ public function renderStyles(string $stylePrototypeName): string
($prototypeName
&& array_key_exists($prototypeName, $prototypes)
&& array_key_exists('__prototypeChain', $prototypes[$prototypeName])
&& in_array($stylePrototypeName, $prototypes[$prototypeName]['__prototypeChain']))) {
&& in_array($stylePrototypeName, $prototypes[$prototypeName]['__prototypeChain'], true))) {
$props = iterator_to_array($subArray);
$props['__meta']['stylesOnly'] = true;
$outputArray[] = $props;
Expand All @@ -89,7 +87,10 @@ public function renderStyles(string $stylePrototypeName): string
// Render each found instantiated prototype
foreach ($outputArray as $props) {
$fusionAst[$this->styleRenderPath] = $props;
$fusionRuntime = new FusionRuntime($fusionAst, $this->controllerContext);
$fusionGlobals = FusionGlobals::fromArray(array_filter([
'request' => $this->assignedActionRequest,
]));
$fusionRuntime = new FusionRuntime(FusionConfiguration::fromArray($fusionAst), $fusionGlobals);
$fusionRuntime->pushContextArray($this->variables);
$output .= $fusionRuntime->render($this->styleRenderPath);
$fusionRuntime->popContext();
Expand Down
15 changes: 3 additions & 12 deletions Classes/FusionObjects/LoadStylesImplementation.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

declare(strict_types=1);

namespace Shel\CriticalCSS\FusionObjects;
Expand All @@ -17,8 +18,6 @@ class LoadStylesImplementation extends AbstractFusionObject
{
/**
* HTML content that should be processed (optional)
*
* @return string|null
*/
protected function getContent(): ?string
{
Expand All @@ -27,22 +26,17 @@ protected function getContent(): ?string

/**
* Path to a CSS resource
*
* @return string
*/
protected function getPath(): string
{
return $this->fusionValue('path');
}

/**
* @return string
*/
public function evaluate(): string
{
try {
$styles = $this->loadResourceContent($this->getPath());
} catch (InvalidVariableException $e) {
} catch (InvalidVariableException) {
throw new \InvalidArgumentException('Resource ' . $this->getPath() . ' cannot be loaded!', 1573314641);
}

Expand All @@ -51,16 +45,13 @@ public function evaluate(): string

/**
* Loads the content of a resource and returns it as string
*
* @return string Content of the resource
* @throws InvalidVariableException
*/
public function loadResourceContent(?string $path): string
{
if ($path === null) {
throw new InvalidVariableException('You have to define a path.', 1573317165);
}

return file_get_contents($path);
return file_get_contents($path) ?: '';
}
}
Loading