PHPackages                             madmis/activity-log-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. madmis/activity-log-bundle

AbandonedArchivedSymfony-bundle[Database &amp; ORM](/categories/database)

madmis/activity-log-bundle
==========================

Activity log bundle - Extended doctrine loggable bundle

0.2.3(8y ago)1183.5k↓33.3%8[1 issues](https://github.com/madmis/ActivityLogBundle/issues)MITPHP

Since Jun 1Pushed 2y ago2 watchersCompare

[ Source](https://github.com/madmis/ActivityLogBundle)[ Packagist](https://packagist.org/packages/madmis/activity-log-bundle)[ Docs](https://github.com/madmis/ActivityLogBundle.git)[ RSS](/packages/madmis-activity-log-bundle/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (3)Dependencies (2)Versions (13)Used By (0)

Symfony ActivityLog Component
=============================

[](#symfony-activitylog-component)

[![SensioLabsInsight](https://camo.githubusercontent.com/f09364443a14ece5f431f813cde6c7890d201cf782242a3737d277bcbc0918b5/68747470733a2f2f696e73696768742e73656e73696f6c6162732e636f6d2f70726f6a656374732f39623765623638332d613434302d346636382d383034612d3338616531303765373564302f6d696e692e706e67)](https://insight.sensiolabs.com/projects/9b7eb683-a440-4f68-804a-38ae107e75d0)[![Build Status](https://camo.githubusercontent.com/2d48d970790be504d4d1b2c9cfa2f8013ce799a7734b08ef5e889f02d879a170/68747470733a2f2f7472617669732d63692e6f72672f6d61646d69732f41637469766974794c6f6742756e646c652e7376673f6272616e63683d6d6173746572)](https://travis-ci.org/madmis/ActivityLogBundle)[![Coverage Status](https://camo.githubusercontent.com/7a321d27bafd11ee57afb09b0a0346e657680995a195379ca36b3c9ecf1afe41/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f6d61646d69732f41637469766974794c6f6742756e646c652f62616467652e7376673f6272616e63683d6d6173746572)](https://coveralls.io/github/madmis/ActivityLogBundle?branch=master)[![Latest Stable Version](https://camo.githubusercontent.com/eb0c5aa74d6a18a1af665289a70c1a71cca188d7b59ef21bc0400e90a9a29447/68747470733a2f2f706f7365722e707567782e6f72672f6d61646d69732f61637469766974792d6c6f672d62756e646c652f762f737461626c65)](https://packagist.org/packages/madmis/activity-log-bundle)[![Total Downloads](https://camo.githubusercontent.com/033ed04238bf5e72dd9b63b871f0110007187b283d62835fe97221eb7c8d711a/68747470733a2f2f706f7365722e707567782e6f72672f6d61646d69732f61637469766974792d6c6f672d62756e646c652f646f776e6c6f616473)](https://packagist.org/packages/madmis/activity-log-bundle)[![License](https://camo.githubusercontent.com/671e295a3d312c7d1c0021f569a5d2537bbdd047cdd7e32bfb6e653e2299f690/68747470733a2f2f706f7365722e707567782e6f72672f6d61646d69732f61637469766974792d6c6f672d62756e646c652f6c6963656e7365)](https://packagist.org/packages/madmis/activity-log-bundle)

ActivityLogBundle - Extended doctrine loggable (StofDoctrineExtensionsBundle)

What's inside
-------------

[](#whats-inside)

ActivityLogBundle uses **Loggable** extension from [StofDoctrineExtensionsBundle](https://github.com/stof/StofDoctrineExtensionsBundle) and [DoctrineExtensions](https://github.com/Atlantic18/DoctrineExtensions)

This bundle extend **Gedmo\\Loggable\\Entity\\MappedSuperclass\\AbstractLogEntry** with below fields:

- parentId - store depedency to "main entity"
- parentClass - store "main entity" type
- oldData - data that were changed
- name - entry name (to show in activity log)
- user - associations mapping with user who changed data

Bundle contain extended listener (**LoggableListener**) to process above fields.

Also available formatter to preprocessing activity log before show in view (html).

Installation
------------

[](#installation)

Pretty simple with Composer, run:

```
composer require madmis/activity-log-bundle
```

Then enable the bundle in the kernel:

```
public function registerBundles()
{
    $bundles = [
        // ...
        new ActivityLogBundle\ActivityLogBundle(),
        // ...
    ];
    ...
}
```

Configure bundle:

```
# app/config/config.yml
doctrine:
    dbal:
        #...
    orm:
        #...
        resolve_target_entities:
            Symfony\Component\Security\Core\User\UserInterface: AppBundle\Entity\User
        mappings:
            gedmo_loggable:
                type: annotation
                prefix: Gedmo\Loggable\Entity
                dir: "%kernel.root_dir%/../src/AppBundle/Entity/"
                alias: GedmoLoggable
                is_bundle: false

stof_doctrine_extensions:
    class:
        loggable: ActivityLogBundle\Listener\LoggableListener
    orm:
        default:
            loggable: true

```

Create entity and make it loggable:

```
namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
use ActivityLogBundle\Entity\Interfaces\StringableInterface;

/**
 * @package AppBundle\Entity
 * @ORM\Entity(repositoryClass="ProjectRepository")
 * @ORM\Table
 * @Gedmo\Loggable(logEntryClass="ActivityLogBundle\Entity\LogEntry")
 */
class Project implements StringableInterface
{
    /**
     * @var int
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     * @ORM\Column(type="string", length=128)
     * @Gedmo\Versioned
     */
    private $name;

    /**
     * @var string
     * @ORM\Column(type="string", length=16)
     * @Gedmo\Versioned
     */
    private $key;

    //...
```

**StringableInterface** required to save **LogEntry::name**.

Then run command to update database schema:

```
php bin/console doctrine:schema:update --force
```

Using formatter to data view
----------------------------

[](#using-formatter-to-data-view)

Formatter class: **ActivityLogBundle\\Service\\ActivityLog\\ActivityLogFormatter**Formatter service: **activity\_log.formatter**

required: **LoggerInterface** as dependency

By default entity without custom formatter class formatted by **ActivityLogBundle\\Service\\ActivityLog\\EntityFormatter\\UniversalFormatter**

But you can implement custom formatter for each entity.

To register a custom formatter, add a service tag with the following (required) properties:

- name: 'activity\_log.formatter'
- entity: Class name of the entity that should be formatted by the registered formatter

Example:

```
services:
    app.formatter.project:
        class: AppBundle\Service\ActivityFormatter\Project
        tags:
            -  { name: activity_log.formatter, entity: 'Project'}
```

As example formatter for **AppBundle\\Entity\\Project** entity:

```
namespace AppBundle\Service\ActivityFormatter;

class Project extends AbstractFormatter implements FormatterInterface
{
    /**
     * @param LogEntryInterface $log
     * @return array
     */
    public function format(LogEntryInterface $log)
    {
        $result = $log->toArray();

        if ($log->isCreate()) {
            $result['message'] = sprintf('The Project "%s" was created.', $log->getName());
        } else if ($log->isRemove()) {
            $result['message'] = sprintf('The Project "%s" was removed.', $log->getName());
        } else if ($log->isUpdate()) {
            $result['message'] = 'The Project "%s" was updated.%s';
            $data = $log->getData();
            $oldData = $log->getOldData();

            $text = '';
            foreach ($data as $field => $value) {
                $value = $this->normalizeValue($field, $value);

                if (array_key_exists($field, $oldData)) {
                    $oldValue = $this->normalizeValue($field, $oldData[$field]);
                    $subText = sprintf('from "%s" to "%s".', $oldValue, $value);
                } else {
                    $subText = sprintf('to "%s".', $value);
                }
                $text .= sprintf('Property "%s" was changed: %s', $field, $subText);
            }

            $result['message'] = sprintf($result['message'], $log->getName(), $text);
        } else {
            $result['message'] = "Undefined action: {$log->getAction()}.";
        }

        return $result;
    }
}
```

If entity has association with other entity it can be resolved by **AbstractFormatter::normalizeValue**. This method call method from the entity formatter class, which named as appropriate property.

For example, **Project** entity has association mapping **ManyToOne** to **Type** entity. To get **Type** name we can add method **type** to **Project** formatter:

```
namespace AppBundle\Service\ActivityFormatter;

class Project extends AbstractFormatter implements FormatterInterface
{
    //...

    /**
     * @param array $value
     * @return string
     */
    protected function type(array $value)
    {
        if (isset($value['id'])) {
            /** @var Type $entity */
            $entity = $this->entityManager->getRepository('AppBundle:Type')
                ->find($value['id']);

            if ($entity) {
                return $entity->getName();
            }
        }

        return '';
    }
```

As result we have formatted response to show in view.

Using activity log in controller
--------------------------------

[](#using-activity-log-in-controller)

```
$em = $this->getDoctrine()->getManager();
// get log entries for entity
$entries =  $em
            ->getRepository('AppBundle:LogEntry')
            ->getLogEntriesQueryBuilder($entity)
           ->getQuery()
          ->getResult();
// format log entries to show in the view
$entries = $this
            ->get('activity_log.formatter')
            ->format($entries);
```

For `$entity` should be configured [Entity formatter](#using-formatter-to-data-view).

###  Health Score

37

—

LowBetter than 83% of packages

Maintenance18

Infrequent updates — may be unmaintained

Popularity38

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~43 days

Recently: every ~71 days

Total

11

Last Release

3207d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/1774703?v=4)[Dmytro](/maintainers/madmis)[@madmis](https://github.com/madmis)

---

Top Contributors

[![madmis](https://avatars.githubusercontent.com/u/1774703?v=4)](https://github.com/madmis "madmis (9 commits)")[![TwanVermeulen](https://avatars.githubusercontent.com/u/1618709?v=4)](https://github.com/TwanVermeulen "TwanVermeulen (5 commits)")[![Gaiidenn](https://avatars.githubusercontent.com/u/18189706?v=4)](https://github.com/Gaiidenn "Gaiidenn (1 commits)")[![jhndjx](https://avatars.githubusercontent.com/u/7516373?v=4)](https://github.com/jhndjx "jhndjx (1 commits)")[![alexmanno](https://avatars.githubusercontent.com/u/10499850?v=4)](https://github.com/alexmanno "alexmanno (1 commits)")[![ViktorParakhonia](https://avatars.githubusercontent.com/u/6010280?v=4)](https://github.com/ViktorParakhonia "ViktorParakhonia (1 commits)")[![WybrenKoelmans](https://avatars.githubusercontent.com/u/2108992?v=4)](https://github.com/WybrenKoelmans "WybrenKoelmans (1 commits)")

---

Tags

symfonybundledoctrineloggableactivity

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/madmis-activity-log-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/madmis-activity-log-bundle/health.svg)](https://phpackages.com/packages/madmis-activity-log-bundle)
```

###  Alternatives

[sonata-project/doctrine-orm-admin-bundle

Integrate Doctrine ORM into the SonataAdminBundle

46117.7M155](/packages/sonata-project-doctrine-orm-admin-bundle)[omines/datatables-bundle

Symfony DataTables Bundle with native Doctrine ORM, Elastica and MongoDB support

2851.4M6](/packages/omines-datatables-bundle)[spiriitlabs/form-filter-bundle

This bundle aim to provide classes to build some form filters and then build a doctrine query from this form filter.

36465.8k8](/packages/spiriitlabs-form-filter-bundle)[redcode/tree-bundle

This Symfony bundle integrates jsTree and Gedmo Nested Set directly to Sonata Admin

3048.5k](/packages/redcode-tree-bundle)[prezent/doctrine-translatable-bundle

Integrate the doctrine-translatable extension in Symfony

14698.4k5](/packages/prezent-doctrine-translatable-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
