Using htmlpurifier with annotations in symfony 2.8 - symfony

I would like to use the htmlpurifier not as a form data transformer, but rather as an annotation in the entities property.
The problem: In the Symfony 2.8 project we use a lot of different types of forms, some using symfonies formbuilder, some via sonata-admin, some using twig and ajax etc ..
So using a transformer and a custom field type is not the way to go.
Also, editing every single create or update action would be overkill.
I've been playing with the idea of an event listener on prePersist, but with such a large amount of different entities in our project we would most likely incur a performance hit if this were to be called on every persist() action. Limiting it to only specific object types would also be painstaking.
Is it possible to use the htmlpurifier bundle as an annotation only on the properties that matter?
eg:
/**
* #var string
*
* #ORM\Column(name="uprename", length=20, nullable=true)
* #htmlpurifier('default')
*/
private $firstName;
Where default would be the default configuration.
bundle: https://github.com/Exercise/HTMLPurifierBundle

Related

Entity Id validation

I am writing REST API, where resources are entities. There is a problem with Id field, which has NoBlank and NotNull constraints (which are logical) when creating new entity - obviously a new entity has no Id before writing to DB. However validation component of course says the entity is not valid. How to overcome this issue without removing the constraints from the Id field?
In my opinion you shouldn't have a constraint on your id.
Url of create should be [POST]/resource and url of edit should be [PUT]/resource/{id}.
(Or POST/PATCH depending on how strictly you are doing rest HTTP methods)
THis way the id is always mandatory.
If you don't want this routing logic, you can use validation groups
/**
* #Assert\NotNull(groups={"create"})
*/
private $id;
/**
* #Assert\NotNull(groups={"create","edit"})
*/
private $whatever;

Symfony Login form with existing user class

I'm trying to use (and understand) how Security works in Symfony. I've created a login form and it works with hard-coded users.
Now I want to use an existing user table in my database. The table has all the requiered fields but with different column names. The entity also exists, also with different names (for example "customUserId" instead of "id").
Something like (with "MAGIC_MAPPING"):
/**
* #ORM\Table(name="custom_user_table")
* #ORM\Entity
*/
class User implements UserInterface, \Serializable
{
/**
* #ORM\Column(name="customUserId", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
* #MAGIC_MAPPING so it links this to the mandatory "id" field
*/
private $customUserId;
...
}
Is there a way to map my existing fields so Symfony uses them for login purpose? Or at least can I make it work without changing my database structure (only the entity class)?
I've tried seleveral actions, from this forum and from Symfony documentation, but it always ends with ugly error I can't fix.
Any idea or lead? Thanks a lot for your help, I've been struggling on this for several hours now...
You have to change the providers configuration inside the security.yml file
here is an example, i use the email field from my administrator entity, I think you can do the same with your entity
providers:
administrator:
entity: { class: Entity:Administrator, property: email }
Try changing the ORM file of that table.
create an ORM file using Command promt.
then edit the orm file .
<mapped-superclass name="FOS\UserBundle\Entity\User" table="your_table_name">
/.../
</mapped>
BenoƮt 's answer help me figure it out. I gave too much attention to Symfony documentation's creation process that I forgot the essential: the UserInterface. No need to map anything, just implement this interface and defined methods like:
public function getUsername() {
return $this->customLogin;
}
Then update the provider configuration (thanks Benoit):
providers:
db_sam_provider:
entity:
class: AppBundle:User
property: customLogin
The other parts are conform to Symfony documentation: here and here

Doctrine2 bug imports 'private' variables from MappedSuperClass when generating entities

I'm using Symfony's entity classes in conjunction with Doctrine's ORM annotation to persist the values to the database. Most tables need a few standard fields, so I have created a base entity that all other entities can extend. According to the documentation this is called a MappedSuperClass: http://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html
// src/Acme/Bundle/Entity/Base.php
namespace Acme\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\MappedSuperclass
* #ORM\HasLifecycleCallbacks()
*/
class Base {
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
// more values...
}
I then create multiple entities that extend this base:
// src/Acme/Bundle/Entity/View.php
namespace Acme\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;
View extends Entity\Base
{
// entity definitions
}
Is this the best way to set default definitions for an entity? If you have better suggestions, let me know.
Next, when I generate entities via:
php app/console doctrine:generate:entities Acme\Bundle
It works great the first time to create the getters and setters, but if I make changes to an entity and generate again, it gives an error like this:
Fatal error: Access level to Acme\Bundle\Entity\View::$id must be protected (as in class Acme\Bundle\Entity\Base) or weaker in /src/Acme/Bundle/Entity/View.php
This is happening because doctrine:generate:entities is importing the 'protected' variables from the MappedSuperClass into the extending entity as 'private'.
Others have complained about this error in other contexts without a solution:
FOSUserBundle generate:entities does not work, Access level of fields too high
https://github.com/FriendsOfSymfony/FOSUserBundle/issues/102
QUESTION: Is doctrine supposed to be importing the protected variables? And is it supposed to be setting them as "private"? Or is this just a known Symfony bug?
It seems like it should not import the protected variables since the #ORM definitions are in the MappedSuperClass already and those are not imported (and when I delete the imported private variables it works fine). But if it does import them, it should not be setting them as private...
I literally have to do a search and replace through all my entities to delete these. Every. Single. Time.
What is the suggested course of action here? If this is a bug, has someone reported this and what is the timeline for fixing? How should I search for this issue on github and report it if it's not reported?
Question 2: As long as this bug exists, is there a way to just generate the getters/setters on a Single Entity?
e.g. php app/console doctrine:generate:entities Acme\Bundle\Entity\View (this doesn't work of course). If I could generate only one entity at a time, it would be less of a hassle deleting all the imported private variables across all my entities.
[EDIT: I have answered this question below]
The answer to #2 is, yes, you can generate entity getters/setters for just one single entity.
From the command line, if you type:
php app/console doctrine:generate:entities --help
You get a list of options. There you will see how to limit entities to bundle, single entity in a bundle, or an entire namespace:
You have to limit generation of entities:
* To a bundle:
php app/console doctrine:generate:entities MyCustomBundle
* To a single entity:
php app/console doctrine:generate:entities MyCustomBundle:User
php app/console doctrine:generate:entities MyCustomBundle/Entity/User
* To a namespace
php app/console doctrine:generate:entities MyCustomBundle/Entity
For the question 1, you need to redefine each primary key when entities are inherited.

How can I use Doctrine Annotations to change a column name in an entity subclass?

I'm using FOSUserBundle with a new Symfony project that has to work with an existing schema. My user entity extends FOS\UserBundle\Entity\User as the instructions say, but the email column is named "email_addr" instead of "email". Since the parent defines $email I can't re-declare it to attach my annotation.
/**
* #var string $emailAddr
*
* #ORM\Column(name="email_addr", type="text", nullable=false)
*/
protected $email;
The exception I get is:
[Doctrine\ORM\Mapping\MappingException]
Property "email" in "Foo\DataBundle\Entity\User" was already declared, but it must be declared only once
My question is either:
How can a Doctrine2 subclass use an annotation to alter something defined in the parent?
Or how can I override column names in the FOSUserBundle?
I found an answer:
More about Doctrine implementations
If you need to change the mapping (for instance to adapt the field names to a legacy database), the only solution is to write the whole mapping again without inheriting the mapping from the mapped superclass. In such case, your entity should extend directly from FOS\UserBundle\Model\User (and FOS\UserBundle\Model\Group for the group).
It looks like doctrine 2.3 added these features. Unfortunately, SO decided that I had to duplicate information already present on their site to avoid a "trivial answer".
#AssociationOverride and #AttributeOverride in new Doctrine 2.3

Extend Symfony2 White October Admin Bundle Form Fields?

This question is quite specific.
I'm using Symfony2 White October Admin Bundle for generating administration for my application.
I wonder if anyone has experience with this bundle and knows how to modify specific fields added to Admin class. The bundle is not documented very well and I'd like to know, if there are methods for doing this, or does the bundle core need to be extended.
For example I've got a Speaker entity with a field storing the path to one's avatar:
/**
* #var string $picturePath
*
* #ORM\Column(name="picture_path", type="string", length=128, nullable=false)
*/
private $picturePath;
Then in the Admin class I'm adding the field:
protected function configure()
{
...
...
->addFields(array(
...
...
'picturePath'=> array("label" => "Avatar"),
));
}
Is there an easy way to tell the bundle that I'd like this field to be an upload field instead of a text field, and define extra methods to call after submitting the form? (e.g. resize the image, store it, and then just store the image path in the DB)
As I haven't found any solution yet, I had to rape my entities to do that. So I modified the basic setter methods to call other methods inside the entity that do the dirty job. This is not a solution, and I'll still be happy if I could find better answers here.

Resources