Can I create a read only timestamp field in Doctrine? - symfony

I followed this question to create timestamps that save on create and update maintained by the database: Doctrine2 - Type timestamp - Default value
Problem is that now I get a "value cannot be null" when saving a record using Doctrine. I see in the generated insert that it's trying to save the timestamps as null. Is there a way to avoid Doctrine setting a column on INSERT/UPDATE.

Why do you want letting DB to do Doctrine job?
Doctrine won't set a column at all, if you don't map it. But would you take a look to Timestampable extension?
Another approach is using Doctrine entity listeners. So you can make your own, on PrePersist and PreUpdate and set the time there.
If you're worrying about setters for changing dates, you can at least use dynamic mapping for that fields (just map datetime properties on-the-fly when you really need to change them). Not sure that you can use reflection though, because your entity can be behind the proxy class.
If you still want keeping business-logic in Database, you can map only fields you really want to change (not datetime fields in your case), then write custom Doctrine hydrator (just extend their AbstractHydrator class) that will populate all the fields you need (include datetime). Also you can configure your new hydrator as default (i.e. in Doctrine configuration section in config.yml), so it will work without any adjustments.

Related

How to set a deleted property to true rather than removing a related doctrine entity in Symfony

I'm building an app that allows a user to create reports for advertisers. The entities are set up so that there is a relation between the Report object and the Advertiser object - so that the advertiser has a getReports() method to get them.
I would like to change the app so that instead of actually deleting entities, that it simply changes a "deleted" property to true. That part is no problem, but I'm unsure how to make it so that the getReports() on the Advertiser entity only returns reports for the advertiser that have a deleted property of false.
Please let me know if you have any suggestions how that should be done in accordance with Symfony best practices.
You should look into Gedmo Doctrine Extensions. http://atlantic18.github.io/DoctrineExtensions/
Specifically for your case:
http://atlantic18.github.io/DoctrineExtensions/doc/softdeleteable.html
TLDR; they allow you to configure behavior of your entities in a way you desire, so for example when you "delete" an entity, Gedmo's listeners would set it's deleted value to a current datetime. Now you'd still have that record in your database but with not null value of deleted column marking it 'soft deleted', so when querying, it wouldn't be returned (because Doctrine knows how to query these stuff and would add a condition i.e.: ... where deleted ...) unless you explicitly say you want to see those soft deleted records.

Saving a newly created entity with default values from config file that are immutable for subsequent persists

I have a requirement, using Doctrine to save an entity with preset values that are populated from application configuration.
There are multiple applications, sharing same codebase, with different configurations.
My initial idea was to use a pre-persist listener, load config values and be done, but the problem is, these attributes should NOT be changed after entity is created, even if the configuration file changes the original entity's configuration needs to stay as they were initially. Even if entity is loaded in a form and resaved with other values changed, these specific initial applicatin settings should only be set on entity creation and kept for the entire lifecycle of the entiy as they were at the start.
I understand, it is possible to set the values on the entity with the setters of the entity, but since these entities are created at various places in the application my thought was that using a pre-persist hook would reduce code duplication.
Is there a way to detect if an entity is newly created, or another listener I could use? I skimmed through the documentation and did not see listeners specific to object creation.
I thought maybe on first pre-persist, some entity attributes such as "created" is possibly not set on first pre-persist called, when object is created and persisted for the first time.
Is there a way to achieve what I am trying to do, some way to set values on entity creation that is immutable over subsequent persists?
You are on the right way. Of course you can use the prePersist event as they pointed out in the docs
https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/events.html#lifecycle-events
prePersist - The prePersist event occurs for a given entity before the
respective EntityManager persist operation for that entity is
executed. It should be noted that this event is only triggered on
initial persist of an entity (i.e. it does not trigger on future
updates).
I would also add a constraint to the entity, that saving your entity with empty value for your desired fields is not possible. So it's ensured that there is no inconsistency.

doctrine:schema:update wants to create an already existing view in symfony 2.8

I have an existing view in my SQL database "view_account" which represents a account entity. This view is read only and has no primary_key field. Actually it has a primary key "id" but the field is not declared as primary key. I can also not change the table design, because its an automatic export from another application generating this tables (the automatic export is every week).
But thats not the problem cause doctrine don't care about "primary key" flag in the database until you don't update the schema.
But whenever i try to "doctrine:schema:update --force" doctrine wants to create this table. How can i ignore this view (or better the entity) from updating by doctrine? Marking the entity read_only with doctrine annotation is not working. Extending a own update-command will also not work, as i found out, it will not work since doctrine 2.4.7 to extend the doctrine-schema-update command (the update command method is ignored in any way).
Whats the best solution?
Edit:
I also tried to configure two entitymanager. One for the "internal" entities and for the "foreign" entities. Since all entities are linked to each other on some point, it is also not possible to have two separated manager don't knowing from each other entities.

Symfony2 - extending existing non-abstract entity?

Let's say I have a Setting entity with some fields like IntValue, dateValue, stringValue and some linked entities, like countries (ManyToMany to entity Country), languages (ManyToMany to Language) etc.
Settings are created by users and assigned to specific objects (not important here, but I wanted to clarify).
Now I suddenly need to have UserDefaultSetting, which will be the same, but with additional user field (ManyToOne to User entity).
I tried to extend existing Setting entity class with one more field added. The problem is, as I looked at the schema update SQL, it created new table for the new entity, but without all the tables needed to ORM connections (mostly ManyToMany). Just one table with "scalar" fields.
So previously I've had setting table with int_value, date_value etc. but also setting_country and setting_language tables, linking ManyToMany relations. After creating child entity, Doctrine created only user_default_setting table with int_value, date_value etc. and additionally user_id column, but I can't see any relation/link tables.
I know I should've been do it with abstract base entity class, but at the time I started, I didn't know that and now part of the project is on production (don't look at me like that, I blame the client) and I don't want to change that "base" class now. Can I inherit everything from non-abstract entity class in a way it will work?
UPDATE: everything explained. See Cerad's comment. Thanks!

Symfony Mapping in Doctrine without Annotations or XML Files

a customer has an existing database. The schema is often changed within the database itself (e.g. he adds a new column).
My task is to develop an admin area with symfony that automatically reacts on table schema changes without modifying the application code. E.g. the customer adds a new column to table "MyEntity", and the application automatically generates a new column in the accordingly list view.
My approach is to dynamically map the table columns to the Entity class so that ALL Attributes and ALL Getters/Setters are generated dynamically from the table schema.
So is it possible to map the table columns in a Doctrine Entity without the use of Annotations or XML Files.
Something like:
class MyEntity{
public function generateMappingFromSchema($sTableName){...}
}
Please don't do that. Doctrine was not designed for such use case.
There is a library though you should check https://github.com/laravel-doctrine/fluent which basically is a mapping driver that allows you to manage your mappings in an Object Oriented approach. And there are other tools:
http://crud-admin-generator.com/
http://crudkit.com/
http://www.grocerycrud.com/
which are maybe better for that, I don't know.
But again, please don't do that. Do not allow the customer to modify the database schema or give them e.g. a phpMyAdmin which was designed for that.

Resources