Git Product home page Git Product logo

entityauditbundle's Introduction

EntityAuditBundle

This extension for Doctrine 2 is inspired by Hibernate Envers and allows full versioning of entities and their associations.

Latest Stable Version Latest Unstable Version License

Total Downloads Monthly Downloads Daily Downloads

Branch Github Actions Code Coverage
1.x Test Coverage Status
2.x. Test Coverage Status

Support

For general support and questions, please use StackOverflow.

If you think you found a bug or you have a feature idea to propose, feel free to open an issue after looking at the contributing guide.

License

This package is available under the LGPL license.

How does it work?

There are a bunch of different approaches to auditing or versioning of database tables. This extension creates a mirroring table for each audited entitys table that is suffixed with "_audit". Besides all the columns of the audited entity there are two additional fields:

  • rev - Contains the global revision number generated from a "revisions" table.
  • revtype - Contains one of 'INS', 'UPD' or 'DEL' as an information to which type of database operation caused this revision log entry.

The global revision table contains an id, timestamp, username and change comment field.

With this approach it is possible to version an application with its changes to associations at the particular points in time.

This extension hooks into the SchemaTool generation process so that it will automatically create the necessary DDL statements for your audited entities.

Installation

Installing the bundle

Simply run assuming you have composer:

$ composer require sonata-project/entity-audit-bundle

Enable the bundle

Finally, enable the bundle in the kernel:

// config/bundles.php

return [
    //...
    SimpleThings\EntityAudit\SimpleThingsEntityAuditBundle::class => ['all' => true],
    //...
];

Configuration

Load extension "simple_things_entity_audit" and specify the audited entities

# config/packages/entity_audit.yaml

simple_things_entity_audit:
    audited_entities:
        - MyBundle\Entity\MyEntity
        - MyBundle\Entity\MyEntity2

If you need to exclude some entity properties from triggering a revision use:

# config/packages/entity_audit.yaml

simple_things_entity_audit:
    global_ignore_columns:
        - created_at
        - updated_at

In order to work with other connection or entity manager than "default", use these settings:

# config/packages/entity_audit.yaml

simple_things_entity_audit:
    connection: custom
    entity_manager: custom

If you need to explicitly discard the foreign keys inferred from the audited entities, you can use the disable_foreign_keys parameter:

simple_things_entity_audit:
    disable_foreign_keys: true

Creating new tables

Call the command below to see the new tables in the update schema queue.

./bin/console doctrine:schema:update --dump-sql

Installation (Standalone)

For standalone usage you have to pass the entity class names to be audited to the MetadataFactory instance and configure the two event listeners.

use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\Common\EventManager;
use SimpleThings\EntityAudit\AuditConfiguration;
use SimpleThings\EntityAudit\AuditManager;
use SimpleThings\EntityAudit\Tests\ArticleAudit;
use SimpleThings\EntityAudit\Tests\UserAudit;

$auditConfig = new AuditConfiguration();
$auditConfig->setAuditedEntityClasses([ArticleAudit::class, UserAudit::class]);
$auditConfig->setGlobalIgnoreColumns(['created_at', 'updated_at']);

$eventManager = new EventManager();
$auditManager = new AuditManager($auditConfig);
$auditManager->registerEvents($eventManager);

$config = new Configuration();
// $config ...
$connection = [];
$entityManager = EntityManager::create($connection, $config, $eventManager);

Usage

Querying the auditing information is done using a SimpleThings\EntityAudit\AuditReader instance.

use SimpleThings\EntityAudit\AuditReader;

class DefaultController extends Controller
{
    public function indexAction(AuditReader $auditReader)
    {
    }
}

In a standalone application you can create the audit reader from the audit manager:

$auditReader = $auditManager->createAuditReader($entityManager);

Find entity state at a particular revision

This command also returns the state of the entity at the given revision, even if the last change to that entity was made in a revision before the given one:

$articleAudit = $auditReader->find(
    SimpleThings\EntityAudit\Tests\ArticleAudit::class,
    $id = 1,
    $rev = 10
);

Instances created through AuditReader#find() are NOT injected into the EntityManagers UnitOfWork, they need to be merged into the EntityManager if it should be reattached to the persistence context in that old version.

Find Revision History of an audited entity

$revisions = $auditReader->findRevisions(
    SimpleThings\EntityAudit\Tests\ArticleAudit::class,
    $id = 1
);

A revision has the following API:

class Revision
{
    public function getRev();
    public function getTimestamp();
    public function getUsername();
}

Find Changed Entities at a specific revision

$changedEntities = $auditReader->findEntitiesChangedAtRevision(10);

A changed entity has the API:

class ChangedEntity
{
    public function getClassName();
    public function getId();
    public function getRevisionType();
    public function getEntity();
}

Find Current Revision of an audited Entity

$revision = $auditReader->getCurrentRevision(
    'SimpleThings\EntityAudit\Tests\ArticleAudit',
    $id = 3
);

Setting the Current Username

Each revision automatically saves the username that changes it. For this to work, the username must be resolved.

In the Symfony web context the username is resolved from the one in the current security context token.

You can override this with your own behaviour by configuring the username_callable service in the bundle configuration. Your custom service must be a callable and should return a string or null.

# config/packages/entity_audit.yaml

simple_things_entity_audit:
    service:
        username_callable: acme.username_callable

In a standalone app or Symfony command you can set an username callable to a specific value using the AuditConfiguration.

$auditConfig = new \SimpleThings\EntityAudit\AuditConfiguration();
$auditConfig->setUsernameCallable(function () {
	$username = //your customer logic
    return username;
});

Viewing auditing

A default Symfony controller is provided that gives basic viewing capabilities of audited data.

To use the controller, import the routing (don't forget to secure the prefix you set so that only appropriate users can get access)

# config/routes.yaml

simple_things_entity_audit:
    resource: "@SimpleThingsEntityAuditBundle/Resources/config/routing/audit.xml"
    prefix: /audit

This provides you with a few different routes:

  • simple_things_entity_audit_home - Displays a paginated list of revisions, their timestamps and the user who performed the revision
  • simple_things_entity_audit_viewrevision - Displays the classes that were modified in a specific revision
  • simple_things_entity_audit_viewentity - Displays the revisions where the specified entity was modified
  • simple_things_entity_audit_viewentity_detail - Displays the data for the specified entity at the specified revision
  • simple_things_entity_audit_compare - Allows you to compare the changes of an entity between 2 revisions

TODOS

  • Currently only works with auto-increment databases
  • Proper metadata mapping is necessary, allow to disable versioning for fields and associations.
  • It does NOT work with Joined-Table-Inheritance (Single Table Inheritance should work, but not tested)

entityauditbundle's People

Contributors

andrewtch avatar atsiddiqui avatar beberlei avatar befresh-mweimerskirch avatar bendavies avatar bobvandevijver avatar c0ntax avatar davidbadura avatar dunglas avatar franmomu avatar ivariable avatar javierjimenez avatar jordisala1991 avatar merk avatar mweimerskirch avatar oskarstark avatar phansys avatar royopa avatar rvanlaak avatar savagedays avatar smoench avatar sonataci avatar soullivaneuh avatar theratg avatar tolry avatar tommygnr avatar vincentlanglet avatar wbloszyk avatar welante avatar x-coder264 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

entityauditbundle's Issues

Issue combine Gedmo\Slug

Hi,

I try to use gedmo Slug with your bundle but when i try to create new record i have an constraint error message

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '853-239' for key 'PRIMARY'

Here the debug result message, as you cas see, res_bien_audit is call two times

DEBUG - SELECT r0_.slug AS slug0 FROM res_bien r0_ WHERE (r0_.slug LIKE 'my string to slugify%') AND r0_.discr IN (.)
DEBUG - "START TRANSACTION"
DEBUG - INSERT INTO res_bien (....) VALUES (...)
DEBUG - INSERT INTO revisions (timestamp, username) VALUES (?, ?)
DEBUG - INSERT INTO res_bien_audit (...) VALUES (...)
DEBUG - UPDATE res_bien SET .... WHERE id = ?
DEBUG - INSERT INTO res_bien_audit (...) VALUES (...)
DEBUG - "ROLLBACK"

The error disapear when I do not use Gedmo Slug notation.

Do you have any idea how to get rid of this error ?

regards

Entites with properties containing an underscore don't work

When finding an Entity at a specific revision with an underscore property I get the following error:

Notice: Undefined index: username_canonical in
/Applications/MAMP/htdocs/xxx/
vendor/simplethings/entity-audit-bundle/src/
SimpleThings/EntityAudit/AuditReader.php line 132

It doesn't work because $this->em->getConnection()->fetchAssoc(...) returns this field as usernameCanonical.

Unchanged DateTime fields listed as changed between revisions

When comparing revisions of entities containing a DateTime field (e.g. "createdAt"), the field is treated as having changed even though it hasn't.

I assume this is because of line 44 in the ArrayDiff class.

Is there a suggested workaround / fix?

Tag a new release

Can you tag a new release? The current stable is 10 month old and miss a lot of bug fixes and enhancement.

Can't login after declaration in AppKernel.php (JSON issue?)

I'm having a "little" problem just after declare EntityAuditBundle on AppKernel.php: I just can't login (using SonataAdmin). If I comment that line, everything works just fine, even if I don't configure it in config.yml and routing.yml (I guess there's nothing to do with autoload.php). Just to put the line new SimpleThings\EntityAudit\SimpleThingsEntityAuditBundle() on AppKernel.php cause and error after login into the web application.

The thing is the error doesn't say anything useful to solve the problem:

FatalErrorException: Error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 43520197 bytes) in /var/git/mercury/mercury/app/cache/dev/classes.php line 4630

That line only returns a json_encode value: return @json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); which belongs to this method:

protected function toJson($data, $ignoreErrors = false)
{
    if ($ignoreErrors) {
        if (version_compare(PHP_VERSION,'5.4.0','>=')) {
            return @json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
        }
        return @json_encode($data);
    }
    if (version_compare(PHP_VERSION,'5.4.0','>=')) {
        return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    }
    return json_encode($data);
}

The only thing is missing in the configuration is the autoload.php declaration, but I'm using Symfony 2.3, so that step is obsolete in my case. All the steps has been completed, even the audit tables creation in the database.

I'm using Symfony 2.3.8, EntityAudit 0.5.1 and Doctrine ORM Admin 2.2.5.

Seems like I'm the only one having this weird issue. Any ideas what causes it?

Allow tagging of version

It would be nice to have a particular version tagged similar to git. It doesn't have to be unique.

Then add revertByTag() method to repository class

Undefined index when i delete an entity which is audit

Notice: Undefined index: titre in MyPath\vendor\simplethings\entity-audit-bundle\src\SimpleThings\EntityAudit\EventListener\LogRevisionsListener.php line 206

Entity User :

/**
* @Orm\OneToOne(targetEntity="MyProject\ReveBundle\Entity\Reve", cascade={"persist", "remove"})
*/
protected $reve;

Action in my Reve repository to remove :

$user->setReve();
$this->_em->persist($user);
$this->_em->remove($reve);
$this->_em->flush();

It's work when the entity is not audit.

Thanks for you help

Retrieve audited OneToMany relations

Hi,

I have an entity named Company which has a OneToMany relationship with another called CompanyLot.

The relation is described by the following in my MYDIR\CoreBundle\Entity\Entity\Company.php:

    /** 
    * @ORM\OneToMany(
    *     targetEntity="MYDIR\CoreBundle\Entity\CompanyLot",
    *     mappedBy="company",
    *     cascade={"persist","remove"}
    * )
    */
    private $companyLot;

Both "Company" and "CompanyLot" are audited, and I see the modifications in xxx_audit tables.

When I fetch the different revs of Company, I need to get the "CompanyLot"s that where attached to it at the time of the revision.

I'm doing this:

$company = $auditReader->find('MYDIR\CoreBundle\Entity\Company',$id,$rev_number);
$companyLots = $company->getCompanyLot();

But $companyLots is always empty. Is my coding wrong or maybe I misunderstood some of EntityAudit limits.

Thank in advance you for your help :)

Entity traversing

Current implementation of AuditReader is a bit inflexible (e.g. it's not possible to count revisions, get all history for a particular class - e.g. I want to see all User changes with no id limits, also see #63 and #20).

I'd like to have, at least, following methods:

  • getRevisionCount()
  • getEntityHistory(array $entityClasses)

If this is OK, I'll make a PR.

Troubles with fresh install (autoload.php)

Hi,

Got this error with a fresh install:

"Fatal error: Class 'SimpleThings\EntityAudit\SimpleThingsEntityAuditBundle' not found in /var/www/app/AppKernel.php on line 27"

Had to change my autoload.php file to use this source instead:

'SimpleThings\EntityAudit' => DIR.'/../vendor/bundles/SimpleThings/EntityAudit/src',

Inspired by Hibernate Envers, is it compatible?

So the readme says this is inspired by Hibernate Envers, does this mean it's also compatible with it? If I have a Hibernate based project with a Symfony2 project, will they work together?

Join Table Inheritance

Hi,

I understand join table inheritance is not currently implemented in this bundle. Are there any plans to implement it? I would love to use this bundle, but unfortunately, without this implementation, I can't use it :( I am currently trying to implement it myself but not having much luck.

Thanks

Using the same entity in both OneToMany and OneToOne

I have found an error while versioning entities like: (error is while auditing Customer entity)

class Address
{
    /**
     * @ORM\Column 
     */
    protected $address_text;

    /**
     * @ORM\ManyToOne(targetEntity="Customer", inversedBy="addresses") 
     */
    protected $customer;
}



class Customer 
{
    /**
    * @ORM\OneToMany(targetEntity="Address", mappedBy="customer")
    */
    protected $addresses;

    /**
    * @ORM\OneToOne(targetEntity="Address")
    */
    protected $primary_address;
}

the UnitOfWork::getEntityIdentifier throws an notice "Undefined index: ........"
in UnitOfWork::entityIdentifiers array - the hash is different that the stored one

TESTED ON Doctrine 2.1.3 and 2.1.6

getOriginalEntityData seems to return the new data

I'm trying to use this EntityAudit extension and i'm forking it for using it in a Zend Framework application. But there seems to be one problem, in the Entity_audit table the LogRevisionsListener writes the NEW data into the table and that's not what you want.

I either think that this wasn't ment to because when a audited entity gets updated I see $this->uow->getOriginalEntityData() which you would expect to original data is returned but that's not the case.

I'm trying to debug this but in the UnitOfWork class $this->originalEntityData[$oid] is changed many times so it's hard to find where this happends.

Are you familiair with this problem? Is there already a fix?

I'm using Doctrine 2.1.2 with Zend Framework glued with Bisna.

Field names are not escaped

DBALException: An exception occurred while executing 'SELECT lft AS left, rgt AS right, lvl AS level, global AS global, id AS id FROM su_Template_audit e WHERE e.rev <= ? AND id = ? ORDER BY e.rev DESC' with params [5, "016zsta0f0004ogs4wok"]:
Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'left, rgt AS right, lvl AS level, global AS global, id AS id FROM su_Template_au' at line 1

EntityAudit not generating any revision tables at all

I'm trying to use your EntityAudit bundle, but when I ran the schema update command nothing happens. No revision tables were generated at all. The only table that got created is "revisions". I ran this command:

$ php app/console doctrine:schema:update --dump-sql
$ php app/console doctrine:schema:update --force

And of course, never saw anything about creating my selected revision tables. When I say selected, I went into my app/config/config.yml and added these entries:

simple_things_entity_audit:
    audited_entities:
        - src\MyCompany\EntityBundle\Entity\Name
        - src\MyCompany\EntityBundle\Entity\PhoneNumber
        - src\MyCompany\EntityBundle\Entity\Avatar

After adding these entries and running the schema update, I should be able to see Name_audit, PhoneNumber_audit, Avatar_audit? correct?
I did also try just adding the entries by just saying "EntityBundle\Entity\Name" as shown in the ReadMe file, but that didn't work at all too.

Any help would be appreciated, many thanks in advance!

Exclude columns from triggering a revision

I have some table columns which I don't want to track. It would be nice to ignore some columns and not trigger a revision if only one of these column values changed.

Working with relations (translation bundle)

Hi, i using translation bundle https://github.com/a2lix/TranslationFormBundle
And Audit bundle don't create any schema for relation tables automatically.

Its work only if i prescribed in the manual as in example

    simple_things_entity_audit:
        audited_entities:
            - MyBundle\Entity\MyEntity
            - MyBundle\Entity\MyEntity2

Can you check this, please.

And how to show in SonataAdmin history page with translation field ?
May be have some examples ?

Error thrown in audit/viewent with DateTime fields in entity

An exception has been thrown during the rendering of a template ("Catchable Fatal Error: Object of class DateTime could not be converted to string in app/cache/dev/twig/32/20/728a51b7c5307253f040a251085b.php line 62") in SimpleThingsEntityAuditBundle::layout.html.twig at line 1.

I suppose I could override the template and deal with the DateTime to string conversion myself. But I'm just playing around with this bundle at the moment.

retrieve entities as they were at a specific revision

I would like to be able to 'snapshot' data by getting all entities as they were at a specific revision number.

One way to achieve this might be to modify AuditReader::find such that a NULL $id parameter results in returning an array of 'latest' (greatest revision number equal to or less then the target revision number and not deleted) entities.

https://github.com/simplethings/EntityAudit/blob/master/src/SimpleThings/EntityAudit/AuditReader.php#L55

Happy to fork and submit a pull request if this approach sounds do-able and the feature is desirable.

Impossible to create trigger for revisions table on Oracle

On Oracle database, it is not possible to create the trigger for the table REVISIONS because EntityAudit uses a reserved word (see http://docs.oracle.com/cd/B19306_01/em.102/b40103/app_oracle_reserved_words.htm).

When I try to create the trigger, I obtain this error :

CREATE TRIGGER REVISIONS_AI_PK
BEFORE INSERT
ON REVISIONS
FOR EACH ROW
DECLARE
last_Sequence NUMBER;
last_InsertID NUMBER;
BEGIN
SELECT REVISIONS_SEQ.NEXTVAL INTO :NEW.id FROM DUAL;
IF (:NEW.id IS NULL OR :NEW.id = 0) THEN
SELECT REVISIONS_SEQ.NEXTVAL INTO :NEW.id FROM DUAL;
ELSE
SELECT NVL(Last_Number, 0) INTO last_Sequence
FROM User_Sequences
WHERE Sequence_Name = 'REVISIONS_SEQ';
SELECT :NEW.id INTO last_InsertID FROM DUAL;
WHILE (last_InsertID > last_Sequence) LOOP
SELECT REVISIONS_SEQ.NEXTVAL INTO last_Sequence FROM DUAL;
END LOOP;
END IF;
END;;
Rapport d'erreur :
ORA-06552: PL/SQL: Compilation unit analysis terminated
ORA-06553: PLS-320: déclaration de type de cette expression est incomplète ou mal structurée
06552. 00000 - "PL/SQL: %s"
*Cause:
*Action:

A solution is to replace the timestamp column name. For details, see http://www.lattimore.id.au/2007/03/09/ora-06552-plsql-compilation-unit-analysis-terminated/

Store audit data in a separate database

Great extension, thanks!

I'd like to store audit data in a separate database, potentially on a different physical server.

Is such a thing even possible ?

If it's just supplying the config option for new entity manager and using it in LogRevisionsListener, then I can do it and create a pull request, it just seems too easy to not be in there already :)

Zend Framework 2 Module

Hello ,
I am trying to create ZF2 Module for EntityAudit , in this Repo https://github.com/tawfekov/ZF2EntityAudit
I was able to integrate EntityAudit into ZF2 ,
getting AuditManager would be like ( in controller class )

$auditManager = $this->getServerLocator()->get("auditManager");

and auditReader :

$auditReader  = $this->getServerLocator()->get("auditReader"); 

but when creating the tables using doctrine cli , it doesn't create the version-ed table

can any body suggest a solution ???

after that I will work in the viewing auditing

Compare.html.twig DateTime errors

When rendering the compare.html.twig view, errors are generated by the following variables which need to be presented as date strings

{{ value.old }}
{{ value.same }}
{{ value.new }}

I have added the Twig date() filter e.g.

{{ value.old|date('jS M Y H:i') }}

However, I still run in to problems with the "value.same" parameter - Twig is reporting

"DateTime::__construct(): Failed to parse time string (556.00) at position 0 (5): Unexpected character"

I am running Symfony 2.5.0 with Doctrine / MySQL / PHP 5.5.9-1

Problem, how use PostgreSQL and Sonata sandbox

PostgreSQL 9.1 and sonata-sandbox
Issue in sonata-project
When used PostgreSQL, command sonata:page:update-core-routes raises an exception:

[PDOException] 
  SQLSTATE[23505]: Unique violation: 7 ERROR:  duplicate key value violates 
  unique constraint "page__page_audit_pkey" DETAIL:  Key (id, rev)=(4, 0) already exists. 

Before this command run:

`````` doctrine:database:create doctrine:schema:create```
```doctrine:fixtures:load```

When used MySQL, everything is working properly

Method prepareUpdateData does not exist

Hi,

when I use EntityAudit and SoftDeleteable on the same entity and I remove this entity, I got this error :

ReflectionException: Method prepareUpdateData does not exist in SimpleThings/EntityAudit/EventListener/LogRevisionsListener.php line 114

Seems that entityAudit is launched two times and the second time I got this error. Also, putting this on line 114 resolves the issue but I don't know the consequences :

if (!$persisterR->hasMethod('prepareUpdateData')) {
      continue;
}

Thanks !

POC: Let admin users confirm change

We do not want users to directly modify their bank account number. An admin or moderator should confirm every change before the actual database change will be made.

http://stackoverflow.com/questions/24733767/let-admin-confirm-database-change

I'm already making use of this bundle for a while, it is great when it comes to maintaining historic data. So I'd like to improve it with features to allow "future changes".

Where should I start in creating a branch for this feature? Are the listeners the best place to start? I'd hope to make a PR within a couple of weeks.

Foreign primary key support

When I use foreign primary key I get

Notice: Undefined index: id in /var/www/ekipazh/vendor/simplethings/entity-audit-bundle/src/SimpleThings/EntityAudit/EventListener/LogRevisionsListener.php line 364

Add a field to the revisions table

Hi,

After a long time I found your very good bundle. I did a history audit by myself, but it's not as flexible as I want, that's why I started to look for another solution.

I need to store one more field in a revision table ("is_valid" field - user can change an entity, but it has to be validated by admin). Is there some way how to add it to the revision table?

Take out backup process of LogRevisionsListener

Hello,

I just installed the EntityAudit, but when I need save an entity that exists, the LogRevisionsListener save a new revision with the new version of entity, but I need made a first backup before for the original state.

Proposition

  • Take out the backup process of LogRevisionsListener in a new class LogRevisions for create an API usable when we want.
  • Adding configuration for the first backup, create 2 revisions: original and actual entity.

Is global_ignore_columns not supported anymore?

I was working my way through the doc and stumbled across:

  [Symfony\Component\Config\Definition\Exception\InvalidConfigurationException]    
  Unrecognized options "global_ignore_columns" under "simple_things_entity_audit"

And true enough, the sample config does not show "global_ignore_columns".

./app/console config:dump-reference simple_things_entity_audit
# Default configuration for extension with alias: "simple_things_entity_audit"
simple_things_entity_audit:
    audited_entities:     []
    table_prefix:         ''
    table_suffix:         _audit
    revision_field_name:  rev
    revision_type_field_name:  revtype
    revision_table_name:  revisions
    revision_id_field_type:  integer
    listener:
        current_username:     true

So this will run:

simple_things_entity_audit:
    audited_entities:
        - Hn\TrainingBundle\Entity\Trainee
#    global_ignore_columns:
#        - created_at
#        - updated_at
    table_prefix:         ''
    table_suffix:         _audit
    revision_field_name:  rev
    revision_type_field_name:  revtype
    revision_table_name:  revisions
    revision_id_field_type:  integer
    listener:
        current_username: true

Have I erred somewhere on the way in setting this up, or has the global_ignore_config been removed?

SQL syntax error when viewing revisions on entities with MySQL reserved yet quoted field names.

Entity with fields to and from produces invalid SQL due to not being quoted is the AS part.

Fields on entity are defined as such:
/**
* @var string $to
* @Orm\Column(name="to", type="string", length=255)
*/
private $to;

SQL errors:

SELECT e.revtype, id AS id, name AS name, to AS to, from AS from, subject AS subject, body AS body FROM MailTemplate_audit e WHERE e.rev = ?' with params {"1":"4"}: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'to, from AS from, subject AS subject, body AS body FROM MailTemplate_audit e W' at line 1 (uncaught exception)

Quick (but untested for side affects) fix is to comment out the end of line 222 of SimpleThings\EntityAudit\AuditReader (https://github.com/simplethings/EntityAudit.git 60a5bcb)

            $columnList .= ', ' . $class->getQuotedColumnName($field, $this->platform);// .' AS ' . $field;

EDIT: Correct formatting for clarity (to and from was showing as to and from)

Revision_id_sequence is not getting created

selection_018
When we upgraded our application, we are getting the REVISIONS_ID_SEQ is not created and we check the database REVISIONS_SEQ is getting created instead of REVISIONS_ID_SEQ.

After that when we modify the code
$sequenceName = $this->platform->supportsSequences()
? 'REVISIONS_ID_SEQ'
: null;
to
$sequenceName = $this->platform->supportsSequences()
? 'REVISIONS_SEQ'
: null;

Then application is working fine. Please can anyone help me out we are using Oracle as database.

ManyToOne inheritance bugs

When the ManyToOne mapping to $organisation is on the abstract class I get an exception saying the organisation_id field is not mapped. The _audit table for each subclass includes all other fields from the abstract class except for those that are ManyToOne associations.

Adding the abstract class to audited_entities in config.yml does not stop the error. Moving the ManyToOne mapping for to each subclass using a Trait solves the problem.

Although it's a little extra code moving the mapping to the subclass works for all entities, except one that uses a Doctrine Extensions nested tree - I can't move the tree mappings into the subclasses as it throws an error saying there are multiple keys.

#config.yml
simple_things_entity_audit:
    audited_entities:
        - Umm\ProjectBundle\Entity\Project //Note: adding the abstract parent class here does not solve the problem
        //other entities to audit

The abstract class that projects inherit from

/**
* @ORM\Table(name="project_project_abstract")
 * @ORM\Entity(repositoryClass="Umm\ProjectBundle\Repository\AbstractProjectRepository")
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({"project" = "Project", "template" = "ProjectTemplate"})
*/
abstract class AbstractProject extends BaseEntity implements ProjectInterface
{
    /**
     *
     * @ORM\Column(name="title", type="string", length=50)
     * @Assert\Length(
     *  min="3",
     *  max="50",
     *  minMessage="project.title.min",
     *  maxMessage="project.title.max"
     * )
     * @Assert\NotBlank(
     *  message="project.title.not_blank"
     * )
     * @JMS\Groups({"summary", "template", "detail", "timeline", "public_api", "public_api_summary"})
     */
    protected $title; //This property is in the _audit table for each subclass

    /**
     *
     * @ORM\Column(name="description", type="string", length=1000, nullable=true)
     *
     * @Assert\Length(
     *  min="3",
     *  max="1000",
     * )
     * @JMS\Groups({"summary", "template", "detail", "public_api", "public_api_summary"})
     *
     */
    protected $description; //This property is in the _audit table for each subclass

    /**
     * @ORM\ManyToOne(targetEntity="Umm\OrganisationBundle\Entity\Organisation")
     * @ORM\JoinColumn(nullable=true)
     * @JMS\Exclude()
     */
    protected $organisation; //This association is NOT in the _audit table for the subclasses

   //other properties
}

The sub class:

/**
 *
 * @ORM\Entity(repositoryClass="Umm\ProjectBundle\Repository\ProjectRepository")
 * @ORM\Table(name="project_project")
 * @ORM\HasLifecycleCallbacks
 *
 */
class Project extends AbstractProject implements TaskableInterface, ProjectTimelineInterface, LoggableStatisticInterface, CommentableInterface
{
  //Other mappings
}

Error description:

"I was stocked to see this PR merged as we have a lot of class inheritance but alas it's not working for us on Symfony 2.6-dev with Sonata Admin. I'm using class table inheritance with Project inheriting from Abstract Project but none of the abstract project properties appear in the project_audit table so I get a DBALException and PDOException when saving or updating a project, or loading fixtures. Not sure if it's caused by Sonata as auditing needs to be set to true in each Admin service?"

Code by @mpclarkson

Revisions numbers are unlogical

Every object should start with rev 1, the insert statement.
The next update should give rev 2, not rev 26 if there were 24 other changes to other, unrelated objects of the same type happened inbetween.

Broken dependencies with doctrine orm?

Hi,

Firstly...thanks in advance for this great bundle!

With today's release (v0.5) I'm having some broken dependencies with composer, if I set composer.json to

        "simplethings/entity-audit-bundle": "dev-master"    

I'm getting the following error:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for symfony/framework-standard-edition 2.3.x-dev -> satisfiable by symfony/framework-standard-edition[2.3.x-dev].
    - Conclusion: remove doctrine/orm 2.3.4
    - Conclusion: don't install doctrine/orm 2.3.4
    - Conclusion: don't install doctrine/orm 2.3.3
    - Conclusion: don't install doctrine/orm 2.3.2
    - Installation request for simplethings/entity-audit-bundle dev-master -> satisfiable by simplethings/entity-audit-bundle[dev-master].
    - Conclusion: don't install doctrine/orm 2.3.1
    - simplethings/entity-audit-bundle dev-master requires doctrine/orm ~2.1.0 -> satisfiable by doctrine/orm[2.1.3, 2.1.4, 2.1.5, 2.1.6, 2.1.7].
    - Can only install one of: doctrine/orm[2.2.3, 2.1.3].
    - Can only install one of: doctrine/orm[2.2.3, 2.1.4].
    - Can only install one of: doctrine/orm[2.2.3, 2.1.5].
    - Can only install one of: doctrine/orm[2.2.3, 2.1.6].
    - Can only install one of: doctrine/orm[2.2.3, 2.1.7].
    - symfony/framework-standard-edition 2.3.x-dev requires doctrine/orm >=2.2.3,<2.4-dev -> satisfiable by doctrine/orm[2.3.4, 2.2.3, 2.3.0, 2.3.1, 2.3.2, 2.3.3].
    - Conclusion: don't install doctrine/orm 2.3.0

Setting composer.json to v0.3 fix the problem

        "simplethings/entity-audit-bundle": "v0.3"    

Thanks for you help

Exception thrown in the SimpleThingsEntityAuditBundle:Audit:view_detail.html.twig template when the entity property is a array

I have the following entity definition:

/**
* @var simple_array $items
*
* @Orm\Column(name="items", type="simple_array", nullable=true)
*/
protected $items;

When I try to render the view_datail.html.twig, I got the next error:

An exception has been thrown during the rendering of a template ("Notice: Array to string conversion in ... line xx") in SimpleThingsEntityAuditBundle:Audit:view_detail.html.twig at line 19.

Those lines in the template are:

   {% if value.timestamp is defined %}
   <td>{{ value|date('m/d/Y') }}</td>
   {% else %}
   <td>{{ value }}</td>   <----- Line 19
   {% endif %}

The solution to the issue would be:

    {% if value.timestamp is defined %}
    <td>{{ value|date('m/d/Y') }}</td>
    {% elseif value is iterable %}
    <td>
        {% for element in value %}
            {{ element }}
        {% endfor %}
    </td>
    {% else %}
    <td>{{ value }}</td>
    {% endif %}

Audit Events

It would be nice to have internal events for audit manger (like "before audit write") etc, that could modify audited data (like converting 1234 5678 0000 0000 card number to 1234 **** **** **00).

If this behavior is OK, I'll make a PR.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.