0
votes

I have this EventSubscriber:

class ChangeLogListener implements EventSubscriber
{
    private $tokenStorage;
    private $str,$str1;

    public function __construct(TokenStorage $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
    }

    public function getSubscribedEvents()
    {
        return array(
            'postPersist',
            'postUpdate',
            'onDelete',
        );
    }

    public function postPersist(LifecycleEventArgs $args)
    {
        if (!$args->getEntity() instanceof ChangeLog)

            $this->createLog($args, 'creation');
    }

    public function postUpdate(LifecycleEventArgs $args)
    {

        $this->createLog($args, 'update');
    }

    public function preRemove(LifecycleEventArgs $args)
    {
        $this->createLog($args, 'remove');
    }

    public function createLog(LifecycleEventArgs $args, $action)
    {
        # Entity manager
        $em = $args->getEntityManager();
        $uow = $em->getUnitOfWork();
        $entity = $args->getEntity();

        # Get user
        $user = $this->tokenStorage->getToken()->getUser();

        #Get changes
        $changes = $uow->getEntityChangeSet($entity);

        $cl = new ChangeLog();
        $cl->setDate(new \DateTime());
        $cl->setUser($user);
        $cl->setEntityName(get_class($entity));
        $cl->setEntityId($entity->getId());
        $cl->setAction($action);
        $cl->setDescription($log);
        $cl->setChangeset($changes);

        $em->persist($cl);
        $em->flush();
    }
}

And when I want to POST item, some data must be recorded to db. After all actions I receive this in change_set in my db:

a:3:{s:5:"value";a:2:{i:0;N;i:1;s:3:"120";}s:4:"item";a:2:{i:0;N;i:1;O:21:"AppBundle\Entity\Item":6:{s:25:"AppBundle\Entity\Itemid";i:127;s:27:"AppBundle\Entity\Itemname";s:7:"newitem";s:13:"*categories";O:33:"Doctrine\ORM\PersistentCollection":2:{s:13:"*collection";O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:2:{i:0;O:25:"AppBundle\Entity\Category":7:{s:29:"AppBundle\Entity\Categoryid";i:2;s:31:"AppBundle\Entity\Categoryname";s:10:"child to 1";s:33:"AppBundle\Entity\Categoryparent";O:40:"Proxies__CG__\AppBundle\Entity\Category":8:{s:17:"isInitialized";b:0;s:29:"AppBundle\Entity\Categoryid";i:1;s:31:"AppBundle\Entity\Categoryname";N;s:33:"AppBundle\Entity\Categoryparent";N;s:35:"AppBundle\Entity\Categorychildren";N;s:8:"*items";N;s:36:"AppBundle\Entity\CategorycreatedAt";N;s:36:"AppBundle\Entity\CategoryupdatedAt";N;}s:35:"AppBundle\Entity\Categorychildren";O:33:"Doctrine\ORM\PersistentCollection":2:{s:13:"*collection";O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:0:{}}s:14:"*initialized";b:0;}s:8:"*items";O:33:"Doctrine\ORM\PersistentCollection":2:{s:13:"*collection";O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:0:{}}s:14:"*initialized";b:0;}s:36:"AppBundle\Entity\CategorycreatedAt";N;s:36:"AppBundle\Entity\CategoryupdatedAt";N;}i:1;O:25:"AppBundle\Entity\Category":7:{s:29:"AppBundle\Entity\Categoryid";i:4;s:31:"AppBundle\Entity\Categoryname";s:8:"child1.1";s:33:"AppBundle\Entity\Categoryparent";r:13;s:35:"AppBundle\Entity\Categorychildren";O:33:"Doctrine\ORM\PersistentCollection":2:{s:13:"*collection";O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:0:{}}s:14:"*initialized";b:0;}s:8:"*items";O:33:"Doctrine\ORM\PersistentCollection":2:{s:13:"*collection";O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:0:{}}s:14:"*initialized";b:0;}s:36:"AppBundle\Entity\CategorycreatedAt";N;s:36:"AppBundle\Entity\CategoryupdatedAt";N;}}}s:14:"*initialized";b:1;}s:13:"*attributes";N;s:32:"AppBundle\Entity\ItemcreatedAt";O:8:"DateTime":3:{s:4:"date";s:26:"2018-03-19 10:22:47.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:3:"UTC";}s:32:"AppBundle\Entity\ItemupdatedAt";N;}}s:9:"attribute";a:2:{i:0;N;i:1;O:26:"AppBundle\Entity\Attribute":3:{s:30:"AppBundle\Entity\Attributeid";i:96;s:33:"AppBundle\Entity\Attributealias";s:5:"price";s:32:"AppBundle\Entity\Attributename";s:5:"price";}}}

But I think this data is not readable.I think I need to parse received data before writing it into db, but I don't understand how to parse this into readable format, something like this:

name: Old Value: 12 => New Value: 121, updatedAt: Old Value: 2018-03-20 05:51:44 => New Value: 2018-03-20 08:36:12 and other

Any idea how to parse this?

1
Just iterate over the change set and generate required array format by yourself. It's not that hard.emix
@MichaelZukowski if I knew how to do it, then I would not ask ... Can you tell me where you can find examples or articles to learn more about this?Dialkord
@Dialkord I had given you links in answer, they are similar to your requirement, if you face any more complexity mark me.Ashutosh Rai
@Dialkord you want an article how to traverse an array? Just use a foreach and see what you get, it isn't that hard, have you tried anything at all?emix
@MichaelZukowski The problem is that I have objects in the resulting array and I just can not use foreach, since there will be an error when the value is an object (the object can not be converted to a string)Dialkord

1 Answers

0
votes

You are directly inserting all work done on entities with whole object, that's why you are saving all the meta-data into db. Better to doctrine customized extension to handle this (doctrine-extensions and see Loggable behavioral extension for Doctrine2) or if you want to create self customized ChangeLogListner then use methods to compute or get exact change-Set using doctrine methods. to methods see here.

you can change your EventListner code something like this:

$em = $this->getDoctrine()->getManager();
$entity = $em->find('My\Entity', 1);
$entity->setTitle('Changed Title!');
$uow = $em->getUnitOfWork();
$uow->computeChangeSets(); // do not compute changes if inside a listener
$changeset = $uow->getEntityChangeSet($entity);

or check Is there a built-in way to get all of the changed/updated fields in a Doctrine 2 entity

if you are trying inside EventListner then try inside particular events like:

public function preUpdate(Event\LifecycleEventArgs $eventArgs)
{   
    $changeArray = $eventArgs->getEntityChangeSet();

    //do stuff with the change array

}