Regenerating slug Doctrine2 - symfony

I'm trying to regerate slug for entities that I've created prior to install Sluggable extension for Doctrine2 as it's explained here: Regenerating slug, but when I set it to empty string or null, does not regerate it, it simply sets as null.
What I'm doing wrong?
The entity:
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* #ORM\Entity
* #ORM\Table(name="product")
*/
class Product
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=200)
* #Assert\NotBlank()
*/
protected $name;
/**
* #ORM\Column(type="text")
* #Assert\NotBlank()
*/
protected $description;
...
/**
* #Gedmo\Slug(fields={"name"})
* #ORM\Column(length=200, unique=true)
*/
private $slug;
public function getSlug()
{
return $this->slug;
}
public function setSlug($slug)
{
$this->slug = $slug;
}
}
And then I try this:
$repository = $this->getDoctrine()->getRepository('CommonBundle:Product');
$product = $repository->findOneBy(array("id"=>1));
$product->setSlug('');
$em = $this->getDoctrine()->getEntityManager();
$em->persist($product);
$em->flush();

OK. I know what is happening. You are probably using an older version of the Doctrine Extensions, probably version 2.1.0. That would be the case if you are developing with Symfony 2.0.X as that is the version which was recommended. Check your deps file, you probably have something like:
[gedmo-doctrine-extensions]
git=http://github.com/l3pp4rd/DoctrineExtensions.git
version=v2.1.0
Those older versions of the extensions don´t support the behaviour described in the documentation (regenerate slug if it is empty). You would need to upgrade your version of the extensions, but this may mean that you may have to upgrade your Doctrine versions to 2.2, not really sure.

Related

Unable to find the Entity relative to a proxy

I have a simple Request on a Contact table.
use App\Entity\Contact;
...
$contact = $this->getUser()->getContact();
$form = $this->createForm(ParentContactType::class,$contact);
$form->handleRequest($request);
But when Handling the form, Symfony throws following Exception:
Unable to find the object manager associated with an entity of class "Proxies\__CG__\App\Entity\Contact".
The contact Class is a normal one,
<?php
namespace App\Entity;
use App\Repository\ContactRepository;
use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Core\Annotation\ApiResource;
/**
* #ORM\Entity(repositoryClass=ContactRepository::class)
*/
#[ApiResource]
class Contact
{
const FIRST_CONTACT = "Contact principal";
const SECOND_CONTACT = "Second contact";
const THIRD_CONTACT = "Troisième contact";
public function __construct(){
}
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=100, nullable=true)
*/
private $type;
/**
* #ORM\Column(type="string", length=3, nullable=true)
*/
private $gender;
+ getter and setter
It used to be working fine, but I do not know how to debug the issue.
Any help would be great.

No identifier/primary key specified for Entity why using KNP Translatable

I am using Knp/DoctrineBehaviors to translate my database content.
I followed the manual and created 2 entities, 1 for non-translatable content and the other for translatable fields.
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface;
use Knp\DoctrineBehaviors\Model\Translatable\TranslatableTrait;
/**
* Class Test
* #package App\Entity
* #ORM\Entity()
*/
class Test implements TranslatableInterface
{
use TranslatableTrait;
/**
* #var integer
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Id()
*/
private $id;
/**
* #return int
*/
public function getId(): int
{
return $this->id;
}
/**
* #param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}
}
and the Translation entity:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\TranslationInterface;
use Knp\DoctrineBehaviors\Model\Translatable\TranslationTrait;
/**
* Class TestTranslation
* #package App\Entity
* #ORM\Entity()
*/
class TestTranslation implements TranslationInterface
{
use TranslationTrait;
/**
* #var
* #ORM\Column(type="string")
*/
private $name;
/**
* #return mixed
*/
public function getName()
{
return $this->name;
}
/**
* #param mixed $name
*/
public function setName($name): void
{
$this->name = $name;
}
}
I also added the Bundle in my bundles.php file.
But when I run the command php bin/console doctrine:schema:update --force to create the table in give the error: No identifier/primary key specified for Entity "App\Entity\TestTranslation". Every Entity must have an identifier/p rimary key.
A primary key is missing in your entity "TestTranslation".
In doctrine every entity class must have an identifier/primary key. You can select the field that serves as the identifier with the #Id() annotation or in your case : #ORM\Id().
For example, add this to your entity :
/**
* #var integer
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Id()
*/
private $id;
And then, you can play the command: php bin/console d:s:u --force
In my case, Symfony 3.4, I forgot to register the bundle and set the config.yml as:
knp_doctrine_behaviors:
translatable: true

Get FosUser authenticated to persist into Easy Admin Entity ( USER LOG)

I have An entity Product Manged By EasyAdmin, i ALSO USE fos UserbUNDLE for user Management.
Everything works fine but when i add a new user in easyadmin i have a dropdown of user but i want to have automatically the authenticated user.
I have defined an one to Many relation between User and Product in an attribut of the class Product.
/**
* #ORM\ManyToOne(targetEntity="User")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
private $user;
Product Entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Product
*
* #ORM\Table(name="product")
* #ORM\Entity(repositoryClass="AppBundle\Repository\ProductRepository")
* #Vich\Uploadable
*/
class Product
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="reference", type="string", length=150)
*/
private $reference;
/**
* #ORM\ManyToOne(targetEntity="Type")
* #ORM\JoinColumn(name="type_id", referencedColumnName="id")
*/
private $type;
/**
* #ORM\Column(type="boolean")
*/
public $status;
/**
* #var string
*
* #ORM\Column(name="titre", type="string", length=150)
*/
private $titre;
User :
<?php
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
// your own logic
}
}
How to get it automatically?
Can we have more details ? Both entities and controller because i think your not using the good targetEntity
i had quite the same issue,i mean,in some cases i was needing to get ONLY THE CURRENT LOGGED USER INFO INSIDE MY SELECT, and sometimes i was needing to get the full list of users from the database
maybe the solution i found could help you:
Get the logged user info in the easyadmin select
to make it simple you have to override the easyadmin formbuilder and ask only the currently logged user info
$formBuilder->add('user', EntityType::class, array(
'class' => 'AppBundle:User',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->where('u.id = :id')->setParameter('id',$this->getUser()->getId());
},
));
return $formBuilder;

Best practice - Check if Entity exist before presist

Whats the best practice to check if entity fields exist before persisting it.
Here's the example
Entity
class Pile{
/**
* #var \ABC\CoreBundle\Entity\Record
*
* #ORM\OneToMany(targetEntity="Record")
*
*/
private $records;
/**
* #var \CSC\CoreBundle\Entity\Project
*
* #ORM\ManyToOne(targetEntity="Project")
*
*/
private $project;
/**
* #var string
*
* #ORM\Column(name="Block", type="string", length=255)
*/
private $block;
/**
* #var string
*
* #ORM\Column(name="Type", type="string", length=255)
*/
private $type;
}
class Record{
/**
* #var \CSC\CoreBundle\Entity\Pile
*
* #ORM\ManyToOne(targetEntity="Pile")
*
*/
private $records;
}
There are two controllers that handle the CRUD of Pile and Records.
To create Pile there must not be any duplicate fields [project, block, type]
In Record Controllers I could create Pile together with Record.
Here's the problem where and when do I check the db if a similar Pile entity is created?
Whats the Best Practice?
Copy and paste the query checker in both controller?
Can I use $form->valid() to perform any check in PileType class?
Must I use a service and have both controller to call the service?
In entity life-cycle use pre-insert?
Thanks
Therefore, the fields must be unique?
If so, then it is very simple: UniqueEntity
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
...
/**
* #ORM\Entity
* #UniqueEntity(
* fields={"project", "block", "type"}
* )
*/
class Pile{
/**
* #var \ABC\CoreBundle\Entity\Record
*
* #ORM\OneToMany(targetEntity="Record")
*
*/
private $records;
/**
* #var \CSC\CoreBundle\Entity\Project
*
* #ORM\ManyToOne(targetEntity="Project")
*
*/
private $project;
/**
* #var string
*
* #ORM\Column(name="Block", type="string", length=255, unique=true)
*/
private $block;
/**
* #var string
*
* #ORM\Column(name="Type", type="string", length=255, unique=true)
*/
private $type;
}
You can use a custom validation constraint in your form, so that $form->isValid() will do the check.
Follow this documentation entry on How to create a Custom Validation Constraint to create the custom validator and then inject doctrine into it to do the check.
UPDATE: Well, I didn't know there was an UniqueEntity Constraint already included in Symfony.
To inject doctrine do the following:
services:
validator.unique.unique_pile:
class: ABC\CoreBundle\Validator\Constraints\UniquePileValidator
arguments: [#doctrine.orm.entity_manager]
tags:
- { name: validator.constraint_validator, alias: unique_pile }
The validator class might then look like this:
// src/ABC/CoreBundle/Validator/Constraints/UniquePileValidator.php
namespace ABC\CoreBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class UniquePileValidator extends ConstraintValidator
{
protected $em;
function __construct($em) {
$this->em = $em;
}
public function validate($value, Constraint $constraint)
{
$repo = $this->em->getRepository('ABC\CoreBundle\Entity\Record');
$duplicate_project = $repo->findByProject($value);
$duplicate_block = $repo->findByBlock($value);
$duplicate_type = $repo->findByType($value);
if ($duplicate_project || $duplicate_block || $duplicate_type) {
$this->context->addViolation(
$constraint->message,
array('%string%' => $value)
);
}
}
}
And to be complete, the constraint class:
// src/ABC/CoreBundle/Validator/Constraints/ContainsAlphanumeric.php
namespace ABC\CoreBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/**
* #Annotation
*/
class ContainsAlphanumeric extends Constraint
{
public $message = 'This Pile already exists!';
public function validatedBy()
{
return 'unique_pile';
}
}
Should be nearly copy/pasteable...

how to extend an entity from one bundle to another bundle

i have an already created symfony bundle. i wanted to add another bundle for my application separately. so now im facing a problem that how to extend an entity from old bundle to newly created one. i extended it normally but it giving errors.
i have these 2 bundles,
MyFirstBundle
MySecondBundle
MyFirstBundle entity,
namespace My\FirstBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
*
* #ORM\Table(name="companies")
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
*/
class Company
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*
* #Groups({"list_companies", "company_details", "ad_details"})
*/
private $id;
/**
* #ORM\Column(name="name", type="string", length=50, nullable=true)'
*
* #Groups({"ad_details"})
*/
private $name;
MySecondBundle Entity,
namespace My\SecondBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use My\FirstBundle\Entity\Company as BaseCompany;
class Companies extends BaseCompany
{
public function __construct() {
parent::__construct();
}
}
im not sure that i can extend my entity like this. im getting error when creating forms with this entity
Class "MySecondBundle:companies" seems not to be a managed Doctrine entity. Did you forget to map it?
You need to add the doctrine annotations for the second entity as well.
/**
*
* #ORM\Table(name="companies")
* #ORM\Entity
* #ORM\HasLifecycleCallbacks
*/
class Companies extends BaseCompany
{
public function __construct() {
parent::__construct();
}
}

Resources