如何在没有数据键的情况下将分形变换对象直接包含到集合元中


How to include fractal transformed objects directly to collection meta without data key

我使用league/fractal与JsonApiSerializer,

我有json输出的用户集合。现在我想在这个json响应中添加一些过滤器数据(比如当前过滤器的用户计数)。

I got this:

$resource = new Collection($dataProvider->getData(), new UserTransformer());

//唯一的方法来包含一些不直接链接的数据我发现是使用setMeta():

    $resource->setMetaValue('projects', $dataProvider->getProjects());
    $resource->setMetaValue('somes',    $dataProvider->getTasks());

但是!"项目",'some '集合(是的,它们也是集合)也包含'data'键。

我有了这样的结构:

{
    'data' => [
         {//user1},{//user2},...
    ],
    'meta' => {
         'projects' => {
              'data' => {...}
         },
         'somes' => {
              'data' => {...}
         }
    }
}

,但我想要这样的:

{
    'data' => [
         {//user1},{//user2},...
    ],
    'meta' => {
         'projects' => {...}, //there is no 'data' key
         'somes' => {...}     //there is no 'data' key
    }
}

我该怎么办?

这有点hack,但没有重构在fractal的League' fractal 'Manager::createData()中硬编码的Scope类就可以正常工作,并且使用自己的Scope类实现的唯一方法是在Manager的扩展中重载此方法。

<?php
use League'Fractal'Serializer'JsonApiSerializer;
/**
 * Class EmbedSerializer
 */
class EmbedSerializer extends JsonApiSerializer
{
    const RESOURCE_EMBEDDED_KEY = 'embedded';
    /**
     * Serialize a collection.
     *
     * @param string $resourceKey
     * @param array  $data
     * @return array
     */
    public function collection($resourceKey, array $data)
    {
        return $resourceKey === self::RESOURCE_EMBEDDED_KEY ? $data : [$resourceKey ?: 'data' => $data];
    }
    /**
     * Serialize an item.
     *
     * @param string $resourceKey
     * @param array  $data
     * @return array
     */
    public function item($resourceKey, array $data)
    {
        return $resourceKey === self::RESOURCE_EMBEDDED_KEY ? $data : [$resourceKey ?: 'data' => [$data]];
    }
}

现在我可以这样写:

    /** @var $this->fractal League'Fractal'Manager */
    $this->fractal->setSerializer(new EmbedSerializer());
    $projectsCollection = $this->fractal->createData(
        new Collection($projects, new UserProjectTransformer(), 'embedded')
    )->toArray();
    $resource = new Collection($users, new UserTransformer());
    $resource->setMetaValue('projects', $projectsCollection);

这就是你所需要的。