Skip to content

Commit

Permalink
Add primaryKey() to context classes.
Browse files Browse the repository at this point in the history
Add a primaryKey method to the context classes. This will let FormHelper
get primaryKey data so that create/update forms can be detected properly
for a given bag of data.
  • Loading branch information
markstory committed Feb 10, 2014
1 parent 5847081 commit 5c357aa
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 11 deletions.
56 changes: 51 additions & 5 deletions src/View/Form/ArrayContext.php
Expand Up @@ -33,11 +33,28 @@
* - `schema` An array of data that emulate the column structures that
* Cake\Database\Schema\Table uses. This array allows you to control
* the inferred type for fields and allows auto generation of attributes
* like maxlength, step and other HTML attributes.
* like maxlength, step and other HTML attributes. If you want
* primary key/id detection to work. Make sure you have provided a `_constraints`
* array that contains `primary`. See below for an exmaple.
* - `errors` An array of validation errors. Errors should be nested following
* the dot separated paths you access your fields with.
* - `isCreate` A boolean that indicates whether or not this form should
* be treated as a create operation. If false this form will be an update.
*
* ### Example
*
* {{{
* $data = [
* 'schema' => [
* 'id' => ['type' => 'integer'],
* 'title' => ['type' => 'string', 'length' => 255],
* '_constraints' => [
* 'primary' => ['type' => 'primary', 'columns' => ['id']]
* ]
* ],
* 'defaults' => [
* 'id' => 1,
* 'title' => 'First post!',
* ]
* ];
*/
class ArrayContext {

Expand Down Expand Up @@ -68,18 +85,47 @@ public function __construct(Request $request, array $context) {
'required' => [],
'defaults' => [],
'errors' => [],
'create' => true,
];
$this->_context = $context;
}

/**
* Get the fields used in the context as a primary key.
*
* @return array
*/
public function primaryKey() {
if (
empty($this->_context['schema']['_constraints']) ||
!is_array($this->_context['schema']['_constraints'])
) {
return [];
}
foreach ($this->_context['schema']['_constraints'] as $data) {
if (isset($data['type']) && $data['type'] === 'primary') {
return isset($data['columns']) ? (array)$data['columns'] : [];
}
}
return [];
}

/**
* Returns whether or not this form is for a create operation.
*
* For this method to return true, both the primary key constraint
* must be defined in the 'schema' data, and the 'defaults' data must
* contain a value for all fields in the key.
*
* @return boolean
*/
public function isCreate() {
return (bool)$this->_context['create'];
$primary = $this->primaryKey();
foreach ($primary as $column) {
if (!isset($this->_context['defaults'][$column])) {
return false;
}
}
return true;
}

/**
Expand Down
13 changes: 13 additions & 0 deletions src/View/Form/EntityContext.php
Expand Up @@ -129,6 +129,19 @@ protected function _prepare() {
$this->_tables[$alias] = $table;
}

/**
* Get the primary key data for the context.
*
* Gets the primary key columns from the root entity's schema.
*
* @return boolean
*/
public function primaryKey() {
$table = $this->_tables[$this->_rootName];
$schema = $table->schema();
return $schema->primaryKey();
}

/**
* Check whether or not this form is a create or update.
*
Expand Down
9 changes: 9 additions & 0 deletions src/View/Form/NullContext.php
Expand Up @@ -41,6 +41,15 @@ public function __construct(Request $request, array $context) {
$this->_request = $request;
}

/**
* Get the fields used in the context as a primary key.
*
* @return array
*/
public function primaryKey() {
return [];
}

/**
* Returns whether or not this form is for a create operation.
*
Expand Down
45 changes: 39 additions & 6 deletions tests/TestCase/View/Form/ArrayContextTest.php
Expand Up @@ -33,6 +33,35 @@ public function setUp() {
$this->request = new Request();
}

/**
* Test getting the primary key.
*
* @return void
*/
public function testPrimaryKey() {
$context = new ArrayContext($this->request, []);
$this->assertEquals([], $context->primaryKey());

$context = new ArrayContext($this->request, [
'schema' => [
'_constraints' => 'mistake',
]
]);
$this->assertEquals([], $context->primaryKey());

$data = [
'schema' => [
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['id']]
]
],
];
$context = new ArrayContext($this->request, $data);

$expected = ['id'];
$this->assertEquals($expected, $context->primaryKey());
}

/**
* Test the isCreate method.
*
Expand All @@ -42,14 +71,18 @@ public function testIsCreate() {
$context = new ArrayContext($this->request, []);
$this->assertTrue($context->isCreate());

$context = new ArrayContext($this->request, [
'create' => false,
]);
$data = [
'schema' => [
'_constraints' => [
'primary' => ['type' => 'primary', 'columns' => ['id']]
]
],
];
$context = new ArrayContext($this->request, $data);
$this->assertFalse($context->isCreate());

$context = new ArrayContext($this->request, [
'create' => true,
]);
$data['defaults'] = ['id' => 2];
$context = new ArrayContext($this->request, $data);
$this->assertTrue($context->isCreate());
}

Expand Down
13 changes: 13 additions & 0 deletions tests/TestCase/View/Form/EntityContextTest.php
Expand Up @@ -53,6 +53,19 @@ public function setUp() {
$this->request = new Request();
}

/**
* Test getting primary key data.
*
* @return void
*/
public function testPrimaryKey() {
$row = new Article();
$context = new EntityContext($this->request, [
'entity' => $row,
]);
$this->assertEquals(['id'], $context->primaryKey());
}

/**
* Test isCreate on a single entity.
*
Expand Down

0 comments on commit 5c357aa

Please sign in to comment.