Skip to content

Workflow component should allow to check if object has a workflow defined #34584

@Steveb-p

Description

@Steveb-p

Description
Currently Symfony\Component\Workflow\Registry allows one to get a workflow associated with an object, but throws an exception if there is none.

In my case, I'd like to create a Normalizer for all my objects that have a workflow to add additional data to them. However, this check requires me to either mark all entities with workflow enabled with an additional interface (which is fine for me as a workaround) or accept the cost of creating exceptions all the time.

Example
I've got a Normalizer class:

<?php declare(strict_types=1);

namespace App\Serializer\Normalizer;

use ApiPlatform\Core\JsonLd\Serializer\ItemNormalizer;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\Transition;

class WorkflowEnabledNormalizer implements NormalizerInterface, NormalizerAwareInterface, ContextAwareNormalizerInterface
{
    use NormalizerAwareTrait;

    private const WORKFLOW_CHECKED_ALREADY = 'WORKFLOW_CHECKED_ALREADY';

    /**
     * @var Registry
     */
    private $workflowRegistry;

    public function __construct(Registry $workflowRegistry)
    {
        $this->workflowRegistry = $workflowRegistry;
    }

    public function supportsNormalization($data, $format = null, array $context = [])
    {
        return $data instanceof WorkflowEnabledInterface && !($context[self::WORKFLOW_CHECKED_ALREADY] ?? false);
    }

    public function normalize($object, $format = null, array $context = [])
    {
        $normalized = $this->normalizer->normalize($object, $format, $context + [self::WORKFLOW_CHECKED_ALREADY => true]);

        if (is_array($normalized)) {
            $workflow = $this->workflowRegistry->get($object);
            $transitions = $workflow->getEnabledTransitions($object);
            $transitions = array_map(function (Transition $transition): string {
                return $transition->getName();
            }, $transitions);
            switch ($format) {
                case ItemNormalizer::FORMAT:
                    $normalized['@transitions'] = $transitions;
                    break;
                default:
                    $normalized['__transitions'] = $transitions;
                    break;
            }
        }

        return $normalized;
    }
}

I'd like to have supportsNormalization method to become instead (or similar):

public function supportsNormalization($data, $format = null, array $context = [])
{
   return !($context[self::WORKFLOW_CHECKED_ALREADY] ?? false) && $this->workflowRegistry->has($data);
}

Is it worthwile?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions