Skip to content

Commit

Permalink
Compatibility backports
Browse files Browse the repository at this point in the history
  • Loading branch information
Radiergummi committed Mar 30, 2021
1 parent 6c23f74 commit 4ee28a2
Show file tree
Hide file tree
Showing 6 changed files with 3,157 additions and 39 deletions.
64 changes: 64 additions & 0 deletions src/Compatibility/Exceptions/InvalidCastException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

/**
* This file is part of elasticsearch, a Matchory application.
*
* Unauthorized copying of this file, via any medium, is strictly prohibited.
* Its contents are strictly confidential and proprietary.
*
* @copyright 2020–2021 Matchory GmbH · All rights reserved
* @author Moritz Friedrich <moritz@matchory.com>
*/

declare(strict_types=1);

namespace Matchory\Elasticsearch\Compatibility\Exceptions;

use RuntimeException;

use function get_class;

class InvalidCastException extends RuntimeException
{
/**
* The name of the affected Eloquent model.
*
* @var string
*/
public $model;

/**
* The name of the column.
*
* @var string
*/
public $column;

/**
* The name of the cast type.
*
* @var string
*/
public $castType;

/**
* Create a new exception instance.
*
* @param object $model
* @param string $column
* @param string $castType
*/
public function __construct($model, $column, $castType)
{
$class = get_class($model);

parent::__construct(
"Call to undefined cast [{$castType}] on column " .
"[{$column}] in model [{$class}]."
);

$this->model = $class;
$this->column = $column;
$this->castType = $castType;
}
}
283 changes: 283 additions & 0 deletions src/Compatibility/GuardsAttributes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
<?php
/** @noinspection PhpMissingParamTypeInspection, PhpMissingReturnTypeInspection, ReturnTypeCanBeDeclaredInspection */

declare(strict_types=1);

namespace Matchory\Elasticsearch\Compatibility;

use Illuminate\Support\Str;

use function array_flip;
use function array_intersect_key;
use function array_merge;
use function count;
use function in_array;
use function preg_grep;
use function preg_quote;
use function strpos;

trait GuardsAttributes
{
/**
* Indicates if all mass assignment is enabled.
*
* @var bool
*/
protected static $unguarded = false;

/**
* The actual columns that exist on the database and can be guarded.
*
* @var array
*/
protected static $guardableColumns = [];

/**
* The attributes that are mass assignable.
*
* @var string[]
*/
protected $fillable = [];

/**
* The attributes that aren't mass assignable.
*
* @var string[]|bool
*/
protected $guarded = ['*'];

/**
* Disable all mass assignable restrictions.
*
* @param bool $state
*
* @return void
*/
public static function unguard($state = true)
{
static::$unguarded = $state;
}

/**
* Enable the mass assignment restrictions.
*
* @return void
*/
public static function reguard()
{
static::$unguarded = false;
}

/**
* Determine if the current state is "unguarded".
*
* @return bool
*/
public static function isUnguarded()
{
return static::$unguarded;
}

/**
* Run the given callable while being unguarded.
*
* @param callable $callback
*
* @return mixed
*/
public static function unguarded(callable $callback)
{
if (static::$unguarded) {
return $callback();
}

static::unguard();

try {
return $callback();
} finally {
static::reguard();
}
}

/**
* Get the fillable attributes for the model.
*
* @return string[]
*/
public function getFillable()
{
return $this->fillable;
}

/**
* Set the fillable attributes for the model.
*
* @param array $fillable
*
* @return $this
*/
public function fillable(array $fillable)
{
$this->fillable = $fillable;

return $this;
}

/**
* Merge new fillable attributes with existing fillable attributes on
* the model.
*
* @param array $fillable
*
* @return $this
*/
public function mergeFillable(array $fillable)
{
$this->fillable = array_merge($this->fillable, $fillable);

return $this;
}

/**
* Get the guarded attributes for the model.
*
* @return array
*/
public function getGuarded()
{
return $this->guarded === false
? []
: $this->guarded;
}

/**
* Set the guarded attributes for the model.
*
* @param array $guarded
*
* @return $this
*/
public function guard(array $guarded)
{
$this->guarded = $guarded;

return $this;
}

/**
* Merge new guarded attributes with existing guarded attributes on
* the model.
*
* @param array $guarded
*
* @return $this
*/
public function mergeGuarded(array $guarded)
{
$this->guarded = array_merge($this->guarded, $guarded);

return $this;
}

/**
* Determine if the given attribute may be mass assigned.
*
* @param string $key
*
* @return bool
*/
public function isFillable($key)
{
if (static::$unguarded) {
return true;
}

// If the key is in the "fillable" array, we can of course assume that
// it's a fillable attribute. Otherwise, we will check the guarded array
// when we need to determine if the attribute is black-listed on
// the model.
if (in_array($key, $this->getFillable())) {
return true;
}

// If the attribute is explicitly listed in the "guarded" array then we
// can return false immediately. This means this attribute is definitely
// not fillable and there is no point in going any further in
// this method.
if ($this->isGuarded($key)) {
return false;
}

return empty($this->getFillable()) &&
strpos($key, '.') === false &&
! Str::startsWith($key, '_');
}

/**
* Determine if the given key is guarded.
*
* @param string $key
*
* @return bool
*/
public function isGuarded($key)
{
if (empty($this->getGuarded())) {
return false;
}

return (
$this->getGuarded() === ['*'] ||
! empty(preg_grep(
'/^' . preg_quote($key, '/') . '$/i',
$this->getGuarded()
)) ||
! $this->isGuardableColumn($key)
);
}

/**
* Determine if the model is totally guarded.
*
* @return bool
*/
public function totallyGuarded()
{
return (
count($this->getFillable()) === 0 &&
$this->getGuarded() === ['*']
);
}

/**
* Determine if the given column is a valid, guardable column.
*
* @param string $key
*
* @return bool
* @noinspection PhpUnusedParameterInspection
*/
protected function isGuardableColumn($key)
{
return true;
}

/**
* Get the fillable attributes of a given array.
*
* @param array $attributes
*
* @return array
*/
protected function fillableFromArray(array $attributes)
{
if ( ! static::$unguarded && count($this->getFillable()) > 0) {
return array_intersect_key($attributes, array_flip(
$this->getFillable()
));
}

return $attributes;
}
}
Loading

0 comments on commit 4ee28a2

Please sign in to comment.