Skip to content

Commit

Permalink
[8.x] Validated subsets (#38366)
Browse files Browse the repository at this point in the history
* conditional rules

* simplify some code

* allow closures on conditional

* Apply fixes from StyleCI

* fix type hint

* onlyValidated and exceptValidated

* change approach

* Apply fixes from StyleCI

* magic methods

* Update src/Illuminate/Support/ValidatedInput.php

Co-authored-by: Mior Muhammad Zaki <crynobone@gmail.com>

* Apply fixes from StyleCI

* use validator method

* add test case

Co-authored-by: Taylor Otwell <taylorotwell@users.noreply.github.com>
Co-authored-by: Mior Muhammad Zaki <crynobone@gmail.com>
  • Loading branch information
3 people authored Aug 13, 2021
1 parent f3470df commit 3591526
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/Illuminate/Contracts/Support/ValidatedData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Illuminate\Contracts\Support;

use ArrayAccess;
use IteratorAggregate;

interface ValidatedData extends Arrayable, ArrayAccess, IteratorAggregate
{
//
}
10 changes: 10 additions & 0 deletions src/Illuminate/Foundation/Http/FormRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,16 @@ protected function failedAuthorization()
throw new AuthorizationException;
}

/**
* Get a validated input container for the validated input.
*
* @return \Illuminate\Support\ValidatedInput
*/
public function safe()
{
return $this->validator->safe();
}

/**
* Get the validated data from the request.
*
Expand Down
208 changes: 208 additions & 0 deletions src/Illuminate/Support/ValidatedInput.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
<?php

namespace Illuminate\Support;

use ArrayIterator;
use Illuminate\Contracts\Support\ValidatedData;
use stdClass;

class ValidatedInput implements ValidatedData
{
/**
* The underlying input.
*
* @var array
*/
protected $input;

/**
* Create a new validated input container.
*
* @param array $input
* @return void
*/
public function __construct(array $input)
{
$this->input = $input;
}

/**
* Get a subset containing the provided keys with values from the input data.
*
* @param array|mixed $keys
* @return array
*/
public function only($keys)
{
$results = [];

$input = $this->input;

$placeholder = new stdClass;

foreach (is_array($keys) ? $keys : func_get_args() as $key) {
$value = data_get($input, $key, $placeholder);

if ($value !== $placeholder) {
Arr::set($results, $key, $value);
}
}

return $results;
}

/**
* Get all of the input except for a specified array of items.
*
* @param array|mixed $keys
* @return array
*/
public function except($keys)
{
$keys = is_array($keys) ? $keys : func_get_args();

$results = $this->input;

Arr::forget($results, $keys);

return $results;
}

/**
* Get the input as a collection.
*
* @return \Illuminate\Support\Collection
*/
public function collect()
{
return new Collection($this->input);
}

/**
* Get the raw, underlying input array.
*
* @return array
*/
public function all()
{
return $this->input;
}

/**
* Get the instance as an array.
*
* @return array
*/
public function toArray()
{
return $this->all();
}

/**
* Dynamically access input data.
*
* @param string $name
* @return mixed
*/
public function __get($name)
{
return $this->input[$name];
}

/**
* Dynamically set input data.
*
* @param string $name
* @param mixed $value
* @return mixed
*/
public function __set($name, $value)
{
$this->input[$name] = $value;
}

/**
* Determine if an input key is set.
*
* @return bool
*/
public function __isset($name)
{
return isset($this->input[$name]);
}

/**
* Remove an input key.
*
* @param string $name
* @return void
*/
public function __unset($name)
{
unset($this->input[$name]);
}

/**
* Determine if an item exists at an offset.
*
* @param mixed $key
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists($key)
{
return isset($this->input[$key]);
}

/**
* Get an item at a given offset.
*
* @param mixed $key
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($key)
{
return $this->input[$key];
}

/**
* Set the item at a given offset.
*
* @param mixed $key
* @param mixed $value
* @return void
*/
#[\ReturnTypeWillChange]
public function offsetSet($key, $value)
{
if (is_null($key)) {
$this->input[] = $value;
} else {
$this->input[$key] = $value;
}
}

/**
* Unset the item at a given offset.
*
* @param string $key
* @return void
*/
#[\ReturnTypeWillChange]
public function offsetUnset($key)
{
unset($this->input[$key]);
}

/**
* Get an iterator for the input.
*
* @return \ArrayIterator
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return new ArrayIterator($this->input);
}
}
11 changes: 11 additions & 0 deletions src/Illuminate/Validation/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Illuminate\Support\Fluent;
use Illuminate\Support\MessageBag;
use Illuminate\Support\Str;
use Illuminate\Support\ValidatedInput;
use RuntimeException;
use stdClass;
use Symfony\Component\HttpFoundation\File\UploadedFile;
Expand Down Expand Up @@ -500,6 +501,16 @@ public function validateWithBag(string $errorBag)
}
}

/**
* Get a validated input container for the validated input.
*
* @return \Illuminate\Support\ValidatedInput
*/
public function safe()
{
return new ValidatedInput($this->validated());
}

/**
* Get the attributes and values that were validated.
*
Expand Down
20 changes: 20 additions & 0 deletions tests/Support/ValidatedInputTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Illuminate\Tests\Support;

use Illuminate\Support\ValidatedInput;
use PHPUnit\Framework\TestCase;

class ValidatedInputTest extends TestCase
{
public function test_can_access_input()
{
$input = new ValidatedInput(['name' => 'Taylor', 'votes' => 100]);

$this->assertEquals('Taylor', $input->name);
$this->assertEquals('Taylor', $input['name']);
$this->assertEquals(['name' => 'Taylor'], $input->only(['name']));
$this->assertEquals(['name' => 'Taylor'], $input->except(['votes']));
$this->assertEquals(['name' => 'Taylor', 'votes' => 100], $input->all());
}
}

0 comments on commit 3591526

Please sign in to comment.