diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 0000000..6ecb734 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,17 @@ +name: Laravel.php Log + +on: push + +jobs: + cd: + runs-on: ubuntu-latest + steps: + - name: cd + uses: tripteki/cd-package@1.0.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + repotoken: ${{ secrets.REPOSITORY_TOKEN }} + repouser: tripteki + repository: https://packagist.org + language: php + artifact: composer.json \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..061b3a5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Trip Teknologi + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a89108c --- /dev/null +++ b/README.md @@ -0,0 +1,86 @@ +

Log

+ +This package provides implementation of Auth Activity Log in repository pattern for Lumen and Laravel besides REST API starterpack of admin management with no intervention to codebase and keep clean. + +Getting Started +--- + +Installation : + +``` +$ composer require tripteki/laravelphp-log +``` + +How to use it : + +- Read detail optional instruction here [Log](https://spatie.be/docs/laravel-activitylog/v4/installation-and-setup). + +- Put `Tripteki\Log\Traits\LogTrait` to any of your model loggable then optionally you can configure `protected static` of `$recordName`, `$recordEvents`, and `$recordLists`. + +- Put `Tripteki\Log\Providers\LogServiceProvider` to service provider configuration list. + +- Put `Tripteki\Log\Providers\LogServiceProvider::ignoreConfig()` into `register` provider, then publish config file into your project's directory with running : + +``` +php artisan vendor:publish --tag=tripteki-laravelphp-log +``` + +- Put `Tripteki\Log\Providers\LogServiceProvider::ignoreMigrations()` into `register` provider, then publish migrations file into your project's directory with running (optionally) : + +``` +php artisan vendor:publish --tag=tripteki-laravelphp-log-migrations +``` + +- Migrate. + +``` +$ php artisan migrate +``` + +- Publish tests file into your project's directory with running (optionally) : + +``` +php artisan vendor:publish --tag=tripteki-laravelphp-log-tests +``` + +- Sample : + +```php +use Tripteki\Log\Contracts\Repository\Admin\ILogRepository as ILogAdminRepository; +use Tripteki\Log\Contracts\Repository\ILogRepository; + +$logAdminRepository = app(ILogAdminRepository::class); + +// $logAdminRepository->get(5); // +// $logAdminRepository->all(); // + +$repository = app(ILogRepository::class); +// $repository->setUser(...); // +// $repository->getUser(); // + +// $repository->archive(5); // +// $repository->unarchive(5); // +// $repository->get(5); // +// $repository->all(); // +``` + +- Generate swagger files into your project's directory with putting this into your annotation configuration (optionally) : + +``` +base_path("app/Http/Controllers/Log") +``` + +``` +base_path("app/Http/Controllers/Admin/Log") +``` + +Usage +--- + +`php artisan adminer:install:log` + +Author +--- + +- Trip Teknologi ([@tripteki](https://linkedin.com/company/tripteki)) +- Hasby Maulana ([@hsbmaulana](https://linkedin.com/in/hsbmaulana)) diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..af47163 --- /dev/null +++ b/composer.json @@ -0,0 +1,57 @@ +{ + "name": "tripteki/laravelphp-log", + "version": "1.0.0", + "description": "Trip Teknologi's Laravel.php Logs", + + "readme": "README.md", + "license": "MIT", + "authors": [ { "name": "Trip Teknologi", "email": "tripteki.company@gmail.com" } ], + "homepage": "https://github.com/tripteki/laravelphp-log", + "support": { "issues": "https://github.com/tripteki/laravelphp-log/issues" }, + + "require": { + + "php": "^8.0.2", + + "tripteki/laravelphp-repository": "^1.0.0", + "tripteki/laravelphp-helpers": "^1.0.0", + "tripteki/laravelphp-adminer": "^1.0.0", + "tripteki/laravelphp-import-export": "^1.0.0", + "tripteki/laravelphp-request-response-query": "^1.0.0", + + "spatie/laravel-activitylog": "^4.7.2" + }, + + "require-dev": {}, + + "suggest": { + + "laravel/lumen-framework": "Required when using lumen framework (^9.0).", + "laravel/framework": "Required when using laravel framework (^9.0)." + }, + + "autoload": { + + "psr-4": { + + "Tripteki\\Log\\": "src/" + } + }, + + "autoload-dev": {}, + + "extra": { + + "laravel": { + + "dont-discover": [], + + "providers": [ + + "Tripteki\\Log\\Providers\\LogServiceProvider" + ], + + "aliases": [] + } + } +} diff --git a/config/log.php b/config/log.php new file mode 100644 index 0000000..4705577 --- /dev/null +++ b/config/log.php @@ -0,0 +1,18 @@ + true, + + "default_log_name" => "log", + + "activity_model" => Tripteki\Log\Models\Admin\Log::class, + "table_name" => "logs", + "database_connection" => null, + + "default_auth_driver" => null, + + "subject_returns_soft_deleted_models" => false, + + "delete_records_older_than_days" => 365, +]; diff --git a/database/migrations/2023_01_20_000000_create_logs_table.php b/database/migrations/2023_01_20_000000_create_logs_table.php new file mode 100644 index 0000000..5798795 --- /dev/null +++ b/database/migrations/2023_01_20_000000_create_logs_table.php @@ -0,0 +1,73 @@ +keytype = app(AuthModelContract::class)->getKeyType(); + } + + /** + * @return void + */ + public function up() + { + $keytype = $this->keytype; + + Schema::connection(config("activitylog.database_connection"))->create(config("activitylog.table_name"), function (Blueprint $table) use ($keytype) { + + $table->uuid("id"); + $table->string("log_name")->nullable(); + $table->text("description"); + + if (! LogServiceProvider::shouldSubjectUid()) { + + $table->nullableMorphs("subject", "subject"); + + } else { + + $table->nullableUuidMorphs("subject", "subject"); + } + + if ($keytype == "int") { + + $table->nullableMorphs("causer", "causer"); + + } else if ($keytype == "string") { + + $table->nullableUuidMorphs("causer", "causer"); + } + + $table->uuid("batch_uuid")->nullable(); + $table->json("properties")->nullable(); + $table->string("event")->nullable(); + $table->timestamps(); + $table->softDeletes(); + + $table->primary("id"); + $table->index("log_name"); + }); + } + + /** + * @return void + */ + public function down() + { + Schema::connection(config("activitylog.database_connection"))->dropIfExists(); + } +}; diff --git a/src/Console/Commands/InstallCommand.php b/src/Console/Commands/InstallCommand.php new file mode 100644 index 0000000..053d9fc --- /dev/null +++ b/src/Console/Commands/InstallCommand.php @@ -0,0 +1,78 @@ +helper = $helper; + } + + /** + * @return int + */ + public function handle() + { + $this->installStack(); + + return 0; + } + + /** + * @return int|null + */ + protected function installStack() + { + (new Filesystem)->ensureDirectoryExists(base_path("routes/user")); + (new Filesystem)->ensureDirectoryExists(base_path("routes/admin")); + (new Filesystem)->copy(__DIR__."/../../../stubs/routes/user/log.php", base_path("routes/user/log.php")); + (new Filesystem)->copy(__DIR__."/../../../stubs/routes/admin/log.php", base_path("routes/admin/log.php")); + $this->helper->putRoute("api.php", "user/log.php"); + $this->helper->putRoute("api.php", "admin/log.php"); + + (new Filesystem)->ensureDirectoryExists(app_path("Http/Controllers/Log")); + (new Filesystem)->copyDirectory(__DIR__."/../../../stubs/app/Http/Controllers/Log", app_path("Http/Controllers/Log")); + (new Filesystem)->ensureDirectoryExists(app_path("Http/Requests/Logs")); + (new Filesystem)->copyDirectory(__DIR__."/../../../stubs/app/Http/Requests/Logs", app_path("Http/Requests/Logs")); + (new Filesystem)->ensureDirectoryExists(app_path("Http/Controllers/Admin/Log")); + (new Filesystem)->copyDirectory(__DIR__."/../../../stubs/app/Http/Controllers/Admin/Log", app_path("Http/Controllers/Admin/Log")); + (new Filesystem)->ensureDirectoryExists(app_path("Imports/Logs")); + (new Filesystem)->copyDirectory(__DIR__."/../../../stubs/app/Imports/Logs", app_path("Imports/Logs")); + (new Filesystem)->ensureDirectoryExists(app_path("Exports/Logs")); + (new Filesystem)->copyDirectory(__DIR__."/../../../stubs/app/Exports/Logs", app_path("Exports/Logs")); + (new Filesystem)->ensureDirectoryExists(app_path("Http/Requests/Admin/Logs")); + (new Filesystem)->copyDirectory(__DIR__."/../../../stubs/app/Http/Requests/Admin/Logs", app_path("Http/Requests/Admin/Logs")); + (new Filesystem)->ensureDirectoryExists(app_path("Http/Responses")); + + $this->helper->putTrait($this->helper->classToFile(get_class(app(AuthModelContract::class))), \Tripteki\Log\Traits\LogCauseTrait::class); + + $this->info("Adminer Log scaffolding installed successfully."); + } +}; diff --git a/src/Contracts/Repository/Admin/ILogRepository.php b/src/Contracts/Repository/Admin/ILogRepository.php new file mode 100644 index 0000000..e99ed77 --- /dev/null +++ b/src/Contracts/Repository/Admin/ILogRepository.php @@ -0,0 +1,11 @@ +data = $data; + } +}; diff --git a/src/Events/Archiving.php b/src/Events/Archiving.php new file mode 100644 index 0000000..838e39a --- /dev/null +++ b/src/Events/Archiving.php @@ -0,0 +1,24 @@ +data = $data; + } +}; diff --git a/src/Events/Unarchived.php b/src/Events/Unarchived.php new file mode 100644 index 0000000..ae86f1a --- /dev/null +++ b/src/Events/Unarchived.php @@ -0,0 +1,24 @@ +data = $data; + } +}; diff --git a/src/Events/Unarchiving.php b/src/Events/Unarchiving.php new file mode 100644 index 0000000..b598a9e --- /dev/null +++ b/src/Events/Unarchiving.php @@ -0,0 +1,24 @@ +data = $data; + } +}; diff --git a/src/Facades/CauserResolver.php b/src/Facades/CauserResolver.php new file mode 100644 index 0000000..fc66006 --- /dev/null +++ b/src/Facades/CauserResolver.php @@ -0,0 +1,10 @@ + \Tripteki\Log\Repositories\Eloquent\LogRepository::class, + \Tripteki\Log\Contracts\Repository\Admin\ILogRepository::class => \Tripteki\Log\Repositories\Eloquent\Admin\LogRepository::class, + ]; + + /** + * @var bool + */ + public static $subjectUid = true; + + /** + * @var bool + */ + public static $loadConfig = true; + + /** + * @var bool + */ + public static $runsMigrations = true; + + /** + * @return bool + */ + public static function shouldSubjectUid() + { + return static::$subjectUid; + } + + /** + * @return bool + */ + public static function shouldLoadConfig() + { + return static::$loadConfig; + } + + /** + * @return bool + */ + public static function shouldRunMigrations() + { + return static::$runsMigrations; + } + + /** + * @return void + */ + public static function ignoreSubjectUid() + { + static::$subjectUid = false; + } + + /** + * @return void + */ + public static function ignoreConfig() + { + static::$loadConfig = false; + } + + /** + * @return void + */ + public static function ignoreMigrations() + { + static::$runsMigrations = false; + } + + /** + * @return void + */ + public function boot() + { + parent::boot(); + + $this->dataEventListener(); + + $this->registerPublishers(); + $this->registerConfigs(); + $this->registerCommands(); + $this->registerMigrations(); + } + + /** + * @return void + */ + protected function registerConfigs() + { + if (static::shouldLoadConfig()) { + + $this->app["config"]->set("activitylog", []); + $this->mergeConfigFrom(__DIR__."/../../config/log.php", "activitylog"); + } + } + + /** + * @return void + */ + protected function registerCommands() + { + if (! $this->app->isProduction() && $this->app->runningInConsole()) { + + $this->commands( + [ + InstallCommand::class, + ]); + } + } + + /** + * @return void + */ + protected function registerMigrations() + { + if ($this->app->runningInConsole() && static::shouldRunMigrations()) { + + $this->loadMigrationsFrom(__DIR__."/../../database/migrations"); + } + } + + /** + * @return void + */ + protected function registerPublishers() + { + $this->publishes( + [ + __DIR__."/../../config/log.php" => config_path("activitylog.php"), + ], + + "tripteki-laravelphp-log"); + + if (! static::shouldRunMigrations()) { + + $this->publishes( + [ + __DIR__."/../../database/migrations" => database_path("migrations"), + ], + + "tripteki-laravelphp-log-migrations"); + } + + $this->publishes( + [ + __DIR__."/../../stubs/tests/Feature/Log/LogTest.stub" => base_path("tests/Feature/Log/LogTest.php"), + ], + + "tripteki-laravelphp-log-tests"); + } + + /** + * @return void + */ + public function dataEventListener() + { + Log::observe(UniqueIdObserver::class); + } +}; diff --git a/src/Repositories/Eloquent/Admin/LogRepository.php b/src/Repositories/Eloquent/Admin/LogRepository.php new file mode 100644 index 0000000..0505de9 --- /dev/null +++ b/src/Repositories/Eloquent/Admin/LogRepository.php @@ -0,0 +1,47 @@ + $querystring["limit"] ?? request()->query("limit", 10), + "current_page" => $querystring["current_page"] ?? request()->query("current_page", 1), + ]; + extract($querystringed); + + $field = "updated_at"; + $fields = [ "id", "causer_type", "causer_id", "subject_type", "subject_id", "log_name", "properties", "event", "created_at", "updated_at", ]; + + $content = QueryBuilder::for(\Spatie\Activitylog\ActivitylogServiceProvider::getActivityModelInstance()->with([ "subject", "causer", ])->withTrashed())-> + defaultSort("-".$field)-> + allowedSorts($fields)-> + allowedFilters($fields)-> + paginate($limit, $fields, "current_page", $current_page)->appends(empty($querystring) ? request()->query() : $querystringed); + + return $content; + } + + /** + * @param int|string $identifier + * @param array $querystring|[] + * @return mixed + */ + public function get($identifier, $querystring = []) + { + $content = \Spatie\Activitylog\ActivitylogServiceProvider::getActivityModelInstance()->withTrashed()->findOrFail($identifier); + $content = $content->load([ "subject", "causer", ]); + + return $content; + } +}; diff --git a/src/Repositories/Eloquent/LogRepository.php b/src/Repositories/Eloquent/LogRepository.php new file mode 100644 index 0000000..f89f889 --- /dev/null +++ b/src/Repositories/Eloquent/LogRepository.php @@ -0,0 +1,128 @@ + $querystring["type"] ?? request()->query("type", "unarchived"), + "limit" => $querystring["limit"] ?? request()->query("limit", 10), + "current_page" => $querystring["current_page"] ?? request()->query("current_page", 1), + ]; + extract($querystringed); + + $content = $this->user; + $action = $content->actions(); + + if ($type == "archived") { + + $action = $action->onlyTrashed(); + } + + $field = "updated_at"; + $fields = [ "id", "subject_type", "subject_id", "log_name", "properties", "event", "created_at", "updated_at", ]; + + $content = $content->setRelation("actions", + QueryBuilder::for($action)-> + defaultSort("-".$field)-> + allowedSorts($fields)-> + allowedFilters($fields)-> + paginate($limit, $fields, "current_page", $current_page)->appends(empty($querystring) ? request()->query() : $querystringed)); + $content = $content->loadCount("actions"); + + return collect($content)->only([ "actions_count", "actions", ]); + } + + /** + * @param int|string $identifier + * @param array $querystring|[] + * @return mixed + */ + public function get($identifier, $querystring = []) + { + $content = $this->user->actions()->findOrFail($identifier); + + return $content; + } + + /** + * @param int|string $identifier + * @return mixed + */ + public function delete($identifier) + { + $content = $this->user->actions()->findOrFail($identifier); + + DB::beginTransaction(); + + try { + + $content->delete(); + + DB::commit(); + + } catch (Exception $exception) { + + DB::rollback(); + } + + return $content; + } + + /** + * @param int|string $identifier + * @return mixed + */ + public function archive($identifier) + { + $content = $this->delete($identifier); + + event(new Archived($content)); + + return $content; + } + + /** + * @param int|string $identifier + * @return mixed + */ + public function unarchive($identifier) + { + $content = $this->user->actions()->withTrashed()->findOrFail($identifier); + + DB::beginTransaction(); + + try { + + $content->restore(); + + DB::commit(); + + event(new Unarchived($content)); + + } catch (Exception $exception) { + + DB::rollback(); + } + + return $content; + } +}; diff --git a/src/Repositories/QueryBuilder/.gitkeep b/src/Repositories/QueryBuilder/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/Traits/LogCauseTrait.php b/src/Traits/LogCauseTrait.php new file mode 100644 index 0000000..43c551c --- /dev/null +++ b/src/Traits/LogCauseTrait.php @@ -0,0 +1,10 @@ +logOnlyDirty() + ->useLogName(isset(static::$recordName) ? static::$recordName : get_class($this)); + + if (isset(static::$recordLists)) { + + $log = $log->logOnly(static::$recordLists); + + } else { + + $log = $log->logFillable(); + } + + return $log; + } +}; diff --git a/stubs/app/Exports/Logs/.gitkeep b/stubs/app/Exports/Logs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/stubs/app/Http/Controllers/Admin/Log/LogAdminController.php b/stubs/app/Http/Controllers/Admin/Log/LogAdminController.php new file mode 100644 index 0000000..0eb3bbf --- /dev/null +++ b/stubs/app/Http/Controllers/Admin/Log/LogAdminController.php @@ -0,0 +1,111 @@ +logAdminRepository = $logAdminRepository; + } + + /** + * @OA\Get( + * path="/admin/logs", + * tags={"Admin Log"}, + * summary="Index", + * @OA\Parameter( + * required=false, + * in="query", + * name="limit", + * description="Log's Pagination Limit." + * ), + * @OA\Parameter( + * required=false, + * in="query", + * name="current_page", + * description="Log's Pagination Current Page." + * ), + * @OA\Parameter( + * required=false, + * in="query", + * name="order", + * description="Log's Pagination Order." + * ), + * @OA\Parameter( + * required=false, + * in="query", + * name="filter[]", + * description="Log's Pagination Filter." + * ), + * @OA\Response( + * response=200, + * description="Success." + * ) + * ) + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\JsonResponse + */ + public function index(Request $request) + { + $data = []; + $statecode = 200; + + $data = $this->logAdminRepository->all(); + + return iresponse($data, $statecode); + } + + /** + * @OA\Get( + * path="/admin/logs/{log}", + * tags={"Admin Log"}, + * summary="Show", + * @OA\Parameter( + * required=true, + * in="path", + * name="log", + * description="Log's Log." + * ), + * @OA\Response( + * response=200, + * description="Success." + * ), + * @OA\Response( + * response=404, + * description="Not Found." + * ) + * ) + * + * @param \App\Http\Requests\Admin\Logs\LogShowValidation $request + * @param string $log + * @return \Illuminate\Http\JsonResponse + */ + public function show(LogShowValidation $request, $log) + { + $form = $request->validated(); + $data = []; + $statecode = 200; + + $data = $this->logAdminRepository->get($log); + + return iresponse($data, $statecode); + } +}; diff --git a/stubs/app/Http/Controllers/Log/LogController.php b/stubs/app/Http/Controllers/Log/LogController.php new file mode 100644 index 0000000..e5378d7 --- /dev/null +++ b/stubs/app/Http/Controllers/Log/LogController.php @@ -0,0 +1,194 @@ +logRepository = $logRepository; + } + + /** + * @OA\Get( + * path="/logs", + * tags={"Logs"}, + * summary="Index", + * security={{ "bearerAuth": {} }}, + * @OA\Parameter( + * required=false, + * in="query", + * name="type", + * schema={"type": "string", "enum": {"archived", "unarchived"}}, + * description="Log's Type." + * ), + * @OA\Parameter( + * required=false, + * in="query", + * name="limit", + * description="Log's Pagination Limit." + * ), + * @OA\Parameter( + * required=false, + * in="query", + * name="current_page", + * description="Log's Pagination Current Page." + * ), + * @OA\Parameter( + * required=false, + * in="query", + * name="order", + * description="Log's Pagination Order." + * ), + * @OA\Parameter( + * required=false, + * in="query", + * name="filter[]", + * description="Log's Pagination Filter." + * ), + * @OA\Response( + * response=200, + * description="Success." + * ) + * ) + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\JsonResponse + */ + public function index(Request $request) + { + $data = []; + $statecode = 200; + + $this->logRepository->setUser($request->user()); + + $data = $this->logRepository->all(); + + return iresponse($data, $statecode); + } + + /** + * @OA\Get( + * path="/logs/{log}", + * tags={"Logs"}, + * summary="Show", + * security={{ "bearerAuth": {} }}, + * @OA\Parameter( + * required=true, + * in="path", + * name="log", + * description="Log's Log." + * ), + * @OA\Response( + * response=200, + * description="Success." + * ), + * @OA\Response( + * response=404, + * description="Not Found." + * ) + * ) + * + * @param \App\Http\Requests\Logs\LogShowValidation $request + * @param string $log + * @return \Illuminate\Http\JsonResponse + */ + public function show(LogShowValidation $request, $log) + { + $form = $request->validated(); + $data = []; + $statecode = 200; + + $this->logRepository->setUser($request->user()); + + $data = $this->logRepository->get($log); + + return iresponse($data, $statecode); + } + + /** + * @OA\Put( + * path="/logs/{context}", + * tags={"Logs"}, + * summary="Update", + * security={{ "bearerAuth": {} }}, + * @OA\Parameter( + * required=true, + * in="path", + * name="context", + * schema={"type": "string", "enum": {"archive", "unarchive"}}, + * description="Log's Context." + * ), + * @OA\RequestBody( + * @OA\MediaType( + * mediaType="application/x-www-form-urlencoded", + * @OA\Schema( + * @OA\Property( + * property="logs", + * type="array", + * @OA\Items(type="string"), + * description="Log's Logs." + * ) + * ) + * ) + * ), + * @OA\Response( + * response=201, + * description="Created." + * ), + * @OA\Response( + * response=422, + * description="Unprocessable Entity." + * ), + * @OA\Response( + * response=404, + * description="Not Found." + * ) + * ) + * + * @param \App\Http\Requests\Logs\LogUpdateValidation $request + * @param string $context + * @return \Illuminate\Http\JsonResponse + */ + public function update(LogUpdateValidation $request, $context) + { + $form = $request->validated(); + $data = []; + $statecode = 202; + + $this->logRepository->setUser($request->user()); + + if ($this->logRepository->getUser()) { + + foreach ($form["logs"] as $log) { + + if ($context == LogUpdateValidation::ARCHIVE) $data[] = $this->logRepository->archive($log); + else if ($context == LogUpdateValidation::UNARCHIVE) $data[] = $this->logRepository->unarchive($log); + } + + if ($data) { + + $statecode = 201; + } + } + + return iresponse($data, $statecode); + } +}; diff --git a/stubs/app/Http/Requests/Admin/Logs/LogShowValidation.php b/stubs/app/Http/Requests/Admin/Logs/LogShowValidation.php new file mode 100644 index 0000000..e7c3435 --- /dev/null +++ b/stubs/app/Http/Requests/Admin/Logs/LogShowValidation.php @@ -0,0 +1,40 @@ + $this->route("log"), + ]; + } + + /** + * @return bool + */ + public function authorize() + { + return true; + } + + /** + * @return array + */ + public function rules() + { + $provider = \Spatie\Activitylog\ActivitylogServiceProvider::getActivityModelInstance(); + + return [ + + "log" => "required|string|exists:".get_class($provider).",".keyName($provider), + ]; + } +}; diff --git a/stubs/app/Http/Requests/Logs/LogShowValidation.php b/stubs/app/Http/Requests/Logs/LogShowValidation.php new file mode 100644 index 0000000..b75eb93 --- /dev/null +++ b/stubs/app/Http/Requests/Logs/LogShowValidation.php @@ -0,0 +1,51 @@ + $this->route("log"), + ]; + } + + /** + * @return bool + */ + public function authorize() + { + return true; + } + + /** + * @return array + */ + public function rules() + { + $provider = \Spatie\Activitylog\ActivitylogServiceProvider::getActivityModelInstance(); + + return [ + + "log" => [ + + "required", + "string", + Rule::exists(get_class($provider), keyName($provider))->where(function ($query) { + + return $query->where("causer_type", get_class(app(AuthModelContract::class)))->where("causer_id", Auth::id()); + }), + ], + ]; + } +}; diff --git a/stubs/app/Http/Requests/Logs/LogUpdateValidation.php b/stubs/app/Http/Requests/Logs/LogUpdateValidation.php new file mode 100644 index 0000000..1923aef --- /dev/null +++ b/stubs/app/Http/Requests/Logs/LogUpdateValidation.php @@ -0,0 +1,61 @@ + $this->route("context"), + ]; + } + + /** + * @return bool + */ + public function authorize() + { + return true; + } + + /** + * @return array + */ + public function rules() + { + $provider = \Spatie\Activitylog\ActivitylogServiceProvider::getActivityModelInstance(); + + return [ + + "context" => "required|string|in:".self::ARCHIVE.",".self::UNARCHIVE, + "logs" => "required|array", + "logs.*" => [ + + Rule::exists(get_class($provider), keyName($provider))->where(function ($query) { + + return $query->where("causer_type", get_class(app(AuthModelContract::class)))->where("causer_id", Auth::id()); + }), + ], + ]; + } +}; diff --git a/stubs/app/Http/Responses/.gitkeep b/stubs/app/Http/Responses/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/stubs/app/Imports/Logs/.gitkeep b/stubs/app/Imports/Logs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/stubs/routes/admin/log.php b/stubs/routes/admin/log.php new file mode 100644 index 0000000..c81c42d --- /dev/null +++ b/stubs/routes/admin/log.php @@ -0,0 +1,12 @@ +middleware(config("adminer.middleware.admin"))->group(function () { + + /** + * Logs. + */ + Route::apiResource("logs", LogAdminController::class)->only([ "index", "show", ])->parameters([ "logs" => "log", ]); +}); diff --git a/stubs/routes/user/log.php b/stubs/routes/user/log.php new file mode 100644 index 0000000..5c11008 --- /dev/null +++ b/stubs/routes/user/log.php @@ -0,0 +1,14 @@ +middleware(config("adminer.middleware.user"))->group(function () { + + /** + * Logs. + */ + Route::get("logs", [ LogController::class, "index", ]); + Route::get("logs/{log}", [ LogController::class, "show", ]); + Route::put("logs/{context}", [ LogController::class, "update", ]); +}); diff --git a/stubs/tests/Feature/Log/LogTest.stub b/stubs/tests/Feature/Log/LogTest.stub new file mode 100644 index 0000000..c4fed29 --- /dev/null +++ b/stubs/tests/Feature/Log/LogTest.stub @@ -0,0 +1,24 @@ +user(); + $this->actingAs($user); + + $data = $this->get(/* config("adminer.route.user") ?? */"api"."/logs"); + $data->assertStatus(200); + } +};