2017-07-01 20:29:49 +00:00
< ? php
namespace Pterodactyl\Repositories\Eloquent ;
2020-07-07 04:25:00 +00:00
use Illuminate\Http\Request ;
2017-08-12 20:29:01 +00:00
use Webmozart\Assert\Assert ;
2018-01-05 04:49:50 +00:00
use Illuminate\Support\Collection ;
2017-11-18 01:01:42 +00:00
use Pterodactyl\Repositories\Repository ;
2020-07-07 04:25:00 +00:00
use Illuminate\Database\Eloquent\Builder ;
2017-08-12 20:29:01 +00:00
use Illuminate\Database\Query\Expression ;
2018-01-05 04:49:50 +00:00
use Illuminate\Database\Eloquent\ModelNotFoundException ;
2018-01-11 05:19:03 +00:00
use Illuminate\Contracts\Pagination\LengthAwarePaginator ;
2017-07-01 20:29:49 +00:00
use Pterodactyl\Contracts\Repository\RepositoryInterface ;
2017-07-08 19:07:51 +00:00
use Pterodactyl\Exceptions\Model\DataValidationException ;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException ;
2017-07-01 20:29:49 +00:00
abstract class EloquentRepository extends Repository implements RepositoryInterface
{
2020-07-07 04:25:00 +00:00
/**
* @ var bool
*/
protected $useRequestFilters = false ;
/**
* Determines if the repository function should use filters off the request object
* present when returning results . This allows repository methods to be called in API
* context ' s such that we can pass through ? filter [ name ] = Dane & sort = desc for example .
*
* @ param bool $usingFilters
* @ return $this
*/
public function usingRequestFilters ( $usingFilters = true )
{
$this -> useRequestFilters = $usingFilters ;
return $this ;
}
/**
* Returns the request instance .
*
* @ return \Illuminate\Http\Request
*/
protected function request ()
{
return $this -> app -> make ( Request :: class );
}
/**
* Paginate the response data based on the page para .
*
* @ param \Illuminate\Database\Eloquent\Builder $instance
* @ param int $default
*
* @ return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
protected function paginate ( Builder $instance , int $default = 50 )
{
if ( ! $this -> useRequestFilters ) {
return $instance -> paginate ( $default );
}
return $instance -> paginate ( $this -> request () -> query ( 'per_page' , $default ));
}
2017-07-01 20:29:49 +00:00
/**
2018-01-05 04:49:50 +00:00
* Return an instance of the eloquent model bound to this
* repository instance .
*
* @ return \Illuminate\Database\Eloquent\Model
*/
public function getModel ()
{
return $this -> model ;
}
/**
* Return an instance of the builder to use for this repository .
*
2017-07-01 20:29:49 +00:00
* @ return \Illuminate\Database\Eloquent\Builder
*/
public function getBuilder ()
{
return $this -> getModel () -> newQuery ();
}
/**
2018-01-05 04:49:50 +00:00
* Create a new record in the database and return the associated model .
*
* @ param array $fields
2019-09-06 04:32:57 +00:00
* @ param bool $validate
* @ param bool $force
2017-07-08 19:07:51 +00:00
* @ return \Illuminate\Database\Eloquent\Model | bool
2018-01-05 04:49:50 +00:00
*
* @ throws \Pterodactyl\Exceptions\Model\DataValidationException
2017-07-01 20:29:49 +00:00
*/
2018-01-05 04:49:50 +00:00
public function create ( array $fields , bool $validate = true , bool $force = false )
2017-07-01 20:29:49 +00:00
{
$instance = $this -> getBuilder () -> newModelInstance ();
2018-01-05 04:49:50 +00:00
( $force ) ? $instance -> forceFill ( $fields ) : $instance -> fill ( $fields );
2017-07-01 20:29:49 +00:00
if ( ! $validate ) {
$saved = $instance -> skipValidation () -> save ();
} else {
if ( ! $saved = $instance -> save ()) {
throw new DataValidationException ( $instance -> getValidator ());
}
}
return ( $this -> withFresh ) ? $instance -> fresh () : $saved ;
}
/**
2018-01-05 04:49:50 +00:00
* Find a model that has the specific ID passed .
*
* @ param int $id
* @ return \Illuminate\Database\Eloquent\Model
*
* @ throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
2017-07-01 20:29:49 +00:00
*/
2018-01-05 04:49:50 +00:00
public function find ( int $id )
2017-07-01 20:29:49 +00:00
{
2018-01-05 04:49:50 +00:00
try {
return $this -> getBuilder () -> findOrFail ( $id , $this -> getColumns ());
} catch ( ModelNotFoundException $exception ) {
throw new RecordNotFoundException ;
2017-07-01 20:29:49 +00:00
}
}
2017-07-08 19:07:51 +00:00
/**
2018-01-05 04:49:50 +00:00
* Find a model matching an array of where clauses .
*
* @ param array $fields
* @ return \Illuminate\Support\Collection
2017-07-08 19:07:51 +00:00
*/
2018-01-05 04:49:50 +00:00
public function findWhere ( array $fields ) : Collection
2017-07-01 20:29:49 +00:00
{
2017-07-08 20:04:59 +00:00
return $this -> getBuilder () -> where ( $fields ) -> get ( $this -> getColumns ());
}
/**
2018-01-05 04:49:50 +00:00
* Find and return the first matching instance for the given fields .
*
* @ param array $fields
2017-07-08 20:04:59 +00:00
* @ return \Illuminate\Database\Eloquent\Model
2018-01-05 04:49:50 +00:00
*
* @ throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
2017-07-08 20:04:59 +00:00
*/
public function findFirstWhere ( array $fields )
{
2018-01-05 04:49:50 +00:00
try {
return $this -> getBuilder () -> where ( $fields ) -> firstOrFail ( $this -> getColumns ());
} catch ( ModelNotFoundException $exception ) {
2017-09-16 03:13:33 +00:00
throw new RecordNotFoundException ;
2017-07-08 20:04:59 +00:00
}
2017-07-01 20:29:49 +00:00
}
2017-08-05 22:20:07 +00:00
/**
2018-01-05 04:49:50 +00:00
* Return a count of records matching the passed arguments .
*
* @ param array $fields
* @ return int
2017-08-05 22:20:07 +00:00
*/
2018-01-05 04:49:50 +00:00
public function findCountWhere ( array $fields ) : int
2017-08-05 22:20:07 +00:00
{
return $this -> getBuilder () -> where ( $fields ) -> count ( $this -> getColumns ());
}
2017-07-01 20:29:49 +00:00
/**
2018-01-05 04:49:50 +00:00
* Delete a given record from the database .
*
2019-09-06 04:32:57 +00:00
* @ param int $id
2018-01-05 04:49:50 +00:00
* @ param bool $destroy
* @ return int
2017-07-01 20:29:49 +00:00
*/
2018-01-05 04:49:50 +00:00
public function delete ( int $id , bool $destroy = false ) : int
2017-07-01 20:29:49 +00:00
{
2018-01-05 04:49:50 +00:00
return $this -> deleteWhere ([ 'id' => $id ], $destroy );
2017-08-09 02:21:10 +00:00
}
/**
2018-01-05 04:49:50 +00:00
* Delete records matching the given attributes .
*
* @ param array $attributes
2019-09-06 04:32:57 +00:00
* @ param bool $force
2018-01-05 04:49:50 +00:00
* @ return int
2017-08-09 02:21:10 +00:00
*/
2018-01-05 04:49:50 +00:00
public function deleteWhere ( array $attributes , bool $force = false ) : int
2017-08-09 02:21:10 +00:00
{
$instance = $this -> getBuilder () -> where ( $attributes );
2017-07-01 20:29:49 +00:00
2017-08-09 02:21:10 +00:00
return ( $force ) ? $instance -> forceDelete () : $instance -> delete ();
2017-07-01 20:29:49 +00:00
}
/**
2018-01-05 04:49:50 +00:00
* Update a given ID with the passed array of fields .
*
2019-09-06 04:32:57 +00:00
* @ param int $id
2018-01-05 04:49:50 +00:00
* @ param array $fields
2019-09-06 04:32:57 +00:00
* @ param bool $validate
* @ param bool $force
2018-01-05 04:49:50 +00:00
* @ return \Illuminate\Database\Eloquent\Model | bool
*
* @ throws \Pterodactyl\Exceptions\Model\DataValidationException
* @ throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
2017-07-01 20:29:49 +00:00
*/
2018-01-05 04:49:50 +00:00
public function update ( $id , array $fields , bool $validate = true , bool $force = false )
2017-07-01 20:29:49 +00:00
{
2018-01-05 04:49:50 +00:00
try {
$instance = $this -> getBuilder () -> where ( 'id' , $id ) -> firstOrFail ();
} catch ( ModelNotFoundException $exception ) {
throw new RecordNotFoundException ;
2017-07-01 20:29:49 +00:00
}
2018-01-05 04:49:50 +00:00
( $force ) ? $instance -> forceFill ( $fields ) : $instance -> fill ( $fields );
2017-07-01 20:29:49 +00:00
if ( ! $validate ) {
$saved = $instance -> skipValidation () -> save ();
} else {
if ( ! $saved = $instance -> save ()) {
throw new DataValidationException ( $instance -> getValidator ());
}
}
2017-07-08 19:17:07 +00:00
return ( $this -> withFresh ) ? $instance -> fresh () : $saved ;
2017-07-01 20:29:49 +00:00
}
2020-04-04 23:07:09 +00:00
/**
* Update a model using the attributes passed .
*
* @ param array | \Closure $attributes
* @ param array $values
* @ return int
*/
public function updateWhere ( $attributes , array $values )
{
return $this -> getBuilder () -> where ( $attributes ) -> update ( $values );
}
2017-07-24 00:57:43 +00:00
/**
2018-01-05 04:49:50 +00:00
* Perform a mass update where matching records are updated using whereIn .
* This does not perform any model data validation .
*
* @ param string $column
2019-09-06 04:32:57 +00:00
* @ param array $values
* @ param array $fields
2018-01-05 04:49:50 +00:00
* @ return int
2017-07-24 00:57:43 +00:00
*/
2018-01-05 04:49:50 +00:00
public function updateWhereIn ( string $column , array $values , array $fields ) : int
2017-07-24 00:57:43 +00:00
{
2018-01-05 04:49:50 +00:00
Assert :: notEmpty ( $column , 'First argument passed to updateWhereIn must be a non-empty string.' );
2017-08-12 20:29:01 +00:00
2017-07-24 00:57:43 +00:00
return $this -> getBuilder () -> whereIn ( $column , $values ) -> update ( $fields );
}
2017-07-08 19:07:51 +00:00
/**
2018-01-05 04:49:50 +00:00
* Update a record if it exists in the database , otherwise create it .
*
* @ param array $where
* @ param array $fields
2019-09-06 04:32:57 +00:00
* @ param bool $validate
* @ param bool $force
2018-01-05 04:49:50 +00:00
* @ return \Illuminate\Database\Eloquent\Model
*
* @ throws \Pterodactyl\Exceptions\Model\DataValidationException
* @ throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
2017-07-08 19:07:51 +00:00
*/
2018-01-05 04:49:50 +00:00
public function updateOrCreate ( array $where , array $fields , bool $validate = true , bool $force = false )
2017-07-01 20:29:49 +00:00
{
2018-01-05 04:49:50 +00:00
foreach ( $where as $item ) {
Assert :: true ( is_scalar ( $item ) || is_null ( $item ), 'First argument passed to updateOrCreate should be an array of scalar or null values, received an array value of %s.' );
}
try {
$instance = $this -> setColumns ( 'id' ) -> findFirstWhere ( $where );
} catch ( RecordNotFoundException $exception ) {
return $this -> create ( array_merge ( $where , $fields ), $validate , $force );
}
return $this -> update ( $instance -> id , $fields , $validate , $force );
2017-07-01 20:29:49 +00:00
}
2017-07-15 16:52:34 +00:00
/**
2018-01-05 04:49:50 +00:00
* Return all records associated with the given model .
*
* @ return \Illuminate\Support\Collection
2020-07-07 04:25:00 +00:00
* @ deprecated Just use the model
2017-07-15 16:52:34 +00:00
*/
2018-01-05 04:49:50 +00:00
public function all () : Collection
2017-07-15 16:52:34 +00:00
{
2020-09-13 18:29:47 +00:00
return $this -> getBuilder () -> get ( $this -> getColumns ());
2017-07-15 16:52:34 +00:00
}
2017-07-20 01:49:41 +00:00
2018-01-11 05:19:03 +00:00
/**
* Return a paginated result set using a search term if set on the repository .
*
* @ param int $perPage
* @ return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
public function paginated ( int $perPage ) : LengthAwarePaginator
{
2020-09-13 18:29:47 +00:00
return $this -> getBuilder () -> paginate ( $perPage , $this -> getColumns ());
2018-01-11 05:19:03 +00:00
}
2017-07-20 01:49:41 +00:00
/**
2018-01-05 04:49:50 +00:00
* Insert a single or multiple records into the database at once skipping
* validation and mass assignment checking .
*
* @ param array $data
* @ return bool
2017-07-20 01:49:41 +00:00
*/
2018-01-05 04:49:50 +00:00
public function insert ( array $data ) : bool
2017-07-20 01:49:41 +00:00
{
return $this -> getBuilder () -> insert ( $data );
}
2017-07-25 02:34:10 +00:00
2017-08-06 02:10:32 +00:00
/**
* Insert multiple records into the database and ignore duplicates .
*
2017-08-22 03:10:48 +00:00
* @ param array $values
2017-08-06 02:10:32 +00:00
* @ return bool
*/
2018-01-05 04:49:50 +00:00
public function insertIgnore ( array $values ) : bool
2017-08-06 02:10:32 +00:00
{
if ( empty ( $values )) {
return true ;
}
2018-01-05 04:49:50 +00:00
foreach ( $values as $key => $value ) {
ksort ( $value );
$values [ $key ] = $value ;
2017-08-06 02:10:32 +00:00
}
$bindings = array_values ( array_filter ( array_flatten ( $values , 1 ), function ( $binding ) {
return ! $binding instanceof Expression ;
}));
$grammar = $this -> getBuilder () -> toBase () -> getGrammar ();
$table = $grammar -> wrapTable ( $this -> getModel () -> getTable ());
$columns = $grammar -> columnize ( array_keys ( reset ( $values )));
$parameters = collect ( $values ) -> map ( function ( $record ) use ( $grammar ) {
return sprintf ( '(%s)' , $grammar -> parameterize ( $record ));
}) -> implode ( ', ' );
$statement = " insert ignore into $table ( $columns ) values $parameters " ;
return $this -> getBuilder () -> getConnection () -> statement ( $statement , $bindings );
}
2018-05-26 18:58:49 +00:00
/**
2018-06-02 21:32:26 +00:00
* Get the amount of entries in the database .
2018-05-26 18:58:49 +00:00
*
* @ return int
2020-07-07 04:25:00 +00:00
* @ deprecated just use the count method off a model
2018-05-26 18:58:49 +00:00
*/
public function count () : int
{
return $this -> getBuilder () -> count ();
}
2017-07-01 20:29:49 +00:00
}