Skip to content

Commit

Permalink
- Fixed non-namespaced calls to HiddenField.
Browse files Browse the repository at this point in the history
- Added JSON check to setValue() when called with JSONPath expression.
- Added tests for JSONText::isJSON()
  • Loading branch information
phptek committed Jun 28, 2016
1 parent 5cb32aa commit c1f2b60
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 9 deletions.
34 changes: 28 additions & 6 deletions code/models/fieldtypes/JSONText.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public function requireField()
*/
public function scaffoldSearchField($title = null)
{
return HiddenField::create($this->getName());
return \HiddenField::create($this->getName());
}

/**
Expand All @@ -131,7 +131,7 @@ public function scaffoldSearchField($title = null)
*/
public function scaffoldFormField($title = null)
{
return HiddenField::create($this->getName());
return \HiddenField::create($this->getName());
}

/**
Expand Down Expand Up @@ -192,12 +192,30 @@ public function getStoreAsArray()

/**
* Utility method to determine whether the data is really JSON or not.
* The Peekmo JSONStore lib won't accept otherwise valid JSON scalars like `true`, `false` & `null` so these need
* to be disallowed.
*
* @param string $value
* @param array $allowed An optional array of allowed "invalid" JSON values
* @return boolean
*/
public function isJson($value)
public function isJson($value, array $allowed = [])
{
if (!isset($value)) {
return false;
}

$value = trim($value);

if (!empty($allowed)) {
$invalid = array_diff(['true', 'false', ''], $allowed);
if (in_array($value, $invalid)) {
return false;
}

return true;
}

return !is_null(json_decode($value, true));
}

Expand Down Expand Up @@ -421,6 +439,11 @@ private function marshallQuery($args, $type = 1)
public function setValue($value, $record = null, $expr = '')
{
if (empty($expr)) {
$allowed = ['']; // Ordinarily this would be invalid JSON, but SS allows it to clear a field
if (!$this->isJson($value, $allowed)) {
$msg = 'Invalid data passed to ' . __FUNCTION__;
throw new JSONTextException($msg);
}
$this->value = $value;
} else {
if (!$this->isValidExpression($expr)) {
Expand All @@ -435,8 +458,7 @@ public function setValue($value, $record = null, $expr = '')

$this->value = $this->jsonStore->toString();
}

// Deal with standard SS behaviour

parent::setValue($this->value, $record);

return $this;
Expand All @@ -446,7 +468,7 @@ public function setValue($value, $record = null, $expr = '')
* Determine the desired userland format to return all query API method results in.
*
* @param mixed
* @return mixed
* @return mixed array|null
* @throws \JSONText\Exceptions\JSONTextException
*/
private function returnAsType($data)
Expand Down
14 changes: 14 additions & 0 deletions tests/JSONTextSetValueTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ public function testSetValueOnSourceArray()
// Invalid #1
$this->setExpectedException('\JSONText\Exceptions\JSONTextException');
$field->setValue(99.99, null, '$[6]'); // Invalid JSON path expression

// Reset expected exception
$this->setExpectedException(null);

// Invalid #2
$this->setExpectedException('\JSONText\Exceptions\JSONTextException');
$field->setValue('true'); // Invalid JSON passed to setValue()

// Reset expected exception
$this->setExpectedException(null);

// Ensure default SS behaviour is respected
$field->setValue('');
$this->assertEquals('', $field->getValue());
}

/**
Expand Down
21 changes: 21 additions & 0 deletions tests/JSONTextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,25 @@ public function testIsExpressionValid()
$this->assertFalse($field->isValidExpression('$'));
$this->assertFalse($field->isValidExpression('$[2]'));
}

/**
* Ordinarily we can just use !is_null(json_decode($json)) but SS allows empty strings passed to setValue() so we need
* to allow otherwise invalid JSON by means of an optional 2nd param
*/
public function testIsJson()
{
$field = JSONText::create('MyJSON');

$this->assertFalse($field->isJson(''));
$this->assertTrue($field->isJson('true'));
$this->assertTrue($field->isJson('false'));
$this->assertFalse($field->isJson('null'));
$this->assertFalse($field->isJson("['one']"));
$this->assertFalse($field->isJson('["one]'));
$this->assertTrue($field->isJson('[]'));
$this->assertTrue($field->isJson('["one"]'));
$this->assertTrue($field->isJson('["one","two"]'));
$this->assertTrue($field->isJson('{"cars":{"american":["buick","oldsmobile"]}}'));
$this->assertTrue($field->isJson('', ['']));
}
}
4 changes: 1 addition & 3 deletions tests/fixtures/yml/MyAwesomeJSONModel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@ MyAwesomeJSONModel:
json-as-object:
MyJSON: '{"cars":{"american":["buick","oldsmobile"]}}'
json-as-array:
MyJSON: '["buick","oldsmobile"]'
json-as-boolean:
MyJSON: 'true'
MyJSON: '["buick","oldsmobile"]'

0 comments on commit c1f2b60

Please sign in to comment.