Skip to content

Commit

Permalink
NEW: Allow CMS feld-data to be converted to JSON and stored to a spec…
Browse files Browse the repository at this point in the history
…ific DB field.
  • Loading branch information
phptek committed Sep 24, 2016
1 parent 39204a9 commit 32cc9c8
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ JSON storage, querying and modification.
* Query JSON data via simple accessors, Postgres-like operators or [JSONPath](http://goessner.net/articles/JsonPath/) expressions.
* Selectively return results of queries as JSON, Array or cast to SilverStripe `Varchar`, `Int`, `Float` or `Boolean` objects.
* Selectively update portions of your source JSON, using [JSONPath](http://goessner.net/articles/JsonPath/) expressions.
* Selectively convert selected CMS input field-data, into JSON and write to specific field(s) on your models.

## Introduction

Expand Down
55 changes: 55 additions & 0 deletions code/extensions/JSONTextExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

/**
* Add this DataExtension to your models if you wish to have specific DB fields
* receive JSON data POSTed from particular input fields in the CMS.
*
* You'll need to declare declare a `$jsontext_field_map` config static on the desired
* model(s) as follows:
*
* <code>
* private static $jsontext_field_map = [
* 'MyDBField1' => [
* 'MyInputField1',
* 'MyInputField2'
* ],
* 'MyDBField2' => [
* 'MyInputField3',
'MyInputField4'
* ]
* ];
* <code>
*
* @package silverstripe-jsontext
* @subpackage extensions
* @author Russell Michell <[email protected]>
*/

class JSONTextExtension extends \DataExtension
{
/**
* Manipulate POSTed data from pre-specified CMS fields and write their data
* as JSON.
*
* @return void
*/
public function onBeforeWrite()
{
// Fields are declared in a config static on decorated models
$fieldMap = $this->getOwner()->config()->get('jsontext_field_map');
$postVars = Controller::curr()->getRequest()->postVars();
$data = [];

foreach ($fieldMap as $dbFieldName => $inputFields) {
foreach ($inputFields as $inputField) {
$data[$dbFieldName][] = [$inputField => $postVars[$inputField]];
}

$jsonTextField = $this->getOwner()->dbObject($dbFieldName);
$this->getOwner()->setField($dbFieldName, $jsonTextField->toJSON($data[$dbFieldName]));
}

parent::onBeforeWrite();
}

}
2 changes: 1 addition & 1 deletion docs/en/jsonpath.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# JSONPath

All the informatation on JSONPath you can eat [can be found here](http://goessner.net/articles/JsonPath/).
All the information on JSONPath you can eat [can be found here](http://goessner.net/articles/JsonPath/).

## Quick Reference

Expand Down
44 changes: 43 additions & 1 deletion docs/en/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ expression.
If the expression matches >1 JSON nodes, then that result is expressed as an indexed array, and each matching
node will be modified with the data passed to `setValue()` as the standard `$value` (first) param.

Example:

```
class MyDataObject extends DataObject
{
Expand Down Expand Up @@ -237,7 +239,7 @@ node will be modified with the data passed to `setValue()` as the standard `$val
parent::requireDefaultRecords();
if (!$this->MyJSON) {
$this->setField($this->MyJSON, $this->stubJSON);
$this->setField('MyJSON', $this->stubJSON);
}
}
Expand All @@ -262,3 +264,43 @@ node will be modified with the data passed to `setValue()` as the standard `$val
}
```

You can also take input from standard CMS input fields, convert those fields' data into JSON
and save it to a specific DB field. You need to declare a special `$jsontext_field_map` config
static on each model who's fields you wish to behave in this way.

In the example below, `MyDBField1` will receive JSON data comprising the combined data of
`MyInputField1` and `MyInputField2` CMS input fields, but not `MyDBField2` which will be inserted into
a DB field of the same name, in the usual way.

Example:

```
class MyDataObject extends DataObject
{
private static $jsontext_field_map = [
'MyDBField1' => [
'MyInputField1',
'MyInputField2'
]
];
private static $db = [
'MyDBField1' => 'JSONText',
'MyDBField2' => 'Text'
]
public function getCMSFields()
{
$fields = parent::getCMSFields();
//
$fields->addFieldsToTab('Root.Main', FieldList::create([
TextField::create('MyInputField1', 'My Input One'),
TextField::create('MyInputField2', 'My Input Two'),
TextField::create('MyDBField2', 'My Input Three')`
]));
return $fields;
}
}
```

0 comments on commit 32cc9c8

Please sign in to comment.