madmis/activity-log-bundle

活动日志组件 - 扩展 doctrine loggable 组件

安装量: 75,474

依赖项: 0

建议者: 0

安全性: 0

星标: 11

关注者: 3

分支: 9

公开问题: 1

类型:symfony-bundle

0.2.3 2017-08-07 06:09 UTC

This package is auto-updated.

Last update: 2024-09-16 01:16:47 UTC


README

SensioLabsInsight Build Status Coverage Status Latest Stable Version Total Downloads License

ActivityLogBundle - 扩展 doctrine loggable (StofDoctrineExtensionsBundle)

包含内容

ActivityLogBundle 使用来自 StofDoctrineExtensionsBundleDoctrineExtensionsLoggable 扩展,并扩展了以下字段

Gedmo\Loggable\Entity\MappedSuperclass\AbstractLogEntry 以下字段:

  • parentId - 存储“主实体”的依赖关系
  • parentClass - 存储“主实体”类型
  • oldData - 发生变化的数据
  • name - 条目名称(显示在活动日志中)
  • user - 与更改数据的用户的关联映射

Bundle 包含扩展的监听器(LoggableListener)以处理上述字段。

还提供格式化器,用于在视图(HTML)中显示活动日志之前进行预处理。

安装

使用 Composer 非常简单,运行

composer require madmis/activity-log-bundle

然后在内核中启用组件

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

配置组件

# 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
            

创建实体并使其可记录

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 是保存 LogEntry::name 所必需的。

然后运行命令更新数据库模式

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

使用格式化器查看数据

格式化器类: ActivityLogBundle\Service\ActivityLog\ActivityLogFormatter 格式化器服务: activity_log.formatter

所需: LoggerInterface 作为依赖项

默认情况下,没有自定义格式化器类的实体使用 ActivityLogBundle\Service\ActivityLog\EntityFormatter\UniversalFormatter 格式化。

但是您可以为每个实体实现自定义格式化器。

要注册自定义格式化器,添加以下属性的服务标签(必需)

  • name: 'activity_log.formatter'
  • entity: 应由注册的格式化器格式化的实体的类名

示例

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

例如,对于 AppBundle\Entity\Project 实体

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 <b>Project <span class="font-green-jungle">"%s"</span></b> was created.', $log->getName());
        } else if ($log->isRemove()) {
            $result['message'] = sprintf('The <b>Project <span class="font-red-flamingo">"%s"</span></b> was removed.', $log->getName());
        } else if ($log->isUpdate()) {
            $result['message'] = '<dl><dt>The <b>Project <span class="font-yellow-gold">"%s"</span></b> was updated.</dt>%s</dl>';
            $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 "<b>%s</b>" to "<b>%s</b>".', $oldValue, $value);
                } else {
                    $subText = sprintf('to "<b>%s</b>".', $value);
                }
                $text .= sprintf('<dd>Property "<b>%s</b>" was changed: %s</dd>', $field, $subText);
            }

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

        return $result;
    }
}

如果实体与其他实体有关联,则可以通过 AbstractFormatter::normalizeValue 解决。该方法调用实体格式化器类中的方法,该方法名称与适当属性相匹配。

例如,Project 实体具有与 Type 实体的 ManyToOne 关联映射。要获取 Type 名称,我们可以在 Project 格式化器中添加 type 方法

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 '';
    }

结果是我们有格式化响应以在视图中显示。

在控制器中使用活动日志

$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);

对于 $entity 应配置 实体格式化器