ActivityLogger plugin for CakePHP 3.x
, (*1)
Installation
You can install this plugin into your CakePHP application using composer., (*2)
The recommended way to install composer packages is:, (*3)
composer require elstc/cakephp-activity-logger
Load plugin
(CakePHP >= 3.6.0) Load the plugin by adding the following statement in your project's src/Application.php
:, (*4)
$this->addPlugin('Elastic/ActivityLogger');
(CakePHP <= 3.5.x) Load the plugin by adding the following statement in your project's config/bootstrap.php
file:, (*5)
Plugin::load('Elastic/ActivityLogger');
Create activity_logs table
run migration command:, (*6)
bin/cake migrations migrate -p Elastic/ActivityLogger
Usage
Attach to Table
class ArticlesTable extends Table
{
public function initialize(array $config)
{
// ...
$this->addBehavior('Elastic/ActivityLogger.Logger', [
'scope' => [
'Articles',
'Authors',
],
]);
}
}
Activity Logging Basis
logging on create
$artice = $this-Articles->newEnity([ /* ... */ ]);
$this->Articles->save($artice);
// saved log
// [action='create', scope_model='Articles', scope_id=$article->id]
logging on update
$artice = $this-Articles->patchEnity(artice, [ /* ... */ ]);
$this->Articles->save($artice);
// saved log
// [action='update', scope_model='Articles', scope_id=$article->id]
logging on delete
$artice = $this-Articles->get($id);
$this->Articles->delete($artice);
// saved log
// [action='delete', scope_model='Articles', scope_id=$article->id]
Activity Logging with Issuer
$this->Articles->setLogIssuer($author); // Set issuer
$artice = $this-Articles->newEnity([ /* ... */ ]);
$this->Articles->save($artice);
// saved log
// [action='create', scope_model='Articles', scope_id=$article->id, ...]
// and
// [action='create', scope_model='Auhtors', scope_id=$author->id, ...]
AutoIssuerComponent
If you using AuthComponent
, the AutoIssuerComponent
will help set issuer to Tables., (*7)
// In AppController
class AppController extends Controller
{
public function initialize()
{
// ...
$this->loadComponent('Elastic/ActivityLogger.AutoIssuer', [
'userModel' => 'Users',
]);
// ...
}
}
If there is load to any Table class before the execution of Controller.startup
event,
please describe initializedTables
option., (*8)
eg:, (*9)
// In AppController
class AppController extends Controller
{
public function initialize()
{
$this->loadModel('Articles');
$this->loadModel('Awesome.Favorites');
// ...
$this->loadComponent('Elastic/ActivityLogger.AutoIssuer', [
'userModel' => 'Users',
'initializedTables' => [
'Articles',
'Awesome.Favorites',
],
]);
// ...
}
}
Activity Logging with Scope
class CommentsTable extends Table
{
public function initialize(array $config)
{
// ...
$this->addBehavior('Elastic/ActivityLogger.Logger', [
'scope' => [
'Articles',
'Authors',
'Users',
],
]);
}
}
$this->Comments->setLogScope([$user, $article]); // Set scope
$comment = $this-Comments->newEnity([ /* ... */ ]);
$this->Comments->save($comment);
// saved log
// [action='create', scope_model='Users', scope_id=$article->id, ...]
// and
// [action='create', scope_model='Articles', scope_id=$author->id, ...]
Activity Logging with message
use setLogMessageBuilder
method. You can generate any message for each action in the log., (*10)
class ArticlesTable extends Table
{
public function initialize(array $config)
{
// ...
$this->addBehavior('Elastic/ActivityLogger.Logger', [
'scope' => [
'Articles',
'Authors',
],
]);
// ADD THIS
$this->setLogMessageBuilder(static function (ActivityLog $log, array $context) {
if ($log->message !== null) {
return $log->message;
}
$message = '';
$object = $context['object'] ?: null;
$issuer = $context['issuer'] ?: null;
switch ($log->action) {
case ActivityLog::ACTION_CREATE:
$message = sprintf('%3$s created #%1$s: "%2$s"', $object->id, $object->title, $issuer->username);
break;
case ActivityLog::ACTION_UPDATE:
$message = sprintf('%3$s updated #%1$s: "%2$s"', $object->id, $object->title, $issuer->username);
break;
case ActivityLog::ACTION_DELETE:
$message = sprintf('%3$s deleted #%1$s: "%2$s"', $object->id, $object->title, $issuer->username);
break;
default:
break;
}
return $message;
});
}
}
Or use setLogMessage
before save|delete action. You can set a log message., (*11)
$this->Articles->setLogMessage('Custom Message');
$this->Articles->save($entity);
// saved log
// [action='update', 'message' => 'Custom Messages', ...]
Save Custom Log
$this->Articles->activityLog(\Psr\Log\LogLevel::NOTICE, 'Custom Messages', [
'action' => 'custom',
'object' => $artice,
]);
// saved log
// [action='custom', 'message' => 'Custom Messages', scope_model='Articles', scope_id=$article->id, ...]
Find Activity Logs
$logs = $this->Articles->find('activity', ['scope' => $article]);