data-hub icon indicating copy to clipboard operation
data-hub copied to clipboard

[Bug]: datahub_context runtime cache value is reset by Pimcore\Model\Version::loadData

Open ThisIsJustARandomGuy opened this issue 2 years ago • 1 comments

Expected behavior

Either the runtime cache value datahub_context should not get reset by loading version data or the datahub implementation should not rely on the value being available (see #465).

Actual behavior

An exception No entry is registered for key 'datahub_context' is raised because of these lines in Pimcore\Model\Version:

//clear runtime cache to avoid dealing with marshalled data
Runtime::clear();

A quick, but ugly workaround would be to replace the second line with this:

Runtime::clear(['datahub_context']);

Steps to reproduce

In a custom resolver, call Pimcore\Model\Version::loadData() on a Version of any Document.

For a very quick repro this would do the trick, I think. But I couldn't verify for now:

<?php
namespace App\EventSubscriber;

use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Type\Definition\Type;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\QueryTypeEvent;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\QueryEvents;
use Pimcore\Bundle\DataHubBundle\GraphQL\Resolver\QueryType;
use Pimcore\Bundle\DataHubBundle\GraphQL\Service;
use Pimcore\Cache\Runtime;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

class QueryEventSubscriber implements EventSubscriberInterface
{
    protected EventDispatcherInterface $eventDispatcher;

    public function __construct(EventDispatcherInterface $eventDispatcher)
    {
        $this->eventDispatcher = $eventDispatcher;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            QueryEvents::POST_BUILD => 'onPostBuild'
        ];
    }

    public function onPostBuild(QueryTypeEvent $event)
    {
        $graphQlService = $event->getQueryType()->getGraphQlService();

        $documentResolver = new LatestVersionQueryType($this->eventDispatcher);
        $documentResolver->setGraphQlService($graphQlService);

        $config['fields']['getDocument']['resolve'] = function($value = null, $args = [], $context = [], ResolveInfo $resolveInfo = null) use($documentResolver) {
            $document = $documentResolver->resolveDocumentGetter();

            $version = $document?->getLatestVersion();
            if( $version instanceof Version ) {
                // This triggers the bug, no need to return the Version.
                // Runtime::get('datahub_context') fails from this point onwards (i.e. when loading children)
                $version->loadData();
            }
            
            return $document;
        };

        $event->setConfig($config);
    }
}

Now, running a getDocument query which, for example, loads the children, should produce the error. Again, I've not yet had time to test this but I hope it's clear what the issue is.

query {
    getDocument(id: 1) {
        id
        children {
            __typename
        }
    }
}

Related issues: #465 #546,

ThisIsJustARandomGuy avatar Jul 12 '22 12:07 ThisIsJustARandomGuy