Skip to content

Commit

Permalink
TASK: 8.3 upmerges
Browse files Browse the repository at this point in the history
  • Loading branch information
dlubitz committed Feb 23, 2024
2 parents ff4fc2d + 68e2adf commit 0dd886c
Show file tree
Hide file tree
Showing 17 changed files with 119 additions and 49 deletions.
17 changes: 0 additions & 17 deletions Neos.Flow/Classes/Cache/CacheFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@ class CacheFactory extends \Neos\Cache\CacheFactory
*/
protected $context;

/**
* A reference to the cache manager
*
* @var CacheManager
*/
protected $cacheManager;

/**
* @var Environment
*/
Expand All @@ -55,16 +48,6 @@ class CacheFactory extends \Neos\Cache\CacheFactory
*/
protected $environmentConfiguration;

/**
* @param CacheManager $cacheManager
*
* @Flow\Autowiring (enabled=false)
*/
public function injectCacheManager(CacheManager $cacheManager): void
{
$this->cacheManager = $cacheManager;
}

/**
* @param EnvironmentConfiguration $environmentConfiguration
*
Expand Down
8 changes: 5 additions & 3 deletions Neos.Flow/Classes/Cache/CacheManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* source code.
*/

use Neos\Cache\CacheFactoryInterface;
use Neos\Flow\Annotations as Flow;
use Neos\Cache\Backend\FileBackend;
use Neos\Cache\Exception\DuplicateIdentifierException;
Expand All @@ -37,7 +38,7 @@
class CacheManager
{
/**
* @var CacheFactory
* @var CacheFactoryInterface
*/
protected $cacheFactory;

Expand Down Expand Up @@ -100,10 +101,10 @@ public function injectLogger(LoggerInterface $logger)
}

/**
* @param CacheFactory $cacheFactory
* @param CacheFactoryInterface $cacheFactory
* @return void
*/
public function injectCacheFactory(CacheFactory $cacheFactory): void
public function injectCacheFactory(CacheFactoryInterface $cacheFactory): void
{
$this->cacheFactory = $cacheFactory;
}
Expand Down Expand Up @@ -496,6 +497,7 @@ protected function createCache(string $identifier): void
$backend = isset($this->cacheConfigurations[$identifier]['backend']) ? $this->cacheConfigurations[$identifier]['backend'] : $this->cacheConfigurations['Default']['backend'];
$backendOptions = isset($this->cacheConfigurations[$identifier]['backendOptions']) ? $this->cacheConfigurations[$identifier]['backendOptions'] : $this->cacheConfigurations['Default']['backendOptions'];
$persistent = isset($this->cacheConfigurations[$identifier]['persistent']) ? $this->cacheConfigurations[$identifier]['persistent'] : $this->cacheConfigurations['Default']['persistent'];
// @phpstan-ignore-next-line - $persistent is not yet part of the CacheFactoryInterface
$cache = $this->cacheFactory->create($identifier, $frontend, $backend, $backendOptions, $persistent);
$this->registerCache($cache, $persistent);
}
Expand Down
22 changes: 17 additions & 5 deletions Neos.Flow/Classes/Core/Booting/Scripts.php
Original file line number Diff line number Diff line change
Expand Up @@ -356,10 +356,22 @@ public static function initializeCacheManagement(Bootstrap $bootstrap)
$configurationManager = $bootstrap->getEarlyInstance(ConfigurationManager::class);
$environment = $bootstrap->getEarlyInstance(Environment::class);

$cacheFactoryObjectConfiguration = $configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_OBJECTS, CacheFactoryInterface::class);
$cacheFactoryClass = isset($cacheFactoryObjectConfiguration['className']) ? $cacheFactoryObjectConfiguration['className'] : CacheFactory::class;
/**
* Workaround to find the correct CacheFactory implementation at compile time.
* We can rely on the $objectConfiguration being ordered by the package names after their loading order.
* The object manager _does_ even know that at a later step in compile time: {@see CompileTimeObjectManager::getClassNameByObjectName()}
* But at this time it is not available. https://github.com/neos/flow-development-collection/issues/3317
*/
$cacheFactoryClass = CacheFactory::class;
$cacheFactoryObjectConfiguration = $configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_OBJECTS);
foreach ($cacheFactoryObjectConfiguration as $objectConfiguration) {
if (isset($objectConfiguration[CacheFactoryInterface::class]['className'])) {
// use the implementation of the package with the highest loading order
$cacheFactoryClass = $objectConfiguration[CacheFactoryInterface::class]['className'];
}
}

/** @var CacheFactory $cacheFactory */
/** @var CacheFactoryInterface $cacheFactory */
$cacheFactory = new $cacheFactoryClass($bootstrap->getContext(), $environment, $configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Neos.Flow.cache.applicationIdentifier'));

$cacheManager = new CacheManager();
Expand All @@ -369,8 +381,6 @@ public static function initializeCacheManagement(Bootstrap $bootstrap)
$cacheManager->injectEnvironment($environment);
$cacheManager->injectCacheFactory($cacheFactory);

$cacheFactory->injectCacheManager($cacheManager);

$bootstrap->setEarlyInstance(CacheManager::class, $cacheManager);
$bootstrap->setEarlyInstance(CacheFactory::class, $cacheFactory);
}
Expand Down Expand Up @@ -861,6 +871,7 @@ protected static function ensureCLISubrequestsUseCurrentlyRunningPhpBinary($phpB
$command[] = '2>&1'; // Output errors in response

// Try to resolve which binary file PHP is pointing to
$output = [];
exec(join(' ', $command), $output, $result);

if ($result === 0 && count($output) === 1) {
Expand All @@ -883,6 +894,7 @@ protected static function ensureCLISubrequestsUseCurrentlyRunningPhpBinary($phpB
$realPhpBinary = @realpath(PHP_BINARY);
if ($realPhpBinary === false) {
// bypass with exec open_basedir restriction
$output = [];
exec(PHP_BINARY . ' -r "echo realpath(PHP_BINARY);"', $output);
$realPhpBinary = $output[0];
}
Expand Down
14 changes: 10 additions & 4 deletions Neos.Flow/Classes/Error/DebugExceptionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,17 @@ protected function renderStatically(int $statusCode, \Throwable $exception)
while (true) {
$filepaths = Debugger::findProxyAndShortFilePath($exception->getFile());
$filePathAndName = $filepaths['proxy'] !== '' ? $filepaths['proxy'] : $filepaths['short'];
$exceptionMessageParts = $this->splitExceptionMessage($exception->getMessage());

$exceptionHeader .= '<h1 class="ExceptionSubject">' . htmlspecialchars($exceptionMessageParts['subject']) . '</h1>';
if ($exceptionMessageParts['body'] !== '') {
$exceptionHeader .= '<p class="ExceptionBody">' . nl2br(htmlspecialchars($exceptionMessageParts['body'])) . '</p>';
['subject' => $exceptionMessageSubject, 'body' => $exceptionMessageBody] = $this->splitExceptionMessage($exception->getMessage());

$exceptionHeader .= '<h1 class="ExceptionSubject">' . htmlspecialchars($exceptionMessageSubject) . '</h1>';
if ($exceptionMessageBody !== '') {
if (str_contains($exceptionMessageBody, ' ')) {
// contents with multiple spaces will be pre-served
$exceptionHeader .= '<p class="ExceptionBodyPre">' . htmlspecialchars($exceptionMessageBody) . '</p>';
} else {
$exceptionHeader .= '<p class="ExceptionBody">' . nl2br(htmlspecialchars($exceptionMessageBody)) . '</p>';
}
}

$exceptionHeader .= '<table class="Flow-Debug-Exception-Meta"><tbody>';
Expand Down
11 changes: 2 additions & 9 deletions Neos.Flow/Classes/Mvc/Controller/ActionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
use Neos\Flow\Property\Exception\TargetNotFoundException;
use Neos\Flow\Property\TypeConverter\Error\TargetNotFoundError;
use Neos\Flow\Reflection\ReflectionService;
use Neos\Flow\Security\Exception\InvalidArgumentForHashGenerationException;
use Neos\Flow\Security\Exception\InvalidHashException;
use Neos\Utility\TypeHandling;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
Expand Down Expand Up @@ -229,13 +227,8 @@ public function processRequest(ActionRequest $request, ActionResponse $response)
if (method_exists($this, $actionInitializationMethodName)) {
call_user_func([$this, $actionInitializationMethodName]);
}
try {
$this->mvcPropertyMappingConfigurationService->initializePropertyMappingConfigurationFromRequest($this->request, $this->arguments);
} catch (InvalidArgumentForHashGenerationException|InvalidHashException $e) {
$message = $this->throwableStorage->logThrowable($e);
$this->logger->notice('Property mapping configuration failed due to HMAC errors. ' . $message, LogEnvironment::fromMethodName(__METHOD__));
$this->throwStatus(400, null, 'Invalid HMAC submitted');
}

$this->mvcPropertyMappingConfigurationService->initializePropertyMappingConfigurationFromRequest($this->request, $this->arguments);

try {
$this->mapRequestArgumentsToControllerArguments();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class Configuration
*/
public function __construct($objectName, $className = null)
{
$backtrace = debug_backtrace();
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
if (isset($backtrace[1]['object'])) {
$this->configurationSourceHint = get_class($backtrace[1]['object']);
} elseif (isset($backtrace[1]['class'])) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public function canConvertFrom($source, $targetType)
return false;
}
$methodParameter = array_shift($methodParameters);
return TypeHandling::normalizeType($methodParameter['type']) === gettype($source);
return TypeHandling::normalizeType($methodParameter['type']) === TypeHandling::normalizeType(gettype($source));
}

/**
Expand Down
7 changes: 6 additions & 1 deletion Neos.Flow/Classes/Reflection/ReflectionService.php
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,12 @@ public function reflectClassProperty(string $className, PropertyReflection $prop
if ($this->isAttributeIgnored($attribute->getName())) {
continue;
}
$this->classReflectionData[$className][self::DATA_CLASS_PROPERTIES][$propertyName][self::DATA_PROPERTY_ANNOTATIONS][$attribute->getName()][] = $attribute->newInstance();
try {
$attributeInstance = $attribute->newInstance();
} catch (\Error $error) {
throw new \RuntimeException(sprintf('Attribute "%s" used in class "%s" was not found.', $attribute->getName(), $className), 1695635128, $error);
}
$this->classReflectionData[$className][self::DATA_CLASS_PROPERTIES][$propertyName][self::DATA_PROPERTY_ANNOTATIONS][$attribute->getName()][] = $attributeInstance;
}
}

Expand Down
5 changes: 5 additions & 0 deletions Neos.Flow/Configuration/Development/Settings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ Neos:
defaultRenderingOptions:
renderTechnicalDetails: true

renderingGroups:
noStacktraceExceptionGroup:
options:
logException: true

errorHandler:
exceptionalErrors: ['%E_USER_ERROR%', '%E_RECOVERABLE_ERROR%', '%E_WARNING%', '%E_NOTICE%', '%E_USER_WARNING%', '%E_USER_NOTICE%', '%E_STRICT%']

Expand Down
9 changes: 8 additions & 1 deletion Neos.Flow/Configuration/Settings.Error.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ Neos:
variables:
errorDescription: 'Sorry, the database connection couldn''t be established.'

noStacktraceExceptionGroup:
matchingExceptionClassNames: ['Neos\Flow\Security\Exception\InvalidHashException']
options:
logException: false
templatePathAndFilename: 'resource://Neos.Flow/Private/Templates/Error/Default.html'
variables:
errorDescription: 'Sorry, something went wrong.'

errorHandler:

# Defines which errors should result in an exception thrown - all other error
Expand Down Expand Up @@ -73,4 +81,3 @@ Neos:

# Maximal recursion for the debugger
recursionLimit: 5

4 changes: 2 additions & 2 deletions Neos.Flow/Configuration/Settings.Log.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Neos:
optionsByImplementation:
'Neos\Flow\Log\ThrowableStorage\FileStorage':
storagePath: '%FLOW_PATH_DATA%Logs/Exceptions'
# The maximum age of throwable dump in seconds, 0 to disable cleaning based on age, default 30 days
# The maximum age of throwable dump in seconds, 0 to disable cleaning based on age
maximumThrowableDumpAge: 2592000
# The maximum number of throwable dumps to store, 0 to disable cleaning based on count, default 10.000
# The maximum number of throwable dumps to store, 0 to disable cleaning based on count
maximumThrowableDumpCount: 10000
4 changes: 2 additions & 2 deletions Neos.Flow/Documentation/TheDefinitiveGuide/PartIII/Http.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ that defines the ``process($request, $next)`` method::
*/
final class SomeMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface;
$response = $next->handle($httpRequest);
public function process(ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface {
$response = $next->handle($request);
return $response->withAddedHeader('X-MyHeader', '123');
}
}
Expand Down
8 changes: 8 additions & 0 deletions Neos.Flow/Resources/Public/Error/Exception.css
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ h1, h2, h3 {
color: #000000;
}

.ExceptionBodyPre {
padding: 10px;
margin: 10px;
color: #000000;
white-space: pre;
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
}

.ExceptionProperty {
color: #34363C;
}
Expand Down
2 changes: 0 additions & 2 deletions Neos.Flow/Tests/Unit/Cache/CacheFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,7 @@ public function createInjectsAnInstanceOfTheSpecifiedBackendIntoTheCacheFrontend
*/
public function aDifferentDefaultCacheDirectoryIsUsedForPersistentFileCaches()
{
$cacheManager = new CacheManager();
$factory = new CacheFactory(new ApplicationContext('Testing'), $this->mockEnvironment, 'UnitTesting');
$factory->injectCacheManager($cacheManager);
$factory->injectEnvironmentConfiguration($this->mockEnvironmentConfiguration);

$cache = $factory->create('Persistent_Cache', VariableFrontend::class, FileBackend::class, [], true);
Expand Down
33 changes: 33 additions & 0 deletions Neos.Flow/Tests/Unit/Fixtures/ClassWithFloatConstructor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
namespace Neos\Flow\Fixtures;

/*
* This file is part of the Neos.Flow 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.
*/

/**
* A value object (POPO) with one constructor argument (float)
*/
class ClassWithFloatConstructor
{
/**
* @var float
*/
public $value;

/**
* ClassWithFloatConstructor constructor.
*
* @param float $value
*/
public function __construct(float $value)
{
$this->value = $value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
class ClassWithIntegerConstructor
{
/**
* @var string
* @var int
*/
public $value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
require_once(__DIR__ . '/../../Fixtures/ClassWithBoolConstructor.php');

use Neos\Flow\Fixtures\ClassWithBoolConstructor;
use Neos\Flow\Fixtures\ClassWithFloatConstructor;
use Neos\Flow\Fixtures\ClassWithIntegerConstructor;
use Neos\Flow\Fixtures\ClassWithStringConstructor;
use Neos\Flow\Property\TypeConverter\ScalarTypeToObjectConverter;
Expand Down Expand Up @@ -108,4 +109,21 @@ public function canConvertFromIntegerToValueObject()
$canConvert = $converter->canConvertFrom(42, ClassWithIntegerConstructor::class);
self::assertTrue($canConvert);
}

/**
* @test
*/
public function canConvertFromFloatToValueObject()
{
$converter = new ScalarTypeToObjectConverter();

$this->reflectionMock->expects(self::once())
->method('getMethodParameters')
->willReturn([[
'type' => 'float'
]]);
$this->inject($converter, 'reflectionService', $this->reflectionMock);
$canConvert = $converter->canConvertFrom(4.2, ClassWithFloatConstructor::class);
self::assertTrue($canConvert);
}
}

0 comments on commit 0dd886c

Please sign in to comment.