Skip to content

Commit

Permalink
EZP-31825: Fixed crashes when ezcontentquery field parameters are inv…
Browse files Browse the repository at this point in the history
…alid (#48)
  • Loading branch information
Steveb-p authored Oct 20, 2020
1 parent d527c77 commit 2287500
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 1 deletion.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"symfony/framework-bundle": "^5.0",
"symfony/http-kernel": "^5.0",
"symfony/translation": "^5.0",
"symfony/yaml": "^5.0"
"symfony/yaml": "^5.0",
"psr/log": "^1.1"
},
"autoload": {
"psr-4": {
Expand Down
55 changes: 55 additions & 0 deletions spec/API/ExceptionSafeQueryFieldServiceSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
namespace spec\EzSystems\EzPlatformQueryFieldType\API;

use eZ\Publish\Core\Repository\Values\Content\Content;
use EzSystems\EzPlatformQueryFieldType\API\ExceptionSafeQueryFieldService;
use EzSystems\EzPlatformQueryFieldType\API\QueryFieldServiceInterface;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;

class ExceptionSafeQueryFieldServiceSpec extends ObjectBehavior
{
function let(QueryFieldServiceInterface $queryFieldService)
{
$arguments = [
Argument::type(Content::class),
Argument::type('string'),
];
$queryFieldService->countContentItems(...$arguments)->willThrow('Exception');
$queryFieldService->loadContentItems(...$arguments)->willThrow('Exception');

$arguments[] = Argument::type('int');
$arguments[] = Argument::type('int');
$queryFieldService->loadContentItemsSlice(...$arguments)->willThrow('Exception');

$this->beConstructedWith($queryFieldService);
}

function it_is_initializable()
{
$this->shouldHaveType(ExceptionSafeQueryFieldService::class);
}

function it_should_return_empty_results_on_count_content_items()
{
$result = $this->countContentItems(new Content([]), 'any');
$result->shouldBe(0);
}

function it_should_return_empty_results_on_load_content_items()
{
$result = $this->loadContentItems(new Content([]), 'any');
$result->shouldBe([]);
}

function it_should_return_empty_results_on_load_content_items_slice()
{
$result = $this->loadContentItemsSlice(new Content([]), 'any', 0, 5);
$result->shouldBe([]);
}
}
74 changes: 74 additions & 0 deletions src/API/ExceptionSafeQueryFieldService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
namespace EzSystems\EzPlatformQueryFieldType\API;

use eZ\Publish\API\Repository\Values\Content\Content;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;

/**
* Silences exceptions when they occur in query field service, for example due to field type misconfigurations.
*/
final class ExceptionSafeQueryFieldService implements QueryFieldServiceInterface, LoggerAwareInterface
{
use LoggerAwareTrait;

/** @var QueryFieldServiceInterface */
private $inner;

public function __construct(QueryFieldServiceInterface $inner, ?LoggerInterface $logger = null)
{
$this->inner = $inner;
$this->logger = $logger ?: new NullLogger();
}

public function loadContentItems(Content $content, string $fieldDefinitionIdentifier): iterable
{
try {
return $this->inner->loadContentItems($content, $fieldDefinitionIdentifier);
} catch (\Throwable $e) {
$this->logger->error($e->getMessage(), [
'exception' => $e,
]);

return [];
}
}

public function countContentItems(Content $content, string $fieldDefinitionIdentifier): int
{
try {
return $this->inner->countContentItems($content, $fieldDefinitionIdentifier);
} catch (\Throwable $e) {
$this->logger->error($e->getMessage(), [
'exception' => $e,
]);

return 0;
}
}

public function loadContentItemsSlice(Content $content, string $fieldDefinitionIdentifier, int $offset, int $limit): iterable
{
try {
return $this->inner->loadContentItemsSlice($content, $fieldDefinitionIdentifier, $offset, $limit);
} catch (\Throwable $e) {
$this->logger->error($e->getMessage(), [
'exception' => $e,
]);

return [];
}
}

public function getPaginationConfiguration(Content $content, string $fieldDefinitionIdentifier): int
{
return $this->inner->getPaginationConfiguration($content, $fieldDefinitionIdentifier);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public function load(array $configs, ContainerBuilder $container)

$loader->load('default_parameters.yaml');
$loader->load('services.yaml');
if (!$container->hasParameter('kernel.debug') || !$container->getParameter('kernel.debug')) {
$loader->load('prod/services.yaml');
}

$this->addContentViewConfig($container);
}
Expand Down
8 changes: 8 additions & 0 deletions src/Symfony/Resources/config/prod/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:
_defaults:
autoconfigure: true
autowire: true
public: true

EzSystems\EzPlatformQueryFieldType\API\ExceptionSafeQueryFieldService:
decorates: 'EzSystems\EzPlatformQueryFieldType\API\QueryFieldServiceInterface'

0 comments on commit 2287500

Please sign in to comment.