Sonata admin configureFormField - doctrine

i use sonata admin and i have a 'Fonctionnare' entity. i changed the 'codeFonctionnaire' type of this entity to string but when i create the Fonctionnaire admin class and try to add new fonctionaire i got this error message:
Neither the property "codeFonctionnaire" nor one of the methods "setCodeFonctionnaire()", "_set()" or "_call()" exist and have public access in class "Examens\ExamensBundle\Entity\Fonctionnaire".
Fonctionnaire.php:
<?php
namespace Examens\ExamensBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Fonctionnaire
*/
class Fonctionnaire
{
/**
* #var string
*/
private $codeFonctionnaire;
//////
/**
* Get codeFonctionnaire
*
* #return string
*/
public function getCodeFonctionnaire()
{
return $this->codeFonctionnaire;
}
////////
FonctionnaireAdmin.php:
<?php
namespace Examens\ExamensBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Examens\ExamensBundle\Entity\Fonctionnaire;
class FonctionnaireAdmin extends Admin
{
protected $datagridValues = array(
'_sort_order' => 'ASC',
'_sort_by' => 'codeFonctionnaire'
);
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('codeFonctionnaire','text',array('label'=>'Code fonctionnaire'))
//////
}
what's wrong with the entity?

You need to regenerate the getters and setters of your Fonctionnaire class. Your IDE can do it for you.
Or at least, just add a
public function setCodeFonctionnaire($codeFonctionnaire) {
$this->codeFonctionnaire = $codeFonctionnaire;
}
EDIT
Here is what might be your complete Fonctionnaire class :
namespace TechVehi\BlogBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class Fonctionnaire {
/**
* #var string
*
* #ORM\Column(name="codeFonctionnaire", type="string", length=255, nullable=true)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $codeFonctionnaire;
/**
* #param string $codeFonctionnaire
*/
public function setCodeFonctionnaire($codeFonctionnaire) {
$this->codeFonctionnaire = $codeFonctionnaire;
}
/**
* #return string
*/
public function getCodeFonctionnaire() {
return $this->codeFonctionnaire;
}
}
You might have forgotten other informations, like the ORM annotation to link your object to your database.

i deleted this code from fonctionnaire.orm.yml:
generator:
strategy: IDENTITY
and it works.

Related

Symfony FOSuser translation new form

I have problem with translation of new inputs in the registration form in FOSUSER. Basicly I Extended the FOS user Entity:
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use FOS\UserBundle\Model\User as BaseUser;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser {
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255)
*
* #Assert\NotBlank(message="Fill it", groups={"Registration", "Profile"})
* #Assert\Length(
* min=3,
* max=255,
* minMessage="To short.",
* maxMessage="To long.",
* groups={"Registration", "Profile"}
* )
*/
protected $nameU;
public function getNameU() {
return $this->nameU;
}
public function setNameU($nameU) {
$this->nameU= $nameU;
}
Ovveride the registration FORM
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Gregwar\CaptchaBundle\Type\CaptchaType;
use FOS\UserBundle\Util\LegacyFormHelper;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('nameU')
}
public function getParent()
{
return 'FOS\UserBundle\Form\Type\RegistrationFormType';
// Or for Symfony < 2.8
// return 'fos_user_registration';
}
public function getBlockPrefix()
{
return 'app_user_registration';
}
// For Symfony 2.x
public function getName()
{
return $this->getBlockPrefix();
}
}
In my registration view I have:
{{ form_label(form.nameU, null,{}) }}
Add to translation specific declaration for a locale of FOS USER BUNDLE in app/Resource/FosUser../translation/.....
form:
group_name: Gruppenname
username: Benutzername TEST <- this change OK
nameU: TESTS <- this not
The translation is not working and it's look like variable name nameU :(
Ok. I have found it. I forget to send it in the registration type:
class RegistrationType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->
->add('numeU',null, array('label' => 'form.nameU', 'translation_domain' => 'FOSUserBundle'))

Constraint validator namespace loading from wrong namespace

I am trying to make custom validator in symfony 2, but it loads from wrong namespace. Error says:
Attempted to load class "DateChecker" from namespace "Symfony\Component\Validator\Constraints\Errand\MainBundle\Validator\Constraints.
Here is my code:
MainBundle/Validator/Constraints/DateCheker.php:
<?php
namespace Errand\MainBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* #Annotation
*/
class DateChecker extends Constraint
{
/**
*
* #var string
*/
public $message = 'some message';
/**
*
* #return string
*/
public function validatedBy()
{
return get_class($this).'Validator';
}
/**
* Get class constraints and properties
*
* #return array
*/
public function getTargets()
{
return array(self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT);
}
}
MainBundle/Validator/Constraints/DateCheckerValidator.php:
namespace Errand\MainBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class DateCheckerValidator extends ConstraintValidator
{
/**
* Method to validate
*
* #param string $value Property value
*
*
* #return boolean
*/
public function validate($value, Constraint $constraint)
{
//validation
}
}
MainBundle/Resources/config/validation.yml:
Errand\MainBundle\Entity\Task:
constraints:
- Errand\MainBundle\Validator\Constraints\DateChecker: ~

symfony annotations validation override entities/models

I'm trying to override the entities validatation of a forum bundle.
I do it like this:
Category entity:
//src/MSD/ForoBundle/Entity/Category.php
namespace MSD\ForoBundle\Entity;
use Herzult\Bundle\ForumBundle\Entity\Category as BaseCategory;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="Herzult\Bundle\ForumBundle\Entity\CategoryRepository")
*/
class Category extends BaseCategory
{
}
Topic entity:
//src/MSD/ForoBundle/Entity/Topic.php
namespace MSD\ForoBundle\Entity;
use Herzult\Bundle\ForumBundle\Entity\Topic as BaseTopic;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Topic
*
* #ORM\Entity(repositoryClass="Herzult\Bundle\ForumBundle\Entity\TopicRepository")
*
*/
class Topic extends BaseTopic
{
/**
* #ORM\ManyToOne(targetEntity="Category")
*/
protected $category;
/**
* #Assert\NotBlank()
* #Assert\MinLength(limit=4, message="Just a little too short| ")
* #Assert\Regex(
* pattern="/^[a-zA-Z0-9\-_¿?!¡ ]{4,50}$/",
* message="El tema puede contener letras, números, guiones y espacios, interrogantes y exclamaciones. Entre 4 y 30 caracteres"
* )
*/
protected $subject;
/**
* {#inheritDoc}
*/
public function getAuthorName()
{
return $this->author;
}
/**
* #ORM\ManyToOne(targetEntity="User")
*/
private $author;
public function setAuthor(User $user)
{
$this->author = $user;
}
public function getAuthor()
{
return $this->author;
}
}
Post Entity:
//src/MSD/ForoBundle/Entity/Post.php
namespace MSD\ForoBundle\Entity;
use Herzult\Bundle\ForumBundle\Entity\Post as BasePost;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity(repositoryClass="Herzult\Bundle\ForumBundle\Entity\PostRepository")
*/
class Post extends BasePost
{
/**
* #ORM\ManyToOne(targetEntity="Topic")
*/
protected $topic;
/**
* #Assert\Regex(
* pattern="/^[^<>]{4,1000}$/",
* message="El mensaje no puede contener '<' ni '>'. Entre 4 y 1000 caracteres"
* )
*
*/
public $message;
public function getAuthorName()
{
return $this->author;
}
/**
* #ORM\ManyToOne(targetEntity="User")
*/
private $author;
public function setAuthor(User $user)
{
$this->author = $user;
}
public function getAuthor()
{
return $this->author;
}
}
And the validation works... except the message of the firt post!! that is created when a new topic is created.
I've tried many changes, but without success.
Any idea of why does it happend?
Thank you
Yeah! I got it. The solution was to add this in the Topic entity:
/**
* #Assert\NotBlank
* #Assert\Valid
*/
protected $firstPost;
Then, the message of the first post is validated.

doctrine 2, how do get data from the inverse side (many to one)

I have two entities, entry and comments.
comments:
/**
* #Entity(repositoryClass="\Entities\Blog\CommentRepository")
* #Table(name="blog_comment")
* #HasLifecycleCallbacks
*/
class Comment extends \Entities\AbstractEntity
{
/**
* #Id #Column(name="id", type="integer")
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ManyToOne(targetEntity="Entry", inversedBy="comments")
* #JoinColumn(name="entry_id", referencedColumnName="id")
*/
protected $entry;
/** #Column(name="approved", type="string", length=255) */
protected $approved;
/** #Column(name="title", type="string", length=255) */
protected $title;
/** #Column(name="content", type="text") */
protected $content;
/** #Column(name="pub_date", type="datetime") */
protected $pub_date;
/** #Column(type="datetime") */
private $created_at;
/** #Column(type="datetime") */
private $updated_at;
/** #PreUpdate */
public function updated()
{
$this->updated_at = new \DateTime("now");
}
public function __construct()
{
$this->created_at = $this->updated_at = new \DateTime("now");
}
}
class CommentRepository extends \Entities\PaginatedRepository
{
protected $_entityClassName = 'Entities\Blog\Comment';
}
and entry:
<?php
namespace Entities\Blog;
/**
* #Entity(repositoryClass="\Entities\Blog\EntryRepository")
* #Table(name="blog_entry")
* #HasLifecycleCallbacks
*/
class Entry extends \Entities\AbstractEntity
{
/**
* #Id #Column(name="id", type="integer")
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/** #Column(name="permalink", type="string", length=255) */
protected $permalink;
/** #Column(name="title", type="string", length=255) */
protected $title;
/** #Column(name="pub_date", type="datetime") */
protected $pub_date;
/** #Column(name="content", type="text") */
protected $content;
/** #OneToMany(targetEntity="Comment", mappedBy="entry") */
protected $comments;
/** #Column(type="datetime") */
private $created_at;
/** #Column(type="datetime") */
private $updated_at;
/** #PreUpdate */
public function updated()
{
$this->updated_at = new \DateTime("now");
}
public function __construct()
{
$this->comments = new \Doctrine\Common\Collections\ArrayCollection();
}
I can get the collection of all comments belonging to each entry via:
foreach ($comments as $comment){
$comment-$commentId;
}
but how can I get the entry information from the comments side. for example, I would like to get the entry id from a specific comment
Each time you create a #OneToMany relation, you create a Collection of proxy objects in class on "One"-side of relation, and single proxy object in class on "Many"-side of relation. Proxy classes are automatically generated by Doctrine2 from your mapping information.
To allow Doctrine2 filling proxy object with real data from DB it's important to declare it protected or private. I'm not sure about that, but seems like Doctrine tracks down any requests to proxy objects inside your entity class and ensures that proxies are populated before first usage.
To access the associated object you have to define accessor function in your Comment class:
class Comment extends \Entities\AbstractEntity{
/** other definitions */
function getEntity(){
return $this->entity;
}
}
And use it like
$comment = $em->find("Entities\Comment",1);
$entity = $comment->getEntity();
Doctrine2 will automatically populate $comment->entity proxy with actual Entity object.
See "Workin with Objects" chapter of Doctrine documentation and "Can you explain me what is a Proxy in Doctrine 2?" on details of proxies.

Polymorphic associations in doctrine 2?

I need a concrete sample of code with doctrine 2 that uses "polymorphic associations".
Let me clarify myself. I have a Entity called Contract and a contract can have many price rules and these price rules can be different kind of classes and presisted in different tables. I suppose this is what's polymorphic associations for or am I wrong?
class contract {
private $id;
private $priceRules;
}
class discountRule implements priceRule{
function calculate() {
// calculate new price after this rule
}
}
class extraSpecialRule implements priceRule {
function calculate() {
// calculate new price after this rule
}
}
There can be new types of price rules in the future,so how can I associate these rules to the main entity and presist them in seperate tables?
Update:
This is my new code:
contract.php
namespace Entities;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #Entity #Table(name="contract")
*/
class Contract {
/**
*
* #Id #Column(type="integer")
* #GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #Column(type="integer")
*/
private $propertyId;
/**
*
* #Column(type="integer")
*/
private $agencyId;
/**
*
* #OneToMany(targetEntity="priceRule" ,mappedBy="contract")
*
*/
private $priceRules;
public function __construct($propertyId,$agencyId){
$this->propertyId=$propertyId;
$this->agencyId=$agencyId;
$this->priceRules=new ArrayCollection();
}
public function addPriceRule(priceRule $rule){
$this->priceRules[]=$rule;
}
public function getPriceRules(){
return $this->priceRules;
}
}
pricerule.php
namespace Entities;
/**
* #Entity
* #InheritanceType("JOINED")
* #DiscriminatorColumn(name="discr" , type="string")
* #DiscriminatorMap({"discountrule"="discountRule","extradiscountrule"="extraDiscountRule"})
*/
class priceRule{
/**
*
* #Id #Column(type="integer")
* #GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #ManyToOne(targetEntity="contract",inversedBy="availibilityRules")
* #JoinColumn("contract_id",referencedColumnName="id")
*/
private $contract;
}
discountrule.php
namespace Entities;
/**
* #Entity
*
*
*/
class discountRule extends priceRule {
/**
*
* #Id #Column(type="integer")
* #GeneratedValue(strategy="AUTO")
*/
private $id;
public function calculatePrice(){
// calculate new price
}
}
extradiscountrule.php
namespace Entities;
/**
* #Entity
*
*
*/
class extraDiscountRule extends priceRule {
/**
*
* #Id #Column(type="integer")
* #GeneratedValue(strategy="AUTO")
*/
private $id;
public function calculate() {
// calculate new price
}
}
sampleusage.php
$contract=new Contract(1,1);
$discount=new discountRule();
$em->persist($discount);
$contract->addPriceRule($discount);
$em->persist($contract->getPriceRules());
$em->persist($contract);
$em->flush();
But when I try to add new rule to the contract I get error message (Fatal error: Uncaught exception 'Doctrine\ORM\Mapping\MappingException' with message 'Class Doctrine\Common\Collections\ArrayCollection is not a valid entity or mapped super class.)
What am I doing wrong ?
You may be missing an #MappedSuperclass on your PriceRule parent object
Refer to: Inheritance Mapping
I don't this is possible because an interface cannot define properties in a class, so you can't guarantee there will be properties for Doctrine to manipulate.
If you could provide more details on your entities I could help better.

Resources