Salut à tous,
j'utilise SonataAdminBundle. Mon but est d'administrer mes Articles de mon site et ainsi de permettre aux administrateurs d'en créer au travers l'interface d'administration.
Voici comment la relation est définis:
J'ai donc dans user:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
/**
* @var articles
*
* Ici on va créé la relation OneToMany (Many: article to One user)
* @ORM\OneToMany(targetEntity="Kark\RecetteBundle\Entity\Article", mappedBy="user", cascade={"persist", "remove"})
*/
protected $articles;
public function __construct()
{
//Une classe à pour instrctruction dans sont constructeur, le constructeur du parent
parent::__construct();
$this->articles = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get articles
*
* @return ArrayCollection
*/
public function getArticles()
{
return $articles;
}
/**
* Méthode qui permet d'ajouter un article à notre utilisateur. On va ainsi respecter le DRY
* en indiquant l'utilisateur qui poste l'article
*
* @param $unArticle
*/
public function addArticle(\Kark\RecetteBundle\Entity\Article $unArticle)
{
$this->articles[] = $unArticle;
$unArticle->setUser($this);
} |
Et voici dans ma classe Article:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| /**
* @ORM\ManyToOne(targetEntity="Kark\UserBundle\Entity\User", inversedBy="articles")
*/
private $user;
/**
* Set user
*
* @param User
* @return article
*/
public function setUser(\Kark\UserBundle\Entity\User $unUser)
{
$this->user = $unUser;
return $this;
}
/**
* Get user
*
* @return User
*/
public function getUser()
{
return $this->user;
} |
Dans mon SonataAdminBundle, j'ai alors définis le constroller CRUD des deux entités User et Article:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| <?php
namespace Kark\AdminBundle\Controller;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
class ArticleAdminController extends Controller
{
}
Voici le CRUD de User:
<?php
namespace Kark\AdminBundle\Controller;
use Sonata\AdminBundle\Controller\CRUDController as Controller;
class UserAdminController extends Controller
{
}
ainsi que leurs configurations dans le admin.cfg:
# Kark/AdminBundle/Resources/config/admin.yml
services:
kark.admin.admin.article:
class: Kark\AdminBundle\Admin\ArticleAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: Article, label: articles }
arguments:
- ~
- Kark\RecetteBundle\Entity\Article
- KarkAdminBundle:ArticleAdmin
Voici la partie pour l'entité User:
kark.admin.admin.userarticle:
class: Kark\AdminBundle\Admin\UserAdmin
tags:
- { name: sonata.admin, manager_type: orm, group: user, label: users }
arguments:
- ~
- Kark\UserBundle\Entity\User
- KarkAdminBundle:UserAdmin |
Tout est bien configuré, et j'ai ainsi la définition suivante dans ma classe Admin de mon Article:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
| <?php
namespace Kark\AdminBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Kark\RecetteBundle\Entity\Article;
use Kark\RecetteBundle\Entity\ImageArticle;
use Knp\Menu\ItemInterface as MenuItemInterface;
class ArticleAdmin extends Admin
{
// setup the default sort column and order
protected $datagridValues = array(
'_sort_order' => 'ASC',
'_sort_by' => 'name'
);
// L'ensemble des champs qui seront montrer lors de la création ou de la modification d'une entité
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->with('General')
->add('titre', 'text')
->add('imageArticle', 'sonata_type_admin', array('delete' => false), array('required' => true, 'edit' => 'inline'))
->add('contenu','textarea');
}
/**
*
* Fonction qui va permettre d'afficher les différent filtres de recherche dans notre tableau
* de notre interface.
*
*/
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('titre')
->add('user.username')
;
}
/**
* Fonction qui redéfini celle de la classe mère Admin. Cette fonction va nous permettre de préciser les
* champs qui seront affiché dans notre tableau lorsque l'on listera nos entités
*/
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('titre')
->add('date', null, array('route' => array('name' => 'show')))
->add('contenu')
->add('user.username')
->add('_action', 'actions', array(
'actions' => array(
'show' => array(),
'edit' => array(),
'delete' => array()
)
))
;
}
/**
* Fonction qui redéfinie la fonction de la classe mère qui permet d'indiquer les champs qui seront affiché
* lorsque l'on consultera un article
*/
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('date')
->add('titre')
->add('contenu')
->add('imageArticle.getWebPath()', 'string', array('template' => 'KarkAdminBundle:ArticleAdmin:list_image.html.twig'))
->add('user.username')
;
}
/**
* {@inheritdoc}
*/
public function prePersist($object)
{
$user = $this->getConfigurationPool()->getContainer()->get('security.context')->getToken()->getUser();
$user->addArticle($object);
}
/**
* {@inheritdoc}
*/
public function preUpdate($object)
{
$user = $this->getConfigurationPool()->getContainer()->get('security.context')->getToken()->getUser();
$user->addArticle($object);
}
} |
Cependant, l'article ne s'insère pas puisque ce dernier réalise une INSERTION et un UPDATE, et que dans la table 'article_audit' il réalise deux fois la même insertion, et ainsi il y a un dupliquata de clé primaire...
Citation:
[3/4] UniqueConstraintViolationException: An exception occurred while executing 'INSERT INTO article_audit (rev, revtype, imageArticle_id, user_id, id, date, titre, contenu, publication, dateEdition, slugTitre) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' with params ["545", "UPD", 43, 1, 43, "2014-06-16 23:28:40", "qsmodjqskdjqslkdqjsk", "<p>qsldkqsmldkqslmdkqsmdlqslk lmqskdmlqskdqsmld qskdjqslkdqjsldqksd<\/p>", 0, "2014-06-16 23:28:40", "qsmodjqskdjqslkdqjsk"]:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '43-545' for key 'PRIMARY'
PDOException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '43-545' for key 'PRIMARY'
Voici le fichier log:
Citation:
DEBUG - INSERT INTO article (date, titre, contenu, publication, dateEdition, slugTitre, imageArticle_id, user_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
DEBUG - INSERT INTO article_audit (rev, revtype, imageArticle_id, user_id, id, date, titre, contenu, publication, dateEdition, slugTitre) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
DEBUG - UPDATE article SET date = ?, titre = ?, contenu = ?, publication = ?, dateEdition = ?, slugTitre = ?, imageArticle_id = ?, user_id = ? WHERE id = ?
DEBUG - INSERT INTO article_audit (rev, revtype, imageArticle_id, user_id, id, date, titre, contenu, publication, dateEdition, slugTitre) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
DEBUG - "ROLLBACK"
CRITICAL - Uncaught PHP Exception Sonata\AdminBundle\Exception\ModelManagerException: "Failed to create object: Kark\RecetteBundle\Entity\Article" at /var/www/recette-etudiant/vendor/sonata-project/doctrine-orm-admin-bundle/Model/ModelManager.php line 142
J'ai essayer d'insérer de manière plus traditionnel, c'est-à-dire avec une action dans mon ArticleController dont voici:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
|
public function ajouterNewsAction($_local)
{
//Toute les création ce feront au travers de formulaire
$monArticle = new Article();
//On créé notre formulaire en utilisant une classe externe
$monFormulaire = $this->createForm(new ArticleType, $monArticle);
//On récupère la requête
$request = $this->get('request');
//Lors de l'envoie d'un formulaire, on le réalise au travers de transfert de données de page à page via une méthode
//appelé POST. Ainsi on va vérifier lors de l'appel de cette fonction si cette méthode est effective, si c'est le cas c'est
//que des données on été transmise via un formulaire de données.
if($this->get('request')->getMethod() == 'POST')
{
//Traitement des données ici on va hydrater notre formulaire avec ce qui a été saisie en récupérant les valeurs
//de mes superglobal $_POST via une fonction plutôt rapide
$monFormulaire->bind($request);
//On vérifie que les valeurs entrées soient correct. La validation des objets se fait via les annotation
//de notre classe Constraints via notre Validator aliasé @Assert.
if($monFormulaire->isValid())
{
//Si l'article est effectivement ajouter, c'est que tout est bon alors on créé un Tag
$this->get('session')->getFlashBag()->add('AjoutRealise', 'L\'article a été rajouté avec succès');
//On récupère l'utilistaeur en cours
$user = $this->getUser();
//On persist alors notre entité hydratée par le formulaire
$entity_manager = $this->getDoctrine()->getManager();
//On récupère le service de management des utilisateur du FOSUB
$userManager = $this->get('fos_user.user_manager');
//On ajoute notre utilisateur à notre article
$user->addArticle($monArticle);
$userManager->updateUser($user);
$entity_manager->flush();
//On redirige vers la page d'affichage de l'article
return $this->redirect($this->generateUrl('karkrecette_voir_article', array("id" => $monArticle->getId(), "slugTitre" => $monArticle->getSlugTitre() )));
}
}
//Si on est pas en présence d'une méthde get, c'est que le formulaire n'est pas encore envoyer, il est alors vierge
//Sinon il se peut que le formulaire ne soit pas valide, on affiche alors le formulaire hydrater des valeur précédement saisie
return $this->render('KarkRecetteBundle:Article:ajouter.html.twig', array("form" => $monFormulaire->createView(), "langue" => $_local));
} |
ET j'ai également la même erreur:
Citation:
An exception occurred while executing 'INSERT INTO article_audit (rev, revtype, imageArticle_id, user_id, id, date, titre, contenu, publication, dateEdition, slugTitre) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' with params ["552", "UPD", 49, 1, 49, "2014-06-17 10:17:29", "qosdkqlmsdkqsmldkqsdmlqsdqlmsd", "qlmskdsqmldkqsmldqskdmlqskdsqmldkqsmdlqskdmlqsdkqsmldqskd qlskdqslmdqsd", 0, "2014-06-17 10:17:52", "qosdkqlmsdkqsmldkqsdmlqsdqlmsd"]:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '49-552' for key 'PRIMARY'
Voici le LOG qui reste toujours le même, un UPDATE après mon INSERT:
Citation:
DEBUG - "START TRANSACTION"
DEBUG - INSERT INTO image_article (url, alt, extension) VALUES (?, ?, ?)
DEBUG - INSERT INTO revisions (timestamp, username) VALUES (?, ?)
DEBUG - INSERT INTO image_article_audit (rev, revtype, id, url, alt, extension) VALUES (?, ?, ?, ?, ?, ?)
DEBUG - INSERT INTO article (date, titre, contenu, publication, dateEdition, slugTitre, imageArticle_id, user_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
DEBUG - INSERT INTO article_audit (rev, revtype, imageArticle_id, user_id, id, date, titre, contenu, publication, dateEdition, slugTitre) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
DEBUG - UPDATE article SET date = ?, titre = ?, contenu = ?, publication = ?, dateEdition = ?, slugTitre = ?, imageArticle_id = ?, user_id = ? WHERE id = ?
DEBUG - INSERT INTO article_audit (rev, revtype, imageArticle_id, user_id, id, date, titre, contenu, publication, dateEdition, slugTitre) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
DEBUG - "ROLLBACK"
CRITICAL - Uncaught PHP Exception Doctrine\DBAL\Exception\UniqueConstraintViolationException: "An exception occurred while executing 'INSERT INTO article_audit (rev, revtype, imageArticle_id, user_id, id, date, titre, contenu, publication, dateEdition, slugTitre) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' with params ["552", "UPD", 49, 1, 49, "2014-06-17 10:17:29", "qosdkqlmsdkqsmldkqsdmlqsdqlmsd", "qlmskdsqmldkqsmldqskdmlqskdsqmldkqsmdlqskdmlqsdkqsmldqskd qlskdqslmdqsd", 0, "2014-06-17 10:17:52", "qosdkqlmsdkqsmldkqsdmlqsdqlmsd"]: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '49-552' for key 'PRIMARY'" at /var/www/recette-etudiant/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php line 65
A mon humble avis, il doit y avoir un flush et un update exécuter l'un après l'autre...ou un comflit entre ORM...cependant je n'en utilise qu'un seul....
Aurais-je loupé une étape oO
Merci :)