Answer the question
In order to leave comments, you need to log in
Insert in postPersist event?
I need to add an entity after adding other entities. Code (similar for postUpdate):
public function postPersist(LifecycleEventArgs $args) {<br>
$entity = $args->getEntity(); $em = $args->getEntityManager();<br><br>
if($entity instanceof FeedItemInterface) {<br>
$feed = new FeedEntity();<br>
$feed->setTitle($entity->getFeedTitle());<br>
$feed->setEntity($entity->getFeedEntityId());<br>
$feed->setType($entity->getFeedType());<br><br>
$em->persist($feed);<br>
$em->flush();<br>
}<br>
}<br>
Integrity constraint violation: 1062 Duplicate entry '30-2' for key 'PRIMARY'
INSERT INTO interview_scientificdirection (interview_id, scientificdirection_id) VALUES (?, ?) ([30,2])<br>
INSERT INTO interview_scientificdirection (interview_id, scientificdirection_id) VALUES (?, ?) ([30,2])<br>
->add('scientificDirections', 'sonata_type_model')
Answer the question
In order to leave comments, you need to log in
I did so.
class LogListener implements EventSubscriber
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function getSubscribedEvents()
{
return array(Events::postUpdate, Events::postPersist, Events::preRemove);
}
public function postUpdate(LifecycleEventArgs $eventArgs)
{
$this->log($eventArgs, Log::ACTION_UPDATE);
}
public function postPersist(LifecycleEventArgs $eventArgs)
{
$this->log($eventArgs, Log::ACTION_PERSIST);
}
public function preRemove(LifecycleEventArgs $eventArgs)
{
$this->log($eventArgs, Log::ACTION_REMOVE);
}
private function log(LifecycleEventArgs $eventArgs, $action)
{
$token = $this->container->get('security.context')->getToken();
if (!$token) {
return;
}
$user = $token->getUser();
if (!($user instanceof User)) {
return;
}
$entity = $eventArgs->getEntity();
if ($entity instanceof Log) {
return;
}
$request = $this->container->get('request');
$log = new Log();
$log->setAction($action);
$log->setUser($user);
$log->setIp($request->server->get('REMOTE_ADDR'));
$log->setEntityClass(get_class($entity));
$log->setEntityId($entity->getId());
$em = $this->container->get('doctrine')->getEntityManager();
$meta = $em->getClassMetadata(get_class($log));
$conn = $em->getConnection();
foreach ($meta->getReflectionProperties() as $fieldName => $reflProp) {
if (!$meta->isIdentifier($fieldName)) {
$columns[] = $fieldName;
$values[] = ':' . $fieldName;
}
}
$insertSql = 'INSERT INTO ' . $meta->getQuotedTableName($conn->getDatabasePlatform())
. ' (' . implode(', ', $columns) . ') '
. 'VALUES (' . implode(', ', $values) . ')';
$stmt = $conn->prepare($insertSql);
$fields = $meta->getFieldNames();
$association = $meta->getAssociationNames();
foreach ($meta->getReflectionProperties() as $fieldName => $reflProp) {
if (!$meta->isIdentifier($fieldName)) {
$value = $reflProp->getValue($log);
if (in_array($fieldName, $fields)) {
$mapping = $meta->getFieldMapping($fieldName);
$stmt->bindValue($meta->getColumnName($fieldName), $value, $mapping['type']);
} else if (in_array($fieldName, $association)) {
$classMeta = $em->getClassMetadata($meta->getAssociationTargetClass($fieldName));
list($classId) = $classMeta->getIdentifier();
$mapping = $classMeta->getFieldMapping($classId);
$associationIdProperty = $classMeta->getReflectionProperty($classId);
$associationValue = $associationIdProperty->getValue($value);
$stmt->bindValue($meta->getColumnName($fieldName), $associationValue, $mapping['type']);
} else {
throw new \Exception('Exception in log listener');
}
}
}
$stmt->execute();
}
}
Well, let's say that FeedEntity implements FeedItemInterface, then it will be an infinite loop, and it will only be executed twice because of the unique key. Yes, and it’s not right to flush in a persister - flush () starts and ends a large transaction, and I suspect that it’s not right to do this in the middle of the controller, at the moment of one of the persisters.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question