├── .gitignore ├── phpunit.xml.dist ├── .github └── workflows │ └── tests.yaml ├── LICENSE.txt ├── composer.json ├── src ├── UserTrailsServiceProvider.php ├── HasDeleteTrails.php └── HasUserTrails.php ├── tests ├── AuthDeleteAuditTrailTest.php ├── AuthAuditTrailTest.php ├── SimpleAuditTrailTest.php └── TestCase.php └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | composer.lock 3 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | ./tests/ 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.github/workflows/tests.yaml: -------------------------------------------------------------------------------- 1 | name: tests 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | tests: 9 | runs-on: ubuntu-latest 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | php: [7.3, 7.4, 8.0] 14 | laravel: [5.*, 6.*, 7.*, 8.*] 15 | exclude: 16 | - php: 8.0 17 | laravel: 5.* 18 | 19 | name: P${{ matrix.php }} - L${{ matrix.laravel }} 20 | 21 | steps: 22 | - name: Checkout code 23 | uses: actions/checkout@v2 24 | 25 | - name: Setup PHP 26 | uses: shivammathur/setup-php@v2 27 | with: 28 | php-version: ${{ matrix.php }} 29 | extensions: dom, curl, libxml, mbstring, zip, json 30 | coverage: none 31 | 32 | - name: Install dependencies 33 | run: | 34 | composer require "illuminate/contracts=${{ matrix.laravel }}" --no-update 35 | composer update --prefer-dist --no-interaction --no-progress 36 | - name: Execute tests 37 | run: vendor/bin/phpunit --verbose --configuration=phpunit.xml.dist 38 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Insense Private Limited 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "insenseanalytics/laravel-user-audit-trails", 3 | "description": "User audit trails for Laravel Eloquent.", 4 | "keywords": [ 5 | "laravel", 6 | "audit trails", 7 | "audit", 8 | "user trails" 9 | ], 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Paras Malhotra", 14 | "email": "paras@insenseanalytics.com" 15 | } 16 | ], 17 | "minimum-stability": "dev", 18 | "require": { 19 | "illuminate/support": "^5.5|^6.0|^7.0|^8.0", 20 | "illuminate/database": "^5.5|^6.0|^7.0|^8.0" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "Insense\\LaravelUserAuditTrails\\": "src/" 25 | } 26 | }, 27 | "autoload-dev": { 28 | "psr-4": { 29 | "Insense\\LaravelUserAuditTrails\\Tests\\": "tests/" 30 | } 31 | }, 32 | "require-dev": { 33 | "phpunit/phpunit": "^6.0|^7.0|8.0|^9.0", 34 | "orchestra/testbench": "^3.5|^4.0|^5.0|^6.0", 35 | "doctrine/dbal": "^2.6" 36 | }, 37 | "extra": { 38 | "laravel": { 39 | "providers": [ 40 | "Insense\\LaravelUserAuditTrails\\UserTrailsServiceProvider" 41 | ] 42 | } 43 | }, 44 | "prefer-stable": true 45 | } -------------------------------------------------------------------------------- /src/UserTrailsServiceProvider.php: -------------------------------------------------------------------------------- 1 | integer($created_by)->unsigned()->nullable(); 25 | } 26 | 27 | if (!is_null($updated_by)) { 28 | $this->integer($updated_by)->unsigned()->nullable(); 29 | } 30 | return $this; 31 | }); 32 | 33 | Blueprint::macro('deletetrails', function ($deleted_by = 'deleted_by') { 34 | if (!is_null($deleted_by)) { 35 | $this->integer($deleted_by)->unsigned()->nullable(); 36 | } 37 | return $this; 38 | }); 39 | 40 | Blueprint::macro('dropUsertrails', function ($created_by = 'created_by', $updated_by = 'updated_by') { 41 | $columnsToDrop = []; 42 | if (!is_null($created_by)) { 43 | $columnsToDrop[] = $created_by; 44 | } 45 | 46 | if (!is_null($updated_by)) { 47 | $columnsToDrop[] = $updated_by; 48 | } 49 | 50 | if (!empty($columnsToDrop)) { 51 | $this->dropColumn($columnsToDrop); 52 | } 53 | }); 54 | 55 | Blueprint::macro('dropDeletetrails', function ($deleted_by = 'deleted_by') { 56 | $columnsToDrop = []; 57 | if (!is_null($deleted_by)) { 58 | $columnsToDrop[] = $deleted_by; 59 | } 60 | 61 | if (!empty($columnsToDrop)) { 62 | $this->dropColumn($columnsToDrop); 63 | } 64 | }); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/HasDeleteTrails.php: -------------------------------------------------------------------------------- 1 | usesDeleteTrails() && $model->isSoftDeleting()) { 30 | $model->updateDeleteTrails(); 31 | } 32 | }); 33 | } 34 | 35 | 36 | /** 37 | * To check if model is soft deleted or not 38 | * @param type $model 39 | */ 40 | public function isSoftDeleting() { 41 | return in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($this)) && !$this->isForceDeleting(); 42 | } 43 | 44 | /** 45 | * Update the deleted by user audit trails. 46 | */ 47 | protected function updateDeleteTrails() 48 | { 49 | $user = Auth::user(); 50 | 51 | if (!is_null(static::$DELETED_BY) && !$this->isDirty(static::$DELETED_BY)) { 52 | $this->setDeletedBy($user ? $user->getKey() : null); 53 | } 54 | } 55 | 56 | /** 57 | * Set the value of the "created by" attribute. 58 | * 59 | * @param mixed $value 60 | * 61 | * @return $this 62 | */ 63 | public function setDeletedBy($value) 64 | { 65 | $this->{static::$DELETED_BY} = $value; 66 | 67 | return $this; 68 | } 69 | 70 | /** 71 | * Determine if the model uses user audit trails. 72 | * 73 | * @return bool 74 | */ 75 | public function usesDeleteTrails() 76 | { 77 | return $this->deleteTrails; 78 | } 79 | 80 | /** 81 | * Get the name of the "created by" column. 82 | * 83 | * @return string 84 | */ 85 | public function getDeletedByColumn() 86 | { 87 | return static::$DELETED_BY; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /tests/AuthDeleteAuditTrailTest.php: -------------------------------------------------------------------------------- 1 | makeUser(); 11 | $this->actingAs($firstUser); 12 | $post = $this->makePostDt(); 13 | 14 | $secondUser = $this->makeSecondUser(); 15 | $this->actingAs($secondUser); 16 | 17 | $post->delete(); 18 | $this->assertSame($firstUser->id, $post->created_by); 19 | $this->assertSame($firstUser->id, $post->updated_by); 20 | $this->assertSame($secondUser->id, $post->deleted_by); 21 | 22 | } 23 | 24 | /** @test */ 25 | public function it_updates_custom_created_updated_deleted_audit_delete_trails() 26 | { 27 | $user = $this->makeUser(); 28 | $this->actingAs($user); 29 | $comment = $this->makeCommentDt(); 30 | 31 | $this->assertSame($user->id, $comment->createdBy); 32 | $this->assertSame($user->id, $comment->updatedBy); 33 | 34 | $comment->delete(); 35 | $this->assertSame($user->id, $comment->deletedBy); 36 | } 37 | 38 | /** @test */ 39 | public function it_updates_deleted_audit_user_info_to_latest_user_trails() 40 | { 41 | $firsrtUser = $this->makeUser(); 42 | $post = $this->makePostDt(); 43 | $this->actingAs($firsrtUser); 44 | $post->delete(); 45 | $this->assertSame($firsrtUser->id, $post->deleted_by); 46 | 47 | $secondUser = $this->makeSecondUser(); 48 | $this->actingAs($secondUser); 49 | 50 | $post->restore(); 51 | $post->delete(); 52 | 53 | $this->assertSame($secondUser->id, $post->deleted_by); 54 | 55 | } 56 | 57 | 58 | /** @test */ 59 | public function it_respects_manual_audit_delete_trails() 60 | { 61 | $user = $this->makeUser(); 62 | $this->actingAs($user); 63 | $post = $this->makePostDt(); 64 | $post->title = 'New Title'; 65 | $post->updated_by = 5; 66 | $post->deleted_by = 7; 67 | $post->save(); 68 | 69 | $this->assertSame(5, $post->updated_by); 70 | $this->assertSame(7, $post->deleted_by); 71 | } 72 | 73 | /** @test */ 74 | public function it_does_not_get_applied_if_not_using_deleted_trails() 75 | { 76 | $user = $this->makeUser(); 77 | $this->actingAs($user); 78 | $page = $this->makePageDt(); 79 | 80 | $this->assertSame($user->id, $page->created_by); 81 | $this->assertTrue(is_null($page->updated_by)); 82 | $this->assertTrue(is_null($page->deleted_by)); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /tests/AuthAuditTrailTest.php: -------------------------------------------------------------------------------- 1 | makeUser(); 14 | $this->actingAs($user); 15 | $post = $this->makePost(); 16 | 17 | $this->assertSame($user->id, $post->created_by); 18 | $this->assertSame($user->id, $post->updated_by); 19 | } 20 | 21 | /** @test */ 22 | public function it_updates_custom_created_audit_user_trails() 23 | { 24 | $user = $this->makeUser(); 25 | $this->actingAs($user); 26 | $comment = $this->makeComment(); 27 | 28 | $this->assertSame($user->id, $comment->createdBy); 29 | $this->assertSame($user->id, $comment->updatedBy); 30 | } 31 | 32 | /** @test */ 33 | public function it_updates_updated_audit_user_trails() 34 | { 35 | $user = $this->makeUser(); 36 | $post = $this->makePost(); 37 | $this->actingAs($user); 38 | $post->title = 'New Title'; 39 | $post->save(); 40 | 41 | $this->assertTrue(is_null($post->created_by)); 42 | $this->assertSame($user->id, $post->updated_by); 43 | } 44 | 45 | /** @test */ 46 | public function it_updates_custom_updated_audit_user_trails() 47 | { 48 | $user = $this->makeUser(); 49 | $comment = $this->makeComment(); 50 | $this->actingAs($user); 51 | $comment->title = 'New Title'; 52 | $comment->save(); 53 | 54 | $this->assertTrue(is_null($comment->created_by)); 55 | $this->assertSame($user->id, $comment->updatedBy); 56 | } 57 | 58 | /** @test */ 59 | public function it_respects_manual_audit_user_trails() 60 | { 61 | $user = $this->makeUser(); 62 | $this->actingAs($user); 63 | $post = $this->makePost(); 64 | $post->title = 'New Title'; 65 | $post->updated_by = 5; 66 | $post->save(); 67 | 68 | $this->assertSame(5, $post->updated_by); 69 | } 70 | 71 | /** @test */ 72 | public function it_does_not_update_createdby_on_updation() 73 | { 74 | $user = $this->makeUser(); 75 | $this->actingAs($user); 76 | $post = $this->makePost(); 77 | 78 | $secondUser = $this->makeSecondUser(); 79 | $this->actingAs($secondUser); 80 | $post->title = 'New Title'; 81 | $post->save(); 82 | 83 | $this->assertSame($user->id, $post->created_by); 84 | $this->assertSame($secondUser->id, $post->updated_by); 85 | } 86 | 87 | /** @test */ 88 | public function it_updates_user_audit_trail_on_touch() 89 | { 90 | $user = $this->makeUser(); 91 | $this->actingAs($user); 92 | $post = $this->makePost(); 93 | 94 | $secondUser = $this->makeSecondUser(); 95 | $this->actingAs($secondUser); 96 | $post->touchUserTrails(); 97 | 98 | $this->assertSame($user->id, $post->created_by); 99 | $this->assertSame($secondUser->id, $post->updated_by); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/HasUserTrails.php: -------------------------------------------------------------------------------- 1 | usesUserTrails()) { 37 | $model->updateUserTrails(); 38 | } 39 | }); 40 | } 41 | 42 | /* 43 | * Update the model's user audit trails. 44 | * 45 | * @return bool 46 | */ 47 | public function touchUserTrails() 48 | { 49 | if (!$this->usesUserTrails()) { 50 | return false; 51 | } 52 | 53 | $this->updateUserTrails(); 54 | 55 | return $this->save(); 56 | } 57 | 58 | /** 59 | * Update the created by and updated by user audit trails. 60 | */ 61 | protected function updateUserTrails() 62 | { 63 | $user = Auth::user(); 64 | 65 | if (!is_null(static::$UPDATED_BY) && !$this->isDirty(static::$UPDATED_BY)) { 66 | $this->setUpdatedBy($user ? $user->getKey() : null); 67 | } 68 | 69 | if (!is_null(static::$CREATED_BY) && !$this->exists && !$this->isDirty(static::$CREATED_BY)) { 70 | $this->setCreatedBy($user ? $user->getKey() : null); 71 | } 72 | } 73 | 74 | /** 75 | * Set the value of the "created by" attribute. 76 | * 77 | * @param mixed $value 78 | * 79 | * @return $this 80 | */ 81 | public function setCreatedBy($value) 82 | { 83 | $this->{static::$CREATED_BY} = $value; 84 | 85 | return $this; 86 | } 87 | 88 | /** 89 | * Set the value of the "updated by" attribute. 90 | * 91 | * @param mixed $value 92 | * 93 | * @return $this 94 | */ 95 | public function setUpdatedBy($value) 96 | { 97 | $this->{static::$UPDATED_BY} = $value; 98 | 99 | return $this; 100 | } 101 | 102 | /** 103 | * Determine if the model uses user audit trails. 104 | * 105 | * @return bool 106 | */ 107 | public function usesUserTrails() 108 | { 109 | return $this->userTrails; 110 | } 111 | 112 | /** 113 | * Get the name of the "created by" column. 114 | * 115 | * @return string 116 | */ 117 | public function getCreatedByColumn() 118 | { 119 | return static::$CREATED_BY; 120 | } 121 | 122 | /** 123 | * Get the name of the "updated by" column. 124 | * 125 | * @return string 126 | */ 127 | public function getUpdatedByColumn() 128 | { 129 | return static::$UPDATED_BY; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /tests/SimpleAuditTrailTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(Blueprint::hasMacro('usertrails')); 14 | $this->assertTrue(Blueprint::hasMacro('dropUsertrails')); 15 | } 16 | 17 | /** @test */ 18 | public function it_creates_the_audit_user_trail_columns() 19 | { 20 | $this->assertTrue(DB::schema()->hasColumn('posts', 'created_by')); 21 | $this->assertTrue(DB::schema()->hasColumn('posts', 'updated_by')); 22 | } 23 | 24 | /** @test */ 25 | public function it_creates_custom_audit_user_trail_columns() 26 | { 27 | $this->assertTrue(DB::schema()->hasColumn('comments', 'createdBy')); 28 | $this->assertTrue(DB::schema()->hasColumn('comments', 'updatedBy')); 29 | } 30 | 31 | /** @test */ 32 | public function it_omits_null_audit_user_trail_columns() 33 | { 34 | $this->assertTrue(DB::schema()->hasColumn('pages', 'created_by')); 35 | $this->assertFalse(DB::schema()->hasColumn('pages', 'updated_by')); 36 | } 37 | 38 | /** @test */ 39 | public function it_drops_the_audit_user_trail_columns() 40 | { 41 | $this->dropUserTrailColumns(); 42 | $this->assertFalse(DB::schema()->hasColumn('posts', 'created_by')); 43 | $this->assertFalse(DB::schema()->hasColumn('posts', 'updated_by')); 44 | } 45 | 46 | /** @test */ 47 | public function it_drops_custom_audit_user_trail_columns() 48 | { 49 | $this->dropUserTrailColumns(); 50 | $this->assertFalse(DB::schema()->hasColumn('comments', 'createdBy')); 51 | $this->assertFalse(DB::schema()->hasColumn('comments', 'updatedBy')); 52 | } 53 | 54 | /** @test */ 55 | public function it_drops_null_audit_user_trail_columns() 56 | { 57 | $this->dropUserTrailColumns(); 58 | $this->assertFalse(DB::schema()->hasColumn('pages', 'created_by')); 59 | } 60 | 61 | /** @test */ 62 | public function it_contains_null_audit_fields_if_not_authenticated() 63 | { 64 | $post = $this->makePost(); 65 | 66 | $this->assertTrue(is_null($post->created_by)); 67 | $this->assertTrue(is_null($post->updated_by)); 68 | } 69 | 70 | 71 | /** @test */ 72 | public function it_provides_deletetrails_macro() 73 | { 74 | $this->assertTrue(Blueprint::hasMacro('deletetrails')); 75 | $this->assertTrue(Blueprint::hasMacro('dropDeletetrails')); 76 | } 77 | 78 | /** @test */ 79 | public function it_checks_the_audit_user_delete_trail_columns() 80 | { 81 | $this->assertTrue(DB::schema()->hasColumn('post_dts', 'deleted_by')); 82 | $this->assertTrue(DB::schema()->hasColumn('comment_dts', 'deletedBy')); 83 | $this->assertFalse(DB::schema()->hasColumn('page_dts', 'deletedByUserId')); 84 | } 85 | 86 | /** @test */ 87 | public function it_drops_the_audit_delete_trail_columns() 88 | { 89 | $this->dropDeleteTrailColumns(); 90 | $this->assertFalse(DB::schema()->hasColumn('post_dts', 'deleted_by')); 91 | } 92 | 93 | /** @test */ 94 | public function it_drops_the_audit_delete_trail_custom_columns() 95 | { 96 | $this->dropDeleteTrailColumns(); 97 | $this->assertFalse(DB::schema()->hasColumn('comment_dts', 'deletedBy')); 98 | } 99 | 100 | /** @test */ 101 | public function it_omits_non_soft_deleted_delete_trail_columns() { 102 | $this->assertFalse(DB::schema()->hasColumn('pages_dt', 'deleted_by')); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Laravel User Audit Trails 2 | 3 | ![tests](https://github.com/insenseanalytics/laravel-user-audit-trails/workflows/tests/badge.svg?branch=master) 4 | [![License](https://poser.pugx.org/insenseanalytics/laravel-user-audit-trails/license)](https://packagist.org/packages/insenseanalytics/laravel-user-audit-trails) 5 | [![Latest Stable Version](https://poser.pugx.org/insenseanalytics/laravel-user-audit-trails/v/stable)](https://packagist.org/packages/insenseanalytics/laravel-user-audit-trails) 6 | [![Total Downloads](https://poser.pugx.org/insenseanalytics/laravel-user-audit-trails/downloads)](https://packagist.org/packages/insenseanalytics/laravel-user-audit-trails) 7 | 8 | This package is created to add audit user trails by using Laravel Eloquent ORM. Using this package, you would be able to record in the respective database tables, the `created_by`, `updated_by` and `deleted_by` user IDs. 9 | 10 | ## Basic Example 11 | 12 | Add the audit trail columns in your database **migrations** like so: 13 | 14 | ```php 15 | $table->usertrails(); // for created_by, updated_by 16 | $table->deletetrails(); // for deleted_by 17 | ``` 18 | 19 | Next, in your model just use the `HasUserTrails` and `HasDeleteTrails` trait to automatically setup audit user trails like so: 20 | ```php 21 | class Post extends \Illuminate\Database\Eloquent\Model 22 | { 23 | use \Insense\LaravelUserAuditTrails\HasUserTrails; 24 | use \Insense\LaravelUserAuditTrails\HasDeleteTrails; 25 | } 26 | ``` 27 | 28 | That's it! Now, sit back and observe the magic of audit user trails. When a new record is created, `created_by` will be updated to the user ID that created it. When a record is updated, `updated_by` will be updated to the user ID that updated it. When a record is soft deleted, `deleted_by` will be updated to the user ID that deleted it. 29 | 30 | ## Requirements 31 | - [PHP >= 7.1](http://php.net/) 32 | - [Laravel 5.5+|6.x|7.x|8.x](https://github.com/laravel/framework) 33 | 34 | ## Quick Installation 35 | ```bash 36 | $ composer require insenseanalytics/laravel-user-audit-trails 37 | ``` 38 | 39 | #### Service Provider (Optional / auto discovered on Laravel 5.5+) 40 | Register provider on your `config/app.php` file. 41 | ```php 42 | 'providers' => [ 43 | ..., 44 | Insense\LaravelUserAuditTrails\UserTrailsServiceProvider::class, 45 | ] 46 | ``` 47 | 48 | ## Setting Up Custom Column Names 49 | If you want to override the default audit trail names of `created_by`, `updated_by` and `deleted_by`, you may do so like so: 50 | 51 | In your database **migration**, add the audit trail columns like so: 52 | ```php 53 | $table->usertrails('your-created-by-column', 'your-updated-by-column'); 54 | $table->deletetrails('your-deleted-by-column'); 55 | ``` 56 | 57 | Next, in your model, override the static properties `CREATED_BY`, `UPDATED_BY` and `DELETED_BY`. Note that PHP does not allow overriding static properties in the same class, so you would need to extend your model class from a base model class that uses the `\Insense\LaravelUserAuditTrails\HasUserTrails` trait like so: 58 | 59 | First create your base model class (if not already created). If already created, just add the trait. 60 | 61 | ```php 62 | class BaseModel extends \Illuminate\Database\Eloquent\Model 63 | { 64 | use \Insense\LaravelUserAuditTrails\HasUserTrails; 65 | use \Insense\LaravelUserAuditTrails\HasDeleteTrails; 66 | } 67 | ``` 68 | Next, override the static properties `CREATED_BY`, `UPDATED_BY` and `DELETED_BY` in your model (that extends the base model) like so: 69 | 70 | ```php 71 | class YourModel extends BaseModel 72 | { 73 | public static $CREATED_BY = 'your-created-by-column'; 74 | public static $UPDATED_BY = 'your-updated-by-column'; 75 | public static $DELETED_BY = 'your-deleted-by-column'; 76 | } 77 | ``` 78 | 79 | ## Omitting Updated By or Created By Columns 80 | If you wish to omit one of the audit trail columns, you can just set the one you would like to omit to null in your database **migration** like so: 81 | 82 | ```php 83 | $table->usertrails('created_by', null); 84 | ``` 85 | The example above omits the updated_by column. You can also do the reverse to omit updated_by by setting the first argument to null. 86 | 87 | Next, override the static properties `CREATED_BY` and `UPDATED_BY` in your model (that extends the base model) to set the omitted property to null like so: 88 | 89 | ```php 90 | class YourModel extends BaseModel 91 | { 92 | public static $CREATED_BY = 'created_by'; 93 | public static $UPDATED_BY = null; 94 | } 95 | ``` 96 | 97 | ## Contributing 98 | We are open to PRs as long as they're backed by tests and a small description of the feature added / problem solved. 99 | 100 | ## License 101 | 102 | The MIT License (MIT). Please see [License File](https://github.com/insenseanalytics/laravel-user-audit-trails/blob/master/LICENSE.txt) for more information. 103 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | setUpDatabase(); 24 | $this->migrateTables(); 25 | $this->migrateDeleteTrailstables(); 26 | } 27 | 28 | protected function getPackageProviders($app) 29 | { 30 | return [UserTrailsServiceProvider::class]; 31 | } 32 | 33 | /** 34 | * Define environment setup. 35 | * 36 | * @param \Illuminate\Foundation\Application $app 37 | * @return void 38 | */ 39 | protected function getEnvironmentSetUp($app) 40 | { 41 | // Setup default database to use sqlite :memory: 42 | $app['config']->set('database.default', 'testbench'); 43 | $app['config']->set('database.connections.testbench', [ 44 | 'driver' => 'sqlite', 45 | 'database' => ':memory:', 46 | 'prefix' => '', 47 | ]); 48 | } 49 | 50 | protected function setUpDatabase() 51 | { 52 | $database = new DB; 53 | 54 | $database->addConnection(['driver' => 'sqlite', 'database' => ':memory:']); 55 | $database->bootEloquent(); 56 | $database->setAsGlobal(); 57 | } 58 | 59 | protected function migrateTables() 60 | { 61 | DB::schema()->create('users', function ($table) { 62 | $table->increments('id'); 63 | $table->string('first_name'); 64 | $table->string('last_name'); 65 | $table->string('email')->unique(); 66 | $table->timestamps(); 67 | }); 68 | 69 | DB::schema()->create('posts', function ($table) { 70 | $table->increments('id'); 71 | $table->string('title'); 72 | $table->timestamps(); 73 | $table->usertrails(); 74 | }); 75 | 76 | DB::schema()->create('comments', function ($table) { 77 | $table->increments('id'); 78 | $table->string('title'); 79 | $table->timestamps(); 80 | $table->usertrails('createdBy', 'updatedBy'); 81 | }); 82 | 83 | DB::schema()->create('pages', function ($table) { 84 | $table->increments('id'); 85 | $table->string('title'); 86 | $table->timestamps(); 87 | $table->usertrails('created_by', null); 88 | }); 89 | } 90 | 91 | protected function migrateDeleteTrailstables() 92 | { 93 | DB::schema()->create('post_dts', function ($table) { 94 | $table->increments('id'); 95 | $table->string('title'); 96 | $table->timestamps(); 97 | $table->softDeletes(); 98 | $table->usertrails(); 99 | $table->deletetrails(); 100 | }); 101 | 102 | DB::schema()->create('comment_dts', function ($table) { 103 | $table->increments('id'); 104 | $table->string('title'); 105 | $table->timestamps(); 106 | $table->softDeletes(); 107 | $table->usertrails('createdBy', 'updatedBy'); 108 | $table->deletetrails('deletedBy'); 109 | }); 110 | 111 | DB::schema()->create('page_dts', function ($table) { 112 | $table->increments('id'); 113 | $table->string('title'); 114 | $table->timestamps(); 115 | $table->usertrails('created_by', null); 116 | }); 117 | } 118 | 119 | protected function dropUserTrailColumns() 120 | { 121 | DB::schema()->table('posts', function ($table) { 122 | $table->dropUsertrails(); 123 | }); 124 | 125 | DB::schema()->table('comments', function ($table) { 126 | $table->dropUsertrails('createdBy', 'updatedBy'); 127 | }); 128 | 129 | DB::schema()->table('pages', function ($table) { 130 | $table->dropUsertrails('created_by', null); 131 | }); 132 | } 133 | 134 | protected function dropDeleteTrailColumns() 135 | { 136 | DB::schema()->table('post_dts', function ($table) { 137 | $table->dropDeletetrails(); 138 | }); 139 | 140 | DB::schema()->table('comment_dts', function ($table) { 141 | $table->dropDeletetrails('deletedBy'); 142 | }); 143 | } 144 | 145 | protected function makePost() 146 | { 147 | $post = new Post; 148 | $post->title = 'Some title'; 149 | $post->save(); 150 | return $post; 151 | } 152 | 153 | protected function makeComment() 154 | { 155 | $comment = new Comment; 156 | $comment->title = 'Some title'; 157 | $comment->save(); 158 | return $comment; 159 | } 160 | 161 | protected function makePage() 162 | { 163 | $page = new Page; 164 | $page->title = 'Some title'; 165 | $page->save(); 166 | return $page; 167 | } 168 | 169 | protected function makePostDt() 170 | { 171 | $post = new PostDT; 172 | $post->title = 'Some title'; 173 | $post->save(); 174 | return $post; 175 | } 176 | 177 | protected function makeCommentDt() 178 | { 179 | $comment = new CommentDT; 180 | $comment->title = 'Some title'; 181 | $comment->save(); 182 | return $comment; 183 | } 184 | 185 | protected function makePageDt() 186 | { 187 | $page = new PageDT; 188 | $page->title = 'Some title'; 189 | $page->save(); 190 | return $page; 191 | } 192 | 193 | protected function makeUser() 194 | { 195 | $user = new User; 196 | $user->first_name = 'Paras'; 197 | $user->last_name = 'Malhotra'; 198 | $user->email = 'paras@insenseanalytics.com'; 199 | $user->save(); 200 | return $user; 201 | } 202 | 203 | protected function makeSecondUser() 204 | { 205 | $user = new User; 206 | $user->first_name = 'Paras'; 207 | $user->last_name = 'Malhotra'; 208 | $user->email = 'paras@test.com'; 209 | $user->save(); 210 | return $user; 211 | } 212 | 213 | protected function deletePostDT() 214 | { 215 | $post = PostDT::latest()->first(); 216 | return $post->delete(); 217 | } 218 | 219 | protected function deleteCommentDT() 220 | { 221 | $comment = CommentDT::latest()->first(); 222 | $comment->delete(); 223 | return $comment; 224 | } 225 | 226 | protected function deletePageDT() 227 | { 228 | $page = PageDT::latest()->first(); 229 | $page->delete(); 230 | return $page; 231 | } 232 | 233 | protected function restorePostDT($id) 234 | { 235 | $post = PostDT::withTrashed()->find($id); 236 | return $post->trashed() ? $post->restore() :false; 237 | } 238 | 239 | protected function restoreComment($id) 240 | { 241 | $comment = CommentDT::withTrashed()->find($id); 242 | return $comment->trashed() ? $comment->restore() : false; 243 | } 244 | } 245 | 246 | class BaseModel extends Model 247 | { 248 | use HasUserTrails; 249 | } 250 | 251 | class Post extends Model 252 | { 253 | use HasUserTrails; 254 | } 255 | 256 | class Comment extends BaseModel 257 | { 258 | public static $CREATED_BY = 'createdBy'; 259 | public static $UPDATED_BY = 'updatedBy'; 260 | } 261 | 262 | class Page extends BaseModel 263 | { 264 | public static $UPDATED_BY = null; 265 | } 266 | 267 | class BaseModel2 extends Model 268 | { 269 | use HasUserTrails; 270 | use HasDeleteTrails; 271 | } 272 | 273 | class PostDT extends BaseModel2 274 | { 275 | use \Illuminate\Database\Eloquent\SoftDeletes; 276 | 277 | protected $table = "post_dts"; 278 | } 279 | 280 | class CommentDT extends BaseModel2 281 | { 282 | use \Illuminate\Database\Eloquent\SoftDeletes; 283 | public static $CREATED_BY = 'createdBy'; 284 | public static $UPDATED_BY = 'updatedBy'; 285 | public static $DELETED_BY = 'deletedBy'; 286 | 287 | protected $table = "comment_dts"; 288 | } 289 | 290 | class PageDT extends BaseModel2 291 | { 292 | use \Illuminate\Database\Eloquent\SoftDeletes; 293 | public static $UPDATED_BY = null; 294 | public static $DELETED_BY = 'deletedByUserId'; 295 | 296 | protected $table = "page_dts"; 297 | } 298 | 299 | class User extends Model implements Authenticatable 300 | { 301 | use \Illuminate\Auth\Authenticatable; 302 | } 303 | --------------------------------------------------------------------------------