Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement a FormHelper context class for Form\Form.
This allows FormHelper to work with Form instances.
- Loading branch information
Showing
2 changed files
with
340 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
<?php | ||
/** | ||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | ||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* | ||
* Licensed under The MIT License | ||
* For full copyright and license information, please see the LICENSE.txt | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* @link http://cakephp.org CakePHP(tm) Project | ||
* @since 3.0.0 | ||
* @license http://www.opensource.org/licenses/mit-license.php MIT License | ||
*/ | ||
namespace Cake\View\Form; | ||
|
||
use Cake\Form\Form; | ||
use Cake\Network\Request; | ||
use Cake\View\Form\ContextInterface; | ||
|
||
/** | ||
* Provides a context provider for Cake\Form\Form instances. | ||
* | ||
* This context provider simply fulfils the interface requirements | ||
* that FormHelper has and allows access to the request data. | ||
*/ | ||
class FormContext implements ContextInterface { | ||
|
||
/** | ||
* The request object. | ||
* | ||
* @var \Cake\Network\Request | ||
*/ | ||
protected $_request; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param \Cake\Network\Request $request The request object. | ||
* @param array $context Context info. | ||
*/ | ||
public function __construct(Request $request, array $context) { | ||
$this->_request = $request; | ||
$context += [ | ||
'entity' => null, | ||
]; | ||
$this->_form = $context['entity']; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function primaryKey() { | ||
return []; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function isPrimaryKey($field) { | ||
return false; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function isCreate() { | ||
return true; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function val($field) { | ||
return $this->_request->data($field); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function isRequired($field) { | ||
$validator = $this->_form->validator(); | ||
if (!$validator->hasField($field)) { | ||
return false; | ||
} | ||
if ($this->type($field) !== 'boolean') { | ||
return $validator->isEmptyAllowed($field, true) === false; | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function fieldNames() { | ||
$schema = $this->_form->schema(); | ||
return $schema->fields(); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function type($field) { | ||
$schema = $this->_form->schema(); | ||
return $schema->fieldType($field); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function attributes($field) { | ||
$column = (array)$this->_form->schema()->field($field); | ||
$whitelist = ['length' => null, 'precision' => null]; | ||
return array_intersect_key($column, $whitelist); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function hasError($field) { | ||
$errors = $this->error($field); | ||
return count($errors) > 0; | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
public function error($field) { | ||
$errors = $this->_form->errors(); | ||
if (isset($errors[$field])) { | ||
return array_values($errors[$field]); | ||
} | ||
return []; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
<?php | ||
/** | ||
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | ||
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* | ||
* Licensed under The MIT License | ||
* For full copyright and license information, please see the LICENSE.txt | ||
* Redistributions of files must retain the above copyright notice. | ||
* | ||
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) | ||
* @link http://cakephp.org CakePHP(tm) Project | ||
* @since 3.0.0 | ||
* @license http://www.opensource.org/licenses/mit-license.php MIT License | ||
*/ | ||
namespace Cake\Test\TestCase\View\Form; | ||
|
||
use Cake\Form\Form; | ||
use Cake\Network\Request; | ||
use Cake\TestSuite\TestCase; | ||
use Cake\View\Form\FormContext; | ||
|
||
/** | ||
* Form context test case. | ||
*/ | ||
class FormContextTest extends TestCase { | ||
|
||
/** | ||
* setup method. | ||
* | ||
* @return void | ||
*/ | ||
public function setUp() { | ||
parent::setUp(); | ||
$this->request = new Request(); | ||
} | ||
|
||
/** | ||
* Test getting the primary key. | ||
* | ||
* @return void | ||
*/ | ||
public function testPrimaryKey() { | ||
$context = new FormContext($this->request, ['entity' => new Form()]); | ||
$this->assertEquals([], $context->primaryKey()); | ||
} | ||
|
||
/** | ||
* Test isPrimaryKey. | ||
* | ||
* @return void | ||
*/ | ||
public function testIsPrimaryKey() { | ||
$context = new FormContext($this->request, ['entity' => new Form()]); | ||
$this->assertFalse($context->isPrimaryKey('id')); | ||
} | ||
|
||
/** | ||
* Test the isCreate method. | ||
* | ||
* @return void | ||
*/ | ||
public function testIsCreate() { | ||
$context = new FormContext($this->request, ['entity' => new Form()]); | ||
$this->assertTrue($context->isCreate()); | ||
} | ||
|
||
/** | ||
* Test reading values from the request & defaults. | ||
*/ | ||
public function testValPresent() { | ||
$this->request->data = [ | ||
'Articles' => [ | ||
'title' => 'New title', | ||
'body' => 'My copy', | ||
] | ||
]; | ||
$context = new FormContext($this->request, ['entity' => new Form()]); | ||
$this->assertEquals('New title', $context->val('Articles.title')); | ||
$this->assertEquals('My copy', $context->val('Articles.body')); | ||
$this->assertNull($context->val('Articles.nope')); | ||
} | ||
|
||
/** | ||
* Test getting values when the request and defaults are missing. | ||
* | ||
* @return void | ||
*/ | ||
public function testValMissing() { | ||
$context = new FormContext($this->request, ['entity' => new Form()]); | ||
$this->assertNull($context->val('Comments.field')); | ||
} | ||
|
||
/** | ||
* Test isRequired | ||
* | ||
* @return void | ||
*/ | ||
public function testIsRequired() { | ||
$form = new Form(); | ||
$form->validator() | ||
->requirePresence('name') | ||
->add('email', 'format', ['rule' => 'email']); | ||
|
||
$context = new FormContext($this->request, [ | ||
'entity' => $form | ||
]); | ||
$this->assertTrue($context->isRequired('name')); | ||
$this->assertTrue($context->isRequired('email')); | ||
$this->assertFalse($context->isRequired('body')); | ||
$this->assertFalse($context->isRequired('Prefix.body')); | ||
} | ||
|
||
/** | ||
* Test the type method. | ||
* | ||
* @return void | ||
*/ | ||
public function testType() { | ||
$form = new Form(); | ||
$form->schema() | ||
->addField('email', 'string') | ||
->addField('user_id', 'integer'); | ||
|
||
$context = new FormContext($this->request, [ | ||
'entity' => $form | ||
]); | ||
$this->assertNull($context->type('undefined')); | ||
$this->assertEquals('integer', $context->type('user_id')); | ||
$this->assertEquals('string', $context->type('email')); | ||
$this->assertNull($context->type('Prefix.email')); | ||
} | ||
|
||
/** | ||
* Test fetching attributes. | ||
* | ||
* @return void | ||
*/ | ||
public function testAttributes() { | ||
$form = new Form(); | ||
$form->schema() | ||
->addField('email', [ | ||
'type' => 'string', | ||
'length' => 10, | ||
]) | ||
->addField('amount', [ | ||
'type' => 'decimal', | ||
'length' => 5, | ||
'precision' => 2, | ||
]); | ||
$context = new FormContext($this->request, [ | ||
'entity' => $form | ||
]); | ||
$this->assertEquals([], $context->attributes('id')); | ||
$this->assertEquals(['length' => 10, 'precision' => null], $context->attributes('email')); | ||
$this->assertEquals(['precision' => 2, 'length' => 5], $context->attributes('amount')); | ||
} | ||
|
||
/** | ||
* Test fetching errors. | ||
* | ||
* @return void | ||
*/ | ||
public function testError() { | ||
$form = new Form(); | ||
$form->validator() | ||
->add('email', 'format', ['rule' => 'email']) | ||
->add('name', 'length', ['rule' => ['minLength', 10]]); | ||
$form->validate([ | ||
'email' => 'derp', | ||
'name' => 'derp' | ||
]); | ||
|
||
$context = new FormContext($this->request, ['entity' => $form]); | ||
$this->assertEquals([], $context->error('empty')); | ||
$this->assertEquals(['The provided value is invalid'], $context->error('email')); | ||
$this->assertEquals(['The provided value is invalid'], $context->error('name')); | ||
|
||
$this->assertEquals([], $context->error('Alias.name')); | ||
$this->assertEquals([], $context->error('nope.nope')); | ||
} | ||
|
||
/** | ||
* Test checking errors. | ||
* | ||
* @return void | ||
*/ | ||
public function testHasError() { | ||
$form = new Form(); | ||
$form->validator() | ||
->add('email', 'format', ['rule' => 'email']) | ||
->add('name', 'length', ['rule' => ['minLength', 10]]); | ||
$form->validate([ | ||
'email' => 'derp', | ||
'name' => 'derp' | ||
]); | ||
|
||
$context = new FormContext($this->request, ['entity' => $form]); | ||
$this->assertTrue($context->hasError('email')); | ||
$this->assertTrue($context->hasError('name')); | ||
$this->assertFalse($context->hasError('nope')); | ||
$this->assertFalse($context->hasError('nope.nope')); | ||
} | ||
|
||
} |