Very simple question I'm not able to find a good answer for...
I have a lot of Entities in my Symfony 2.6 - when ever a user makes some changes to any one of them I would like to have a log entry with who/what/where.
Who maked the changes. (user id)
What did he/she do. ( POST/PUT data)
Where was this done (which entity / url)
[EDIT]
It could perhaps just be a table with these columns:
userid
data
entity
created
[/EDIT]
Is there a bundle for this?
For my projects I usually use the EntityAudit bundle. What it does is save a copy of the old state whenever an audited entity is changed. By comparing those to the current version you can see what has changed.
It also gives you a revision history that lists all the entities that have changed in your database.
You have several Bundles out there that do this, a couple of which have already been mentioned. I've had a lot of success with Gedmo Doctrine Extensions.
Some Documentation here: http://symfony.com/doc/current/cookbook/doctrine/common_extensions.html
And installation instructions here:
https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/symfony2.md
The installation is the tough part. Once that's done, all you need to do is annotate any entity fields you wish to log.
Related
I've started to refactor the ext:crawler to make it compatible with TYPO3 9LTS.
Currently we have a domain model based only on a database table + a TCA configuration:
https://github.com/AOEpeople/crawler/blob/master/ext_tables.sql#L48
https://github.com/AOEpeople/crawler/blob/master/Configuration/TCA/tx_crawler_configuration.php
I want to add a regular Domain Model and Repository for the Configurations instead, to benefit more from the code from TYPO3 Core.
My problem is currently:
I don't know how to migrate data from the already existing table tx_crawler_configuration to the new tx_crawler_domain_model_configuration without the users are loosing any data, or need to do any manual work.
I haven't found anything on this topic yet. I know I can "use foreign data source" but it's not foreign data, so not sure this is the best approach.
https://docs.typo3.org/typo3cms/ExtbaseFluidBook/6-Persistence/4-use-foreign-data-sources.html
I appreciate your input, thanks.
Torben Hansen just did something similar, when he migrated sf_bannners from using own Category concept to use the sys_category concept of TYPO3
What he does is creating a ext_update.php script that is being called automatically upon installation. You can see his commit here
https://github.com/derhansen/sf_banners/commit/02c2c6f1729b96940bb4dd0ca29761fe48d28c14
and probably catch him on Slack with any questions
We have factories for creating complex objects. (For makin' stuff)
We have repositories for find them. (For findin' stuff)
What do we have for updating them? (For changin' stuff up)
Seems like a missing piece in the puzzle? I don't think it belongs in repositories, as that breaks single responsibility...
Updating an Entity (and so, the database) belongs to the Repository. The Repository itself is an Layer between the Database itself and the program.
Every Database Operation therefore belongs to the Repository. Also, a Repository mustn't communicate with a database, it also could have an XML, CSV or API as data source. But that doesn't matter, because you're communicating with the Repository. The Repository deals with all that's coming afterwards.
You could just change the Repository with another one and your program would work without any problems, because the repositories all implement the same interface. You don't like that MySQL Database anymore, that old fashioned CSV is much better? Just replace the used Repository and you're done.
Finding an entry with an repository isn't more than a SELECT statement, so why won't you UPDATE or DELETE with it?
Further reading on the MSDN
Found a great explanation and example on web.archive.org
I think it depends on approach.
With DDD for example what You are saying is true. Repository should be responsible for adding, finding and removing, because it works on a collection, but there is a question why it should be able to update a single object.
What can be done? I think I will only copy what other person said, so I wil just post link to answer: approach to removing save/update from repository
I'm using the latest version dev-master of Doctrine extensions with Symfony2.7.0.
I added both extensions Softdeleteable and Translatable to my entity. The problem is that when the entity gets soft-deleted its translation gets hard-deleted.
Is there a workaround this?
Edit
I have found this issue on Github, but I can't make much of the answer.
After reviewing the github issues and the proposed "fixes" and consulting experts I have decided that this was more trouble than its worth.
The problem is obviously the listner, and I shouldn't be messing with the bundles under vendor.
When translatables get the 'delete' from my soft-deleted object, these "children" of my object are not really objects of their own thus can't be configured to be soft-deleted.
My solution is to add a deletedAt attribute, NULL by default and when in my controller I used to execute $entityManager->delete($object) I now, just have to change the value of deletedAt to the current DateTime. $object->setDeletedAt($date).
And when retrieving objects I just add a clause SELECT * FROM table_name WHERE deletedAt IS NULL;
This implies changing a lot of queries but it is the simplest option while waiting for a fix.
Im using SonataAdminBundle - more specificly the SonataORMAdminBundle with Doctrine - to do some of my administration. So far this turned out to be a really useful Bundle, however a senseful deletion of entities is somewhat tricky.
Consider a Tour entity has a Truck and a Trailer entity, but when a Truck is being discarded it should no longer appear in the overall Admin Application. Nevertheless, there might still exists legacy Tour entities with a relation to this Truck.
So it is unclear how to tackle this problem when a user might edit such a legacy Tour in the admin, is the entity selection gone?
I've taken a look at the SoftDelete Extension Bundles, but it seems to come with a lot of work for adjusting all the specific cases.
Is there a simple approach at the Bundle Level or in Doctrine in General tackle those kind of problems?
The way this behavior is implemented when needed in the Sonata suite is through a new boolean field in the entity: 'enabled'. We then add a filter on it to display it or not, and never actually delete the object in the usage. Soft-deletion being a client-specific operation (you might have dedicated business rules along with it), we didn't implement it natively in the Sonata suite. Your implementation should depend on your needs in this case.
We however integrated the EntityAuditBundle from Simplethings (https://github.com/simplethings/EntityAudit) in the SonataDoctrineORMAdminBundle: each entity which has an Admin class is audited automatically. This allows to track each edit done on the audited entities. (Not necessarily what you're looking for but might be interesting nonetheless).
Finally, as you mentioned, SoftDelete might do the trick for you. But you might rather have your own event listeners (using preRemove for instance) and implement your solution your own way.
If you think your solution might be worth integration in the SonataDoctrineORMAdminBundle, feel free to create an issue on github, and we'll discuss it.
So heres the scenario:
Currently we have a development site with 3 models. We found we didn't like our initial schema and added a few rows. We re-generated the schema (doctrine:build-sql).
Now it forced us to drop and re-create all the tables and dump back in all the information as no ALTERS were created but rather CREATE statements only. Not a problem...
The big problem came to updating the models. After we ran a build-all and such a few errors popped up i.e. "Widget sort not found" etc. We figured out we needed to rebuild the models. So we can a symfony doctrine:build-models course Course (Course was the table name...course the models). This worked great and fixed the broken links within Symfony.
The downside is all custom code in the actions.class.php file was lost as were customizations to the _form.php page.
My question on this is, how do we store our own actions so they are not lost if you update a models schema? Similarly templates and such are re-generated to but do not hold any customizations.
There surely must be a simple solution to updating a model's schema in symfony?
Found my answer to this. You don't update the module per say but the models of the database. You can change your schema.yml file and do a symfony migration
http://www.slideshare.net/denderello/symfony-live-2010-using-doctrine-migrations
If you just want CRUD/minimal customisation, you can do this with the admin generator:
./symfony doctrine:generate-admin appname Course
A regular module can't be updated once generated without losing customisations - they are intended to be a starting point.