1

Categoryの束を含むエンティティがありますAssets。カテゴリには、getCountその中のアセットの量を返すメソッドがあります。

FosRestBundle と JMSSerializerBundle を使用して、Category アセットを json にシリアル化します。現在、さまざまな種類のアセット (externalと など) を導入する機能変更がありましinternalた。

私はまだエンティティのシリアライゼーションを使いたいと思ってPreSerializeEventいます。

ただし、シリアライザー コンポーネントのドキュメントは、関連する部分を次のように参照することでわかりにくくなっています。do something

ここで実際に何かを行うにはどうすればよいですか?

私が達成したいのは、フラグが設定されている場合に呼び出されるメソッドを変更することです。シリアライザーの通常のケースでは、メソッドを使用する必要がありますが、シリアル化されているgetCount場合はgetExternalCountOnly、Category オブジェクトのメソッドを使用する必要がありますgetCount

これは実際にここで行うことができますか、それとも間違った方向に進んでいますか?

私を参照してくださいCategorySerializationSubscriber:

<?php
namespace Hn\AssetDbBundle\Listener;

use Hn\AssetDbBundle\Entity\Category;
use Hn\UserBundle\Entity\User;
use JMS\Serializer\Annotation\PostSerialize;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
use JMS\Serializer\EventDispatcher\ObjectEvent;
use JMS\Serializer\EventDispatcher\PreSerializeEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;

/**
 * Class CategorySerializationSubscriber
 * @package Hn\AssetDbBundle\Listener
 */

class CategorySerializationSubscriber implements EventSubscriberInterface
{
    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @var User $user
     */

    private $user;

    /**
     * @param LoggerInterface $logger
     */

    public function __construct(LoggerInterface $logger, SecurityContextInterface $context)
    {
        $this->user = $context->getToken()->getUser();
        $this->logger = $logger;
        $logger->critical($this->user->getFullNameOrEmail());
    }

    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return [
            [
                'event' => 'serializer.pre_serialize',
                'method' => 'onPreSerialize'
            ],
        ];
    }

    /**
     * @param PreSerializeEvent $event
     */

    public function onPreSerialize(PreSerializeEvent $event)
    {
        $category = $this->getCategoryFromEvent($event);

        if (!$category) {
            $this->logger->info('is not a category, aborting');
            return;
        }

        $userCanViewInternalAsset = $this->user->isAllowedToViewInternalAssets();

        /**
         * How to actually do something?
         * 
         * Pseudocode follows:
         */

        if ($userCanViewInternalAsset) {
            $seriaization->replaceMethod($category, 'getCount', 'getExternalAssetCount');
        } else {
            /**
             * $category->getCount(); remains intact
             */
        }
    }

    /**
     * @param PreSerializeEvent $event
     * @return Category|null
     */

    protected function getCategoryFromEvent(PreSerializeEvent $event) {

        /**
         * @var Category $category
         */

        $category = $event->getObject();

        if (!$category instanceof Category) {
            return null;

        }

        return $category;

    }
}
4

1 に答える 1

2

デフォルトで除外してから、postSerialize() サブスクライバーを使用して必要な関数を追加するのはどうですか? 例えば:

services.yml (またはservicesconfig.yml の下)で定義します。

category_serialization_subscriber:
    class: Hn\AssetDbBundle\Listener\CategorySerializationSubscriber
    tags:
        - { name: jms_serializer.event_subscriber }

次に、上記のクラスから変更された次のとおりです。

public static function getSubscribedEvents()
{
    return array(array(
        'event'  => 'serializer.post_serialize',
        'class'  => 'Hn\AssetDbBundle\Entity\Category',
        'method' => 'onPostSerialize'
    ));
}

public function onPostSerialize(ObjectEvent $event)
{
    $category = $event->getObject();
    $visitor  = $event->getVisitor();

    if ($this->user->isAllowedToViewInternalAssets()) {
        $visitor->addData('count', $category->getExternalAssetCount());
    } else {
        $visitor->addData('count', $category->getCount());
    }
}
于 2014-12-23T17:34:52.483 に答える