Skip to content

Commit

Permalink
Merge pull request #73 from pimcore/events
Browse files Browse the repository at this point in the history
 Add events for Query & Mutation
  • Loading branch information
weisswurstkanone authored Jul 5, 2019
2 parents 2d56b21 + 176c424 commit c61fe50
Show file tree
Hide file tree
Showing 14 changed files with 730 additions and 30 deletions.
6 changes: 5 additions & 1 deletion doc/GraphQL.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,8 @@ to do that for all definitions, or
datahub:graphql:rebuild-definitions --definitions=newsapp,otherendpoint
```

for specific definitions.
for specific definitions.

## Events

See [Events Documentation](./graphl/Events.md)
110 changes: 110 additions & 0 deletions doc/graphl/Events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#Events

DataHub GraphQL events are based on symfony event dispatcher, which are triggered during execution of Query and Mutation requests.
[Read more](https://github.com/pimcore/pimcore/blob/master/doc/Development_Documentation/20_Extending_Pimcore/11_Event_API_and_Event_Manager.md) about events on Pimcore documentation.

All DataHub events are defined as a constant on component classes:
- [Query](https://github.com/pimcore/data-hub/blob/master/src/Event/GraphQL\QueryEvents.php)
- [Mutation](https://github.com/pimcore/data-hub/blob/master/src/Event/GraphQL\MutationEvents.php)
- [Executor](https://github.com/pimcore/data-hub/blob/master/src/Event/GraphQL\ExecutorEvents.php)

## Event Listener examples

Add configuration in your `app/config/services.yml`:
```yml
services:
AppBundle\EventListener\GraphQlListener:
tags:
- { name: kernel.event_listener}
```
Add Listener class `src/AppBundle/EventListener/GraphQlListener`

#### Example 1: Query & Mutation execution
```php
<?php
namespace AppBundle\EventListener;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\ExecutorEvents;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\ExecutorEvent;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\ExecutorResultEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class GraphQlListener implements EventSubscriberInterface
{
/**
* @inheritDoc
*/
public static function getSubscribedEvents()
{
return [
ExecutorEvents::PRE_EXECUTE => 'onPreExecute', //Pre execute on Query & Mutation
ExecutorEvents::POST_EXECUTE => 'onPostExecute' //Post execute on Query & Mutation
];
}
/**
* @param ExecutorEvent $event
*/
public function onPreExecute(ExecutorEvent $event)
{
// do something with the query or schema
$query = $event->getQuery();
$schema = $event->getSchema();
}
/**
* @param ExecutorResultEvent $event
*/
public function onPostExecute(ExecutorResultEvent $event)
{
// do something with output result
$result = $event->getResult();
}
}
```

#### Example 2: Bypass workspace permissions with Query/Mutation build events
```php
<?php
namespace AppBundle\EventListener;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\MutationEvents;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\MutationTypeEvent;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\QueryTypeEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class GraphqlListener implements EventSubscriberInterface
{
/**
* @inheritDoc
*/
public static function getSubscribedEvents()
{
return [
MutationEvents::PRE_BUILD => 'onMutationPreBuild',
QueryEvents::PRE_BUILD => 'onQueryPreBuild'
];
}
/**
* @param ExecutorEvent $event
*/
public function onMutationPreBuild(MutationTypeEvent $event)
{
$mutationType = $event->getMutationType();
$mutationType->setOmitPermissionCheck(true); //omit permission check for mutations
}
/**
* @param ExecutorResultEvent $event
*/
public function onQueryPreBuild(QueryTypeEvent $event)
{
$queryType = $event->getQueryType();
$queryType->setOmitPermissionCheck(true); //omit permission check for queries
}
}
```
40 changes: 35 additions & 5 deletions src/Controller/WebserviceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
use GraphQL\Error\Warning;
use GraphQL\GraphQL;
use Pimcore\Bundle\DataHubBundle\Configuration;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\ExecutorEvents;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\ExecutorEvent;
use Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\ExecutorResultEvent;
use Pimcore\Bundle\DataHubBundle\GraphQL\ClassTypeDefinitions;
use Pimcore\Bundle\DataHubBundle\GraphQL\Mutation\MutationType;
use Pimcore\Bundle\DataHubBundle\GraphQL\Query\QueryType;
Expand All @@ -29,13 +32,27 @@
use Pimcore\Localization\LocaleServiceInterface;
use Pimcore\Logger;
use Pimcore\Model\Factory;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

class WebserviceController extends FrontendController
{
/**
* @var EventDispatcherInterface
*/
private $eventDispatcher;

/**
* @param EventDispatcherInterface $eventDispatcher
*/
public function __construct(EventDispatcherInterface $eventDispatcher)
{
$this->eventDispatcher = $eventDispatcher;
}

/**
* @param Service $service
* @param LocaleServiceInterface $localeService
Expand Down Expand Up @@ -69,8 +86,8 @@ public function webonyxAction(Service $service, LocaleServiceInterface $localeSe

ClassTypeDefinitions::build($service, $context);

$queryType = new QueryType($service, $localeService, $modelFactory, [], $context);
$mutationType = new MutationType($service, $localeService, $modelFactory, [], $context);
$queryType = new QueryType($service, $localeService, $modelFactory, $this->eventDispatcher, [], $context);
$mutationType = new MutationType($service, $localeService, $modelFactory, $this->eventDispatcher, [], $context);


try {
Expand Down Expand Up @@ -112,18 +129,31 @@ public function webonyxAction(Service $service, LocaleServiceInterface $localeSe
];
}

$result = GraphQL::executeQuery(
$schema,
$event = new ExecutorEvent(
$request,
$query,
$schema,
$context);

$this->eventDispatcher->dispatch(ExecutorEvents::PRE_EXECUTE, $event);

$result = GraphQL::executeQuery(
$event->getSchema(),
$event->getQuery(),
$rootValue,
$context,
$event->getContext(),
$variableValues,
null,
null,
$validators

);

$exResult = new ExecutorResultEvent($request, $result);
$this->eventDispatcher->dispatch(ExecutorEvents::POST_EXECUTE,
$exResult);
$result = $exResult->getResult();

if (PIMCORE_DEBUG) {
$debug = Debug::INCLUDE_DEBUG_MESSAGE | Debug::INCLUDE_TRACE | Debug::RETHROW_INTERNAL_EXCEPTIONS;
$output = $result->toArray($debug);
Expand Down
32 changes: 32 additions & 0 deletions src/Event/GraphQL/ExecutorEvents.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php
/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Enterprise License (PEL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PEL
*/

namespace Pimcore\Bundle\DataHubBundle\Event\GraphQL;

final class ExecutorEvents
{
/**
* @Event("Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\ExecutorEvent")
*
* @var string
*/
const PRE_EXECUTE = 'pimcore.datahub.graphql.executor.preExecute';

/**
* @Event("Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model\ExecutorResultEvent")
*
* @var string
*/
const POST_EXECUTE = 'pimcore.datahub.graphql.executor.postExecute';
}
125 changes: 125 additions & 0 deletions src/Event/GraphQL/Model/ExecutorEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php
/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Enterprise License (PEL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PEL
*/

namespace Pimcore\Bundle\DataHubBundle\Event\GraphQL\Model;

use GraphQL\Type\Schema;
use Pimcore\Event\Traits\RequestAwareTrait;
use Pimcore\Event\Traits\ResponseAwareTrait;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\Request;

class ExecutorEvent extends Event
{
use RequestAwareTrait;
use ResponseAwareTrait;

/**
* @var string
*/
protected $request;

/**
* @var string
*/
protected $query;

/**
* @var Schema
*/
protected $schema;

/**
* @var array
*/
protected $context;

/**
* @return string
*/
public function getRequest()
{
return $this->request;
}

/**
* @param string $request
*/
public function setRequest(string $request)
{
$this->request = $request;
}

/**
* @return Schema
*/
public function getSchema()
{
return $this->schema;
}

/**
* @param Schema $schema
*/
public function setSchema(Schema $schema)
{
$this->schema = $schema;
}

/**
* @return array
*/
public function getContext()
{
return $this->context;
}

/**
* @param array $context
*/
public function setContext(array $context)
{
$this->context = $context;
}

/**
* @return string
*/
public function getQuery()
{
return $this->query;
}

/**
* @param string $query
*/
public function setQuery($query)
{
$this->query = $query;
}

/**
* @param Request $request
* @param array $query
* @param Schema $schema
* @param array $context
*/
public function __construct(Request $request, $query, Schema $schema, $context)
{
$this->request = $request;
$this->query = $query;
$this->schema = $schema;
$this->context = $context;
}
}
Loading

0 comments on commit c61fe50

Please sign in to comment.