tapp/filament-auditing

Filament Laravel 审计插件。

v3.0.7 2024-08-15 16:24 UTC

README

Latest Version on Packagist Code Style Action Status Total Downloads

A Filament 插件,用于Laravel Auditing 包。此插件包含一个关系管理器,可以添加到您的 Filament 资源中。

此包提供了一个 Filament 资源管理器,可以在查看和编辑页面上显示所有审计的表格,并允许恢复审计。

安装

注意 此插件使用Laravel Auditing 包。首先安装并配置此包。

您可以通过 composer 安装此插件

composer require tapp/filament-auditing:"^3.0"

注意 对于 Filament 2.x,请检查 2.x 分支

您可以使用以下命令发布视图文件

php artisan vendor:publish --tag="filament-auditing-views"

您可以使用以下命令发布翻译文件

php artisan vendor:publish --tag="filament-auditing-translations"

您可以使用以下命令发布配置文件

php artisan vendor:publish --tag="filament-auditing-config"

这是发布配置文件的内容

<?php

return [

    'audits_sort' => [
        'column' => 'created_at',
        'direction' => 'desc',
    ],

    'is_lazy' => true,
    
    'audits_extend' => [
        // 'url' => [
        //     'class' => \Filament\Tables\Columns\TextColumn::class,
        //     'methods' => [
        //         'sortable',
        //         'searchable' => true,
        //         'default' => 'N/A'
        //     ]
        // ],
    ]

    'custom_audits_view' => false,

    'custom_view_parameters' => [
    ],

    'mapping' => [
    ],
];

audits_sort 可以用于更改审计表格的默认排序。

使用方法

要将审计表格显示在您的 Filament 资源中,只需在资源的 getRelations 方法中添加 AuditsRelationManager::class

use Tapp\FilamentAuditing\RelationManagers\AuditsRelationManager;

public static function getRelations(): array
{
    return [
        // ...
        AuditsRelationManager::class,
    ];
}

就这样,您就设置好了!

如果您访问您的资源并编辑一些数据,现在您将在编辑和查看页面上看到审计表格。

扩展列

如果您需要向 AuditsRelationManager 添加不在表中存在的列,您可以在配置中使用以下示例中所示格式添加它,它将被添加到表构建器中。要添加的列的名称是包含有关类其他信息的关联数组的关键,如下所示。必须添加列实例,但如果不需要,则可以省略方法,或添加到需要的地方。

<?php

return [

    'audits_extend' => [
       'url' => [
           'class' => \Filament\Tables\Columns\TextColumn::class, // required
           'methods' => [
               'sortable',
               'default' => 'NIL',
            ],
        ],
    ]

];

请在配置中添加此信息后运行此命令以使更改生效。

php artisan optimize

目前不支持具有两个必需参数的方法。

自定义视图数据格式化

如果您想以特定方式修改审计内容以显示旧值和新值,例如显示特定列的值而不是关系的外键 ID,甚至可以自定义整个视图以以不同于默认表格的方式显示数据,您可以使用以下描述的这些方法之一(首先,请确保已发布插件视图)

显示相关列而不是外键 ID

要使用另一个字段来显示关系,而不是旧值和新值中的外键 ID,您可以在 filament-auditing.php 配置文件中的 mapping 数组中添加应显示的标签和字段,以及相关模型,使用外键作为数组键。例如,在具有 user_id 外键的 user 关系中,此配置将显示用户 name 以及 User 标签

'mapping' => [
        'user_id' => [
            'model' => App\Models\User::class,
            'field' => 'name',
            'label' => 'User',
        ],
    ],

如果您想自定义视图,您可以在已发布的视图文件 views/vendor/filament-auditing/tables/columns/key-value.blade.php 中进行操作。

自定义旧值和新值

如果您需要自定义其他旧值和新值的展示,除了相关字段外,您可以在可审计的模型上添加一个 formatAuditFieldsForPresentation($field, $record) 方法,该方法包含两个参数

  • 第一个参数包含字段名(old_valuesnew_values)。
  • 第二个参数包含当前审计记录

此方法必须返回格式化的审计字段。

例如,假设您有一个可审计的 Article 模型,该模型包含一个相关用户,并且您添加了一个返回相关用户名(而不是 ID)并使用一些 HTML 代码格式化数据的 formatAuditFieldsForPresentation($field, $record) 方法

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use OwenIt\Auditing\Contracts\Audit;
use OwenIt\Auditing\Contracts\Auditable;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Arr;
use Illuminate\Support\HtmlString;

class Article extends Model implements Auditable
{
    use \OwenIt\Auditing\Auditable;

    // ...

    public function formatAuditFieldsForPresentation($field, Audit $record)
    {
        $fields = Arr::wrap($record->{$field});

        $formattedResult = '<ul>';

        foreach ($fields as $key => $value) {
            $formattedResult .= '<li>';
            $formattedResult .= match ($key) {
                'user_id' => '<strong>User</strong>: '.User::find($record->{$field}['user_id'])?->name.'<br />',
                'title' => '<strong>Title</strong>: '.(string) str($record->{$field}['title'])->title().'<br />',
                'order' => '<strong>Order</strong>: '.$record->{$field}['order'].'<br />',
                'content' => '<strong>Content</strong>: '.$record->{$field}['content'].'<br />',
                default => ' - ',
            };
            $formattedResult .= '</li>';
        }

        $formattedResult .= '</ul>';

        return new HtmlString($formattedResult);
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

自定义整个视图内容

如果您想自定义整个视图内容,可以在 config/filament-auditing.php 文件中将 custom_audits_view 配置值设置为 true

'custom_audits_view' => true,

此修改将允许您完全控制显示并按特定要求进行调整。现在您可以在 resources/views/vendor/filament-auditing/tables/custom-audit-content.blade.php 文件中添加自定义内容。例如

@php
$type = (string) str(class_basename($owner))->lower();
@endphp

@if(isset($records))
    <x-filament-tables::table>
        <x-slot name="header">
            @foreach($headers as $header)
            <x-filament-tables::header-cell>
                {{$header}}
            </x-filament-tables::header-cell>
            @endforeach
        </x-slot>
        @foreach($records as $audit)
            <x-filament-tables::row>
                @foreach ($audit->getModified() as $attribute => $modified)
                    <x-filament-tables::cell>
                        @lang($type.'.metadata', $audit->getMetadata())
                        <br />
                        @php
                            $current = $type.'.'.$audit->event.'.modified.'.$attribute;

                            $modified['new'] = $owner->formatFieldForPresentation($attribute, $modified['new']);

                            if (isset($modified['old'])) {
                                $modified['old'] = $owner->formatFieldForPresentation($attribute, $modified['old']);
                            }
                        @endphp

                        @lang($current, $modified)
                    </x-filament-tables::cell>
                @endforeach
            </x-filament-tables::row>
        @endforeach
    </x-filament-tables::table>
@else
    <div class="flex items-center justify-center h-32 text-gray-500 dark:text-gray-400">
        @lang($type.'.unavailable_audits')
    </div>
@endif

所有者记录可通过 $owner 变量在此视图中使用。要向视图中传递一些额外的参数,可以使用 custom_view_parameters 配置

'custom_view_parameters' => [
    'headers' => [
        'Audit',
    ],
],

要格式化字段,您也可以在所有者模型上添加一个 formatFieldForPresentation 方法,该方法以字段名和值作为参数,如上面的示例。此方法必须返回一个格式化的字段。

例如,在一个 Article 模型中,要返回相关用户的名字

public function formatFieldForPresentation($field, $value)
{
    return match($field) {
        'user_id' => $value ? optional(User::find($value))->name : $value,
        default => $value,
    };
}

上述 custom-audit-content.blade.php 视图代码中使用的 article.php 语言文件内容的示例

<?php

return [
    'unavailable_audits' => 'No article audits available',

    'metadata' => 'On :audit_created_at, :user_name [:audit_ip_address] :audit_event this record via :audit_url',

    'updated' => [
        'modified' => [
            'order' => 'The Order has been modified from <strong>:old</strong> to <strong>:new</strong>',
            'title' => 'The Title has been modified from <strong>:old</strong> to <strong>:new</strong>',
            'content' => 'The Content has been modified from <strong>:old</strong> to <strong>:new</strong>',
            'user_id' => 'The User has been modified from <strong>:old</strong> to <strong>:new</strong>',
        ],
    ],
];

权限

默认注册了两个权限,允许访问

  • audit:查看审计
  • restoreAudit:恢复审计

您可以通过添加带有 auditrestoreAudit 的策略来覆盖这些权限。

事件触发

当审计被恢复时,会触发 auditRestored 事件,因此您可以使用 $listeners 属性注册一个监听器,在审计恢复后执行一些额外的代码。

例如:在您资源的编辑页面

protected $listeners = [
    'auditRestored',
];

public function auditRestored()
{
    // your code
}

事件监听器

审计关系管理器监听 updateAuditsRelationManager 事件以刷新审计表。

因此,您可以在您资源的编辑页面(例如:在 PostResource 的编辑页面 app/Filament/Resources/PostResource/Pages/EditPost.php)中更新表单时触发此事件

protected function afterSave(): void
{
    $this->dispatch('updateAuditsRelationManager');
}

警告

在分发此事件时,将 is_lazy 配置在 filament-auditing.php 配置文件中设置为 false,以避免以下异常:“Typed property Filament\Resources\RelationManagers\RelationManager::$table must not be accessed before initialization”