2016-03-25 01:18:05 -07:00
< ? php
2021-06-10 13:15:52 -07:00
2016-03-25 01:18:05 -07:00
namespace App\Models ;
2021-06-10 13:15:52 -07:00
2018-07-16 14:13:07 -07:00
use App\Models\Traits\Searchable ;
2016-12-29 22:23:36 -08:00
use App\Presenters\Presentable ;
2024-07-04 12:49:22 -07:00
use Carbon\Carbon ;
2021-06-10 13:19:27 -07:00
use Illuminate\Database\Eloquent\Factories\HasFactory ;
2016-09-29 22:20:49 -07:00
use Illuminate\Database\Eloquent\SoftDeletes ;
2016-03-25 01:18:05 -07:00
2016-04-07 13:21:09 -07:00
/**
* Model for the Actionlog ( the table that keeps a historical log of
* checkouts , checkins , and updates ) .
*
* @ version v1 . 0
*/
2016-12-29 22:23:36 -08:00
class Actionlog extends SnipeModel
2016-03-25 01:18:05 -07:00
{
2024-08-10 09:14:20 -07:00
use CompanyableTrait ;
2021-06-10 13:17:44 -07:00
use HasFactory ;
2024-01-30 13:14:59 -08:00
// This is to manually set the source (via setActionSource()) for determineActionSource()
protected ? string $source = null ;
2024-08-10 09:00:34 -07:00
protected $with = [ 'admin' ];
2024-01-30 13:14:59 -08:00
2021-06-10 13:16:56 -07:00
protected $presenter = \App\Presenters\ActionlogPresenter :: class ;
2016-03-25 01:18:05 -07:00
use SoftDeletes ;
2016-12-29 22:23:36 -08:00
use Presentable ;
2021-06-10 13:17:18 -07:00
2021-06-10 13:15:52 -07:00
protected $table = 'action_logs' ;
2016-03-25 01:18:05 -07:00
public $timestamps = true ;
2023-12-14 06:33:25 -08:00
protected $fillable = [
'created_at' ,
'item_type' ,
'user_id' ,
'item_id' ,
'action_type' ,
'note' ,
'target_id' ,
'target_type' ,
'stored_eula'
];
2016-03-25 01:18:05 -07:00
2018-07-16 14:13:07 -07:00
use Searchable ;
2021-06-10 13:15:52 -07:00
2018-07-16 14:13:07 -07:00
/**
* The attributes that should be included when searching the model .
2021-06-10 13:15:52 -07:00
*
2018-07-16 14:13:07 -07:00
* @ var array
*/
2023-12-14 06:33:25 -08:00
protected $searchableAttributes = [
'action_type' ,
'note' ,
'log_meta' ,
'user_id' ,
'remote_ip' ,
'user_agent' ,
'action_source'
];
2018-07-16 14:13:07 -07:00
/**
* The relations and their attributes that should be included when searching the model .
2021-06-10 13:15:52 -07:00
*
2018-07-16 14:13:07 -07:00
* @ var array
*/
protected $searchableRelations = [
2021-06-10 13:15:52 -07:00
'company' => [ 'name' ],
2022-08-02 23:50:10 -07:00
'admin' => [ 'first_name' , 'last_name' , 'username' , 'email' ],
'user' => [ 'first_name' , 'last_name' , 'username' , 'email' ],
2024-08-11 02:26:02 -07:00
'assets' => [ 'asset_tag' , 'name' ],
2018-08-01 00:06:41 -07:00
];
2018-07-16 14:13:07 -07:00
2018-08-01 00:06:41 -07:00
/**
* Override from Builder to automatically add the company
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-09-29 22:20:49 -07:00
public static function boot ()
2016-03-25 01:18:05 -07:00
{
2016-09-29 22:20:49 -07:00
parent :: boot ();
2021-06-10 13:15:52 -07:00
static :: creating ( function ( self $actionlog ) {
2016-09-29 22:20:49 -07:00
// If the admin is a superadmin, let's see if the target instead has a company.
2024-07-04 12:49:22 -07:00
if ( auth () -> user () && auth () -> user () -> isSuperUser ()) {
2016-10-12 18:45:32 -07:00
if ( $actionlog -> target ) {
$actionlog -> company_id = $actionlog -> target -> company_id ;
2016-12-29 14:02:18 -08:00
} elseif ( $actionlog -> item ) {
2016-10-12 18:45:32 -07:00
$actionlog -> company_id = $actionlog -> item -> company_id ;
}
2024-07-04 12:49:22 -07:00
} elseif ( auth () -> user () && auth () -> user () -> company ) {
$actionlog -> company_id = auth () -> user () -> company_id ;
2016-09-29 22:20:49 -07:00
}
});
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the actionlog -> item relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-09-06 19:39:42 -07:00
public function item ()
2016-03-25 01:18:05 -07:00
{
2016-09-06 19:39:42 -07:00
return $this -> morphTo ( 'item' ) -> withTrashed ();
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the actionlog -> company relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-12-29 14:02:18 -08:00
public function company ()
{
2021-06-10 13:16:56 -07:00
return $this -> hasMany ( \App\Models\Company :: class , 'id' , 'company_id' );
2016-11-11 20:30:26 -08:00
}
2022-08-02 23:50:10 -07:00
/**
* Establishes the actionlog -> asset relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function assets ()
{
return $this -> hasMany ( \App\Models\Asset :: class , 'id' , 'item_id' );
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the actionlog -> item type relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-09-06 19:39:42 -07:00
public function itemType ()
2016-03-25 01:18:05 -07:00
{
2016-12-29 14:02:18 -08:00
if ( $this -> item_type == AssetModel :: class ) {
2021-06-10 13:15:52 -07:00
return 'model' ;
2016-09-15 19:58:27 -07:00
}
2021-06-10 13:15:52 -07:00
2016-09-06 19:39:42 -07:00
return camel_case ( class_basename ( $this -> item_type ));
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the actionlog -> target type relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2017-05-23 14:31:14 -07:00
public function targetType ()
{
if ( $this -> target_type == User :: class ) {
2021-06-10 13:15:52 -07:00
return 'user' ;
2017-05-23 14:31:14 -07:00
}
2021-06-10 13:15:52 -07:00
2017-05-23 14:31:14 -07:00
return camel_case ( class_basename ( $this -> target_type ));
}
2016-12-15 20:52:39 -08:00
2018-08-01 00:06:41 -07:00
/**
* Establishes the actionlog -> uploads relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-09-06 19:39:42 -07:00
public function uploads ()
2016-03-25 01:18:05 -07:00
{
2016-09-06 19:39:42 -07:00
return $this -> morphTo ( 'item' )
-> where ( 'action_type' , '=' , 'uploaded' )
2016-03-25 01:18:05 -07:00
-> withTrashed ();
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the actionlog -> userlog relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-09-06 19:39:42 -07:00
public function userlog ()
2016-03-25 01:18:05 -07:00
{
2016-09-06 19:39:42 -07:00
return $this -> target ();
2016-03-25 01:18:05 -07:00
}
2018-08-01 00:06:41 -07:00
/**
2022-08-02 23:50:10 -07:00
* Establishes the actionlog -> admin user relationship
2018-08-01 00:06:41 -07:00
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2022-08-02 23:50:10 -07:00
public function admin ()
2016-03-25 01:18:05 -07:00
{
2016-09-06 19:39:42 -07:00
return $this -> belongsTo ( User :: class , 'user_id' )
2016-03-25 01:18:05 -07:00
-> withTrashed ();
}
2022-08-02 23:50:10 -07:00
/**
* Establishes the actionlog -> user relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
public function user ()
{
return $this -> belongsTo ( User :: class , 'target_id' )
-> withTrashed ();
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the actionlog -> target relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2016-09-06 19:39:42 -07:00
public function target ()
2016-03-25 01:18:05 -07:00
{
2016-12-30 11:44:47 -08:00
return $this -> morphTo ( 'target' ) -> withTrashed ();
2016-08-02 05:06:17 -07:00
}
2018-08-01 00:06:41 -07:00
/**
* Establishes the actionlog -> location relationship
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return \Illuminate\Database\Eloquent\Relations\Relation
*/
2021-06-10 13:15:52 -07:00
public function location ()
{
2021-06-10 13:16:56 -07:00
return $this -> belongsTo ( \App\Models\Location :: class , 'location_id' ) -> withTrashed ();
2017-08-25 18:40:20 -07:00
}
2018-08-01 00:06:41 -07:00
2016-03-25 01:18:05 -07:00
/**
2018-08-01 00:06:41 -07:00
* Check if the file exists , and if it does , force a download
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
* @ return string | false
*/
2016-10-31 21:00:30 -07:00
public function get_src ( $type = 'assets' , $fieldname = 'filename' )
2016-03-25 01:18:05 -07:00
{
2021-06-10 13:15:52 -07:00
if ( $this -> filename != '' ) {
$file = config ( 'app.private_uploads' ) . '/' . $type . '/' . $this -> { $fieldname };
2018-05-02 14:13:06 -07:00
return $file ;
}
2021-06-10 13:15:52 -07:00
2018-05-02 14:13:06 -07:00
return false ;
2016-03-25 01:18:05 -07:00
}
/**
2018-08-01 00:06:41 -07:00
* Saves the log record with the action type
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v3 . 0 ]
2021-06-10 13:15:52 -07:00
* @ return bool
2018-08-01 00:06:41 -07:00
*/
2016-03-25 01:18:05 -07:00
public function logaction ( $actiontype )
{
$this -> action_type = $actiontype ;
2023-12-14 06:33:39 -08:00
$this -> remote_ip = request () -> ip ();
$this -> user_agent = request () -> header ( 'User-Agent' );
$this -> action_source = $this -> determineActionSource ();
2016-03-25 01:18:05 -07:00
if ( $this -> save ()) {
return true ;
} else {
return false ;
}
}
2018-08-01 00:06:41 -07:00
/**
* Calculate the number of days until the next audit
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return int
*/
2021-06-10 13:15:52 -07:00
public function daysUntilNextAudit ( $monthInterval = 12 , $asset = null )
{
2017-08-29 16:00:22 -07:00
$now = Carbon :: now ();
2017-08-25 18:40:20 -07:00
$last_audit_date = $this -> created_at ;
2017-08-29 16:00:22 -07:00
$next_audit = $last_audit_date -> addMonth ( $monthInterval );
$next_audit_days = $now -> diffInDays ( $next_audit );
2017-08-25 18:40:20 -07:00
// Override the default setting for interval if the asset has its own next audit date
if (( $asset ) && ( $asset -> next_audit_date )) {
$override_default_next = \Carbon :: parse ( $asset -> next_audit_date );
2017-08-29 16:00:22 -07:00
$next_audit_days = $override_default_next -> diffInDays ( $now );
2017-08-25 18:40:20 -07:00
}
return $next_audit_days ;
}
2018-08-01 00:06:41 -07:00
/**
* Calculate the date of the next audit
*
* @ author [ A . Gianotto ] [ < snipe @ snipe . net > ]
* @ since [ v4 . 0 ]
* @ return \Datetime
*/
2021-06-10 13:15:52 -07:00
public function calcNextAuditDate ( $monthInterval = 12 , $asset = null )
{
2017-08-25 18:40:20 -07:00
$last_audit_date = Carbon :: parse ( $this -> created_at );
// If there is an asset-specific next date already given,
if (( $asset ) && ( $asset -> next_audit_date )) {
2017-08-28 17:20:20 -07:00
return \Carbon :: parse ( $asset -> next_audit_date );
2017-08-25 18:40:20 -07:00
}
2017-08-28 17:20:20 -07:00
return \Carbon :: parse ( $last_audit_date ) -> addMonths ( $monthInterval ) -> toDateString ();
2017-08-25 18:40:20 -07:00
}
2016-03-25 01:18:05 -07:00
/**
2018-08-01 00:06:41 -07:00
* Gets action logs in chronological order , excluding uploads
*
* @ author Vincent Sposato < vincent . sposato @ gmail . com >
* @ since v1 . 0
* @ return \Illuminate\Database\Eloquent\Collection
*/
2016-03-25 01:18:05 -07:00
public function getListingOfActionLogsChronologicalOrder ()
{
2016-09-06 19:39:42 -07:00
return $this -> all ()
2016-03-25 01:18:05 -07:00
-> where ( 'action_type' , '!=' , 'uploaded' )
2016-09-06 19:39:42 -07:00
-> orderBy ( 'item_id' , 'asc' )
2016-03-25 01:18:05 -07:00
-> orderBy ( 'created_at' , 'asc' )
-> get ();
}
2023-12-14 06:33:39 -08:00
2023-12-14 06:43:38 -08:00
/**
* Determines what the type of request is so we can log it to the action_log
*
* @ author A . Gianotto < snipe @ snipe . net >
* @ since v6 . 3.0
* @ return string
*/
2024-01-30 13:14:59 -08:00
public function determineActionSource () : string
{
// This is a manually set source
if ( $this -> source ) {
return $this -> source ;
}
2023-12-14 06:33:39 -08:00
// This is an API call
if ((( request () -> header ( 'content-type' ) && ( request () -> header ( 'accept' )) == 'application/json' ))
&& ( starts_with ( request () -> header ( 'authorization' ), 'Bearer ' ))) {
return 'api' ;
}
// This is probably NOT an API call
if ( request () -> filled ( '_token' )) {
return 'gui' ;
}
// We're not sure, probably cli
return 'cli/unknown' ;
}
2024-01-30 13:14:59 -08:00
// Manually sets $this->source for determineActionSource()
public function setActionSource ( $source = null ) : void
{
$this -> source = $source ;
}
2024-08-10 09:00:34 -07:00
public function scopeOrderAdmin ( $query , $order )
{
return $query -> leftJoin ( 'users as admin_sort' , 'action_logs.user_id' , '=' , 'admin_sort.id' ) -> select ( 'action_logs.*' ) -> orderBy ( 'admin_sort.first_name' , $order ) -> orderBy ( 'admin_sort.last_name' , $order );
}
2016-03-25 01:18:05 -07:00
}