diff --git a/app/Enumerations/ActionLogTypes.php b/app/Enumerations/ActionLogTypes.php new file mode 100644 index 00000000..902b2bd2 --- /dev/null +++ b/app/Enumerations/ActionLogTypes.php @@ -0,0 +1,21 @@ +id, $type->name); + } + } +} \ No newline at end of file diff --git a/app/Enumerations/ActionLogTypesForLogger.php b/app/Enumerations/ActionLogTypesForLogger.php new file mode 100644 index 00000000..8566e5f6 --- /dev/null +++ b/app/Enumerations/ActionLogTypesForLogger.php @@ -0,0 +1,16 @@ +string_id, $type->id); + } + } +} \ No newline at end of file diff --git a/app/Events/ChangeSettings.php b/app/Events/ChangeSettings.php new file mode 100644 index 00000000..62452518 --- /dev/null +++ b/app/Events/ChangeSettings.php @@ -0,0 +1,22 @@ +customField = $customField; + } +} diff --git a/app/Events/CreateNewUser.php b/app/Events/CreateNewUser.php new file mode 100644 index 00000000..03743247 --- /dev/null +++ b/app/Events/CreateNewUser.php @@ -0,0 +1,27 @@ +user = $user; + } +} diff --git a/app/Events/DeleteCustomField.php b/app/Events/DeleteCustomField.php new file mode 100644 index 00000000..38d22fa3 --- /dev/null +++ b/app/Events/DeleteCustomField.php @@ -0,0 +1,27 @@ +customField = $customField; + } +} diff --git a/app/Events/EditCustomField.php b/app/Events/EditCustomField.php new file mode 100644 index 00000000..9bb15320 --- /dev/null +++ b/app/Events/EditCustomField.php @@ -0,0 +1,27 @@ +customField = $customField; + } +} diff --git a/app/Events/EditUser.php b/app/Events/EditUser.php new file mode 100644 index 00000000..4d16cc29 --- /dev/null +++ b/app/Events/EditUser.php @@ -0,0 +1,25 @@ +user = $user; + } +} diff --git a/app/Http/Controllers/Admin/CreateNewCustomField.php b/app/Http/Controllers/Admin/CreateNewCustomField.php index ed452eea..22abf4eb 100644 --- a/app/Http/Controllers/Admin/CreateNewCustomField.php +++ b/app/Http/Controllers/Admin/CreateNewCustomField.php @@ -4,8 +4,10 @@ namespace App\Http\Controllers\Admin; use App\Enumerations\CustomFieldResources; use App\Enumerations\CustomFieldTypes; +use App\Events\CreateNewCustomField as CreateNewCustomFieldEvent; use App\Http\Requests\NewCustomFieldRequest; use App\Models\CustomField; +use Illuminate\Support\Facades\Event; class CreateNewCustomField extends Controller { @@ -59,6 +61,9 @@ class CreateNewCustomField extends Controller $customField->save(); + // fire event about creating new custom field + Event::fire(new CreateNewCustomFieldEvent($customField)); + return redirect() ->route('customfields.new') ->with('success', trans('admin/customFields.successfullyCreated')); diff --git a/app/Http/Controllers/Admin/CreateNewUser.php b/app/Http/Controllers/Admin/CreateNewUser.php index 0dce40d5..ce45a036 100644 --- a/app/Http/Controllers/Admin/CreateNewUser.php +++ b/app/Http/Controllers/Admin/CreateNewUser.php @@ -3,11 +3,12 @@ namespace App\Http\Controllers\Admin; use App\Enumerations\UserRoles; +use App\Events\CreateNewUser as CreateNewUserEvent; use App\Http\Controllers\Controller; use App\Http\Requests; use App\Http\Requests\CreateNewUserRequest; use App\Models\User; -use Illuminate\Http\Request; +use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Hash; class CreateNewUser extends Controller @@ -51,6 +52,9 @@ class CreateNewUser extends Controller // store user into database $user->save(); + // fire event + Event::fire(new CreateNewUserEvent($user)); + // refresh page with information about successfull registration return redirect() ->route('users.new') diff --git a/app/Http/Controllers/Admin/EditCustomField.php b/app/Http/Controllers/Admin/EditCustomField.php index a24dc1e9..9591125c 100644 --- a/app/Http/Controllers/Admin/EditCustomField.php +++ b/app/Http/Controllers/Admin/EditCustomField.php @@ -4,10 +4,13 @@ namespace App\Http\Controllers\Admin; use App\Enumerations\CustomFieldResources; use App\Enumerations\CustomFieldTypes; +use App\Events\DeleteCustomField; +use App\Events\EditCustomField as EditCustomFieldEvent; use App\Http\Controllers\Controller; use App\Http\Requests; use App\Http\Requests\EditCustomFieldRequest; use App\Models\CustomField; +use Illuminate\Support\Facades\Event; class EditCustomField extends Controller { @@ -60,6 +63,9 @@ class EditCustomField extends Controller // save changes into database $customField->save(); + // fire event about editing custom field + Event::fire(new EditCustomFieldEvent($customField)); + return redirect() ->route('customfields.edit', ['id' => $id]) ->with('success', trans('admin/customFields.successfullyEdited')); @@ -89,6 +95,9 @@ class EditCustomField extends Controller // delete item $field->delete(); + // fire event about editing custom field + Event::fire(new DeleteCustomField($field)); + // redirect back to overview return redirect() ->route('customfields.overview') diff --git a/app/Http/Controllers/Admin/EditUser.php b/app/Http/Controllers/Admin/EditUser.php index f9b0a7c5..986777ba 100644 --- a/app/Http/Controllers/Admin/EditUser.php +++ b/app/Http/Controllers/Admin/EditUser.php @@ -4,11 +4,13 @@ namespace App\Http\Controllers\Admin; use App\Enumerations\UserRoles; use App\Enumerations\UserStates; +use App\Events\EditUser as EditUserEvent; use App\Http\Controllers\Controller; use App\Http\Requests; use App\Http\Requests\EditUserRequest; use App\Models\User; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Hash; class EditUser extends Controller @@ -74,6 +76,9 @@ class EditUser extends Controller $user->save(); + // fire event about editing user + Event::fire(new EditUserEvent($user)); + return redirect() ->route('users.detail', ['id' => $id]) ->with('success', trans('admin/userManagement.userSuccessfullyEdited')); diff --git a/app/Listeners/LogChangeSettings.php b/app/Listeners/LogChangeSettings.php new file mode 100644 index 00000000..85969150 --- /dev/null +++ b/app/Listeners/LogChangeSettings.php @@ -0,0 +1,33 @@ +saveLog($parameters); + } + + /** + * Getter for action name. Used only internally + * + * @return mixed + */ + protected function getName() + { + return 'changeSettings'; + } +} diff --git a/app/Listeners/LogCreateCustomField.php b/app/Listeners/LogCreateCustomField.php new file mode 100644 index 00000000..5cd7c5f3 --- /dev/null +++ b/app/Listeners/LogCreateCustomField.php @@ -0,0 +1,37 @@ + $event->customField->id, + 'name' => $event->customField->name + ]; + + $this->saveLog($parameters); + } + + /** + * Getter for action name. Used only internally + * + * @return mixed + */ + protected function getName() + { + return 'newCustomField'; + } +} diff --git a/app/Listeners/LogCreatedUser.php b/app/Listeners/LogCreatedUser.php new file mode 100644 index 00000000..9da573ec --- /dev/null +++ b/app/Listeners/LogCreatedUser.php @@ -0,0 +1,36 @@ + $event->user->id, + 'name' => $event->user->name, + 'email' => $event->user->email + ]; + + $this->saveLog($parameters); + } + + /** + * Getter for action name. Used only internally + * + * @return mixed + */ + protected function getName() + { + return 'createUser'; + } +} diff --git a/app/Listeners/LogDeleteField.php b/app/Listeners/LogDeleteField.php new file mode 100644 index 00000000..07703ac5 --- /dev/null +++ b/app/Listeners/LogDeleteField.php @@ -0,0 +1,36 @@ + $event->customField->id, + 'name' => $event->customField->name + ]; + + $this->saveLog($parameters); + } + + /** + * Getter for action name. Used only internally + * + * @return mixed + */ + protected function getName() + { + return 'deleteCustomField'; + } +} diff --git a/app/Listeners/LogEditCustomField.php b/app/Listeners/LogEditCustomField.php new file mode 100644 index 00000000..b28b0055 --- /dev/null +++ b/app/Listeners/LogEditCustomField.php @@ -0,0 +1,36 @@ + $event->customField->id, + 'name' => $event->customField->name + ]; + + $this->saveLog($parameters); + } + + /** + * Getter for action name. Used only internally + * + * @return mixed + */ + protected function getName() + { + return 'editCustomField'; + } +} diff --git a/app/Listeners/LogEditUser.php b/app/Listeners/LogEditUser.php new file mode 100644 index 00000000..c656e4ee --- /dev/null +++ b/app/Listeners/LogEditUser.php @@ -0,0 +1,37 @@ + $event->user->id, + 'name' => $event->user->name, + 'email' => $event->user->email + ]; + + $this->saveLog($parameters); + } + + /** + * Getter for action name. Used only internally + * + * @return mixed + */ + protected function getName() + { + return 'userEdit'; + } +} diff --git a/app/Listeners/LogLogin.php b/app/Listeners/LogLogin.php new file mode 100644 index 00000000..4e2cecc5 --- /dev/null +++ b/app/Listeners/LogLogin.php @@ -0,0 +1,36 @@ + $event->user->id, + 'name' => $event->user->name, + 'email' => $event->user->email + ]; + + $this->saveLog($parameters); + } + + /** + * Getter for action name. Used only internally + * + * @return mixed + */ + protected function getName() + { + return 'login'; + } +} diff --git a/app/Listeners/LogLogout.php b/app/Listeners/LogLogout.php new file mode 100644 index 00000000..7aeefce3 --- /dev/null +++ b/app/Listeners/LogLogout.php @@ -0,0 +1,37 @@ + $event->user->id, + 'name' => $event->user->name, + 'email' => $event->user->email + ]; + + $this->saveLog($parameters); + } + + /** + * Getter for action name. Used only internally + * + * @return mixed + */ + protected function getName() + { + return 'logout'; + } +} diff --git a/app/Listeners/Logger.php b/app/Listeners/Logger.php new file mode 100644 index 00000000..e1b75628 --- /dev/null +++ b/app/Listeners/Logger.php @@ -0,0 +1,74 @@ +actionTypes = ActionLogTypesForLogger::getWithTranslations(); + } + + /** + * Shortcut for loging events + * + * @param array $parameters + */ + protected function saveLog($parameters = []) + { + // try to translate string id into integer id + $typeId = $this->getTypeId(); + + // is user logged in and exists given type? + if (!Auth::check() || is_null($typeId)) { + return; + } + + // get user id + $userId = Auth::user()->id; + + // setup object for insertion + $data = [ + 'user_id' => $userId, + 'type_id' => $typeId, + 'parameters' => json_encode((array)$parameters) + ]; + + // create new logged event + ActionLog::create($data); + } + + /** + * Translate string id to integer id + * + * @return int|null ID of action type when exists, null otherwise + */ + private function getTypeId() + { + $name = $this->getName(); + if (!isset($this->actionTypes[$name])) { + return null; + } + + return $this->actionTypes[$name]; + } + + /** + * Getter for action name. Used only internally + * + * @return mixed + */ + abstract protected function getName(); +} diff --git a/app/Models/ActionLog.php b/app/Models/ActionLog.php index 8b95d4b6..809a43b7 100644 --- a/app/Models/ActionLog.php +++ b/app/Models/ActionLog.php @@ -9,8 +9,9 @@ use Illuminate\Database\Eloquent\Model; */ class ActionLog extends Model { + protected $table = 'action_log'; - public $timestamps = true; + public $timestamps = false; protected $fillable = [ 'type_id', diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 58ce9624..24f304ae 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -13,8 +13,30 @@ class EventServiceProvider extends ServiceProvider * @var array */ protected $listen = [ - 'App\Events\SomeEvent' => [ - 'App\Listeners\EventListener', + 'App\Events\CreateNewUser' => [ + 'App\Listeners\LogCreatedUser', + ], + 'App\Events\EditUser' => [ + 'App\Listeners\LogEditUser', + ], + 'App\Events\CreateNewCustomField' => [ + 'App\Listeners\LogCreateCustomField', + ], + 'App\Events\EditCustomField' => [ + 'App\Listeners\LogEditCustomField', + ], + 'App\Events\DeleteCustomField' => [ + 'App\Listeners\LogDeleteField', + ], + 'App\Events\ChangeSettings' => [ + 'App\Listeners\LogChangeSettings', + ], + // internal Laravel events - should work as auth.login and auth.logout, however it doesn't... + 'Illuminate\Auth\Events\Login' => [ + 'App\Listeners\LogLogin' + ], + 'Illuminate\Auth\Events\Logout' => [ + 'App\Listeners\LogLogout' ], ]; diff --git a/database/migrations/2016_01_28_213204_AddStringIdForActionTypes.php b/database/migrations/2016_01_28_213204_AddStringIdForActionTypes.php new file mode 100644 index 00000000..bb02c3cc --- /dev/null +++ b/database/migrations/2016_01_28_213204_AddStringIdForActionTypes.php @@ -0,0 +1,33 @@ +string('string_id', 64) + ->after('id') + ->unique()->comment = 'String ID used for better readability in loggers'; + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('action_log_types', function (Blueprint $table) { + $table->dropColumn('string_id'); + }); + } +} diff --git a/database/seeds/DatabaseSeeder.php b/database/seeds/DatabaseSeeder.php index 27d1d43e..9d64c78a 100644 --- a/database/seeds/DatabaseSeeder.php +++ b/database/seeds/DatabaseSeeder.php @@ -14,5 +14,6 @@ class DatabaseSeeder extends Seeder // fill up custom field types $this->call(SeedCustomFieldTypes::class); $this->call(SeedCustomFieldResources::class); + $this->call(SeedActionLogTypes::class); } } \ No newline at end of file diff --git a/database/seeds/SeedActionLogTypes.php b/database/seeds/SeedActionLogTypes.php new file mode 100644 index 00000000..126faaa6 --- /dev/null +++ b/database/seeds/SeedActionLogTypes.php @@ -0,0 +1,34 @@ +insert([ + 'string_id' => $type, + 'name' => 'admin/actionLog.name' . ucfirst($type), + 'value' => 'admin/actionLog.' . $type + ]); + } + } +} diff --git a/resources/lang/en/admin/actionLog.php b/resources/lang/en/admin/actionLog.php new file mode 100644 index 00000000..5b744e16 --- /dev/null +++ b/resources/lang/en/admin/actionLog.php @@ -0,0 +1,23 @@ + 'Logged in', + 'logout' => 'Logged out', + 'selfUserEdit' => 'Updated self user', + 'userEdit' => 'Updated someone\'s profile', + 'changePassword' => 'Changed password', + 'newCustomField' => 'Added new custom field', + 'editCustomField' => 'Edited custom field', + 'deleteCustomField' => 'Deleted custom field', + 'changeSettings' => 'Changes settings', + + // list of names + 'nameLogin' => 'Logged in', + 'nameLogout' => 'Logged out', + 'nameSelfUserEdit' => 'Updated self user', + 'nameUserEdit' => 'Updated someone\'s profile', + 'nameChangePassword' => 'Changed password', + 'nameNewCustomField' => 'Added new custom field', + 'nameEditCustomField' => 'Edited custom field', + 'nameDeleteCustomField' => 'Deleted custom field', + 'nameChangeSettings' => 'Changes settings', +]; \ No newline at end of file