Skip to content

Commit

Permalink
Allow for guarding or unguarding multiple attributes at once.
Browse files Browse the repository at this point in the history
  • Loading branch information
TimothyBJacobs committed Mar 28, 2017
1 parent 77a53f5 commit a39a04a
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 20 deletions.
59 changes: 39 additions & 20 deletions src/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,29 +268,42 @@ public function fill( array $data = array() ) {
*
* @since 2.1.0
*
* @param string $attribute
* @param callable $callback
* @param string|array $attribute,...
* @param callable $callback
*/
public function with_guarded( $attribute, $callback ) {

if ( is_array( $attribute ) ) {
$attributes = $attribute;
} else {
$attributes = func_get_args();
$callback = array_pop( $attributes );
}

$unguarded = static::$_unguarded;

if ( $unguarded ) {
static::$_unguarded = false;
}

if ( ( $i = array_search( $attribute, $this->_fillable, true ) ) !== false ) {
unset( $this->_fillable[ $i ] );
$_fillable = $this->_fillable;
$_guarded = $this->_guarded;

if ( $this->_fillable ) {
$this->_fillable = array_diff( $this->_fillable, $attributes );

// If the diff removes all fillable attributes we need to use _guarded.
if ( ! $this->_fillable ) {
$this->_guarded = $attributes;
}
} else {
$this->_guarded[] = $attribute;
$this->_guarded = array_unique( array_merge( $this->_guarded, $attributes ) );
}

$callback( $this );

if ( $i !== false ) {
$this->_fillable[ $i ] = $attribute;
} else {
unset( $this->_guarded[ array_search( $attribute, $this->_guarded, true ) ] );
}
$this->_fillable = $_fillable;
$this->_guarded = $_guarded;

static::$_unguarded = $unguarded;
}
Expand All @@ -300,7 +313,7 @@ public function with_guarded( $attribute, $callback ) {
*
* @since 2.1.0
*
* @param string $attribute
* @param string $attribute,...
* @param callable $callback
*/
public function with_unguarded( $attribute, $callback ) {
Expand All @@ -311,21 +324,27 @@ public function with_unguarded( $attribute, $callback ) {
return;
}

$i = false;
if ( is_array( $attribute ) ) {
$attributes = $attribute;
} else {
$attributes = func_get_args();
$callback = array_pop( $attributes );
}

$_fillable = $this->_fillable;
$_guarded = $this->_guarded;

if ( $this->_fillable ) {
$this->_fillable[] = $attribute;
} elseif ( ( $i = array_search( $attribute, $this->_guarded, true ) ) !== false ) {
unset( $this->_guarded[ $i ] );
$this->_fillable = array_merge( $this->_fillable, $attributes );
} else {
$this->_guarded = array_diff( $this->_guarded, $attributes );
}

$callback( $this );

if ( $this->_fillable ) {
unset( $this->_fillable[ array_search( $attribute, $this->_fillable, true ) ] );
} elseif ( $i !== false ) {
$this->_guarded[ $i ] = $attribute;
}
$this->_fillable = $_fillable;
$this->_guarded = $_guarded;

}

/**
Expand Down
92 changes: 92 additions & 0 deletions tests/unit/test-model-php7.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,51 @@ public static function get_table() {
$this->assertEquals( 'o', $model->get_attribute( 'colC' ) );
}

public function test_with_guarded_multiple() {

$table = $this->get_table();

/** @var Model $model */
$model = new class( $table, [] ) extends Model {

public static $table;

public function __construct( $table = null, $data = array() ) {

if ( $table ) {
static::$table = $table;
}

parent::__construct( [] );
}

public function get_pk() {
return $this->get_attribute( 'colA' );
}

public static function get_table() {
return static::$table;
}

};

$model::$table = $table;

$model->with_guarded( 'colB', 'colC', function ( Model $model ) {
$model->fill( array( 'colA' => 'He', 'colB' => 'll', 'colC' => 'o' ) );
} );

$this->assertEquals( 'He', $model->get_attribute( 'colA' ) );
$this->assertEquals( null, $model->get_attribute( 'colB' ) );
$this->assertEquals( null, $model->get_attribute( 'colC' ) );

$model->fill( array( 'colA' => 'He', 'colB' => 'll', 'colC' => 'o' ) );

$this->assertEquals( 'He', $model->get_attribute( 'colA' ) );
$this->assertEquals( 'll', $model->get_attribute( 'colB' ) );
$this->assertEquals( 'o', $model->get_attribute( 'colC' ) );
}

public function test_with_guarded_and_existing_guarded_properties() {

$table = $this->get_table();
Expand Down Expand Up @@ -387,6 +432,53 @@ public static function get_table() {
$this->assertEquals( 'o', $model->get_attribute( 'colC' ) );
}

public function test_with_unguarded_multiple() {

$table = $this->get_table();

/** @var Model $model */
$model = new class( $table, [] ) extends Model {

public static $table;

protected $_guarded = array( 'colA', 'colB' );

public function __construct( $table = null, $data = array() ) {

if ( $table ) {
static::$table = $table;
}

parent::__construct( [] );
}

public function get_pk() {
return $this->get_attribute( 'colA' );
}

public static function get_table() {
return static::$table;
}

};

$model::$table = $table;

$model->with_unguarded( 'colA', 'colB', function ( Model $model ) {
$model->fill( array( 'colA' => 'He', 'colB' => 'll', 'colC' => 'o' ) );
} );

$this->assertEquals( 'He', $model->get_attribute( 'colA' ) );
$this->assertEquals( 'll', $model->get_attribute( 'colB' ) );
$this->assertEquals( 'o', $model->get_attribute( 'colC' ) );

$model->fill( array( 'colA' => 'Me', 'colB' => 'bo', 'colC' => 'o' ) );

$this->assertEquals( 'He', $model->get_attribute( 'colA' ) );
$this->assertEquals( 'll', $model->get_attribute( 'colB' ) );
$this->assertEquals( 'o', $model->get_attribute( 'colC' ) );
}

public function test_with_unguarded_and_existing_guarded_properties() {

$table = $this->get_table();
Expand Down

0 comments on commit a39a04a

Please sign in to comment.