Skip to content

Commit

Permalink
Nested fields with url_handlers (eg UploadField) now work in DataList…
Browse files Browse the repository at this point in the history
…Field
  • Loading branch information
Zauberfisch committed Sep 21, 2017
1 parent 7984c22 commit 3ffc742
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 4 deletions.
9 changes: 9 additions & 0 deletions _config/extensions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
Name: silverstripe-serialized-dataobject-extensions
After: 'framework/*','cms/*'
---
Form:
extensions:
- 'zauberfisch\SerializedDataObject\Form\FormExtension'
url_handlers:
'field/$FieldName!': 'handleFieldArrayList'
4 changes: 2 additions & 2 deletions javascript/ArrayListField.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
recordList = field.getRecordList(),
_this = this,
newIndex = recordList.find('.record').length,
url = field.data('add-record-url') + '?index=' + newIndex;
url = field.data('add-record-url');
this.addClass('loading');
this.getRootForm().addClass('changed');
$.get(url, function (content) {
$.get(url, {'index': newIndex}, function (content) {
recordList.append(content);
_this.removeClass('loading');
_this.blur();
Expand Down
39 changes: 37 additions & 2 deletions src/Form/ArrayListField.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

class ArrayListField extends FormField {
protected $recordFieldsCallback;
protected $recordFieldsUpdateCallback;
protected $recordClassName;
protected $orderable = false;

Expand Down Expand Up @@ -147,6 +148,10 @@ protected function getRecordFields($index, AbstractDataObject $record = null) {
->addExtraClass('controls')
);
$this->prefixRecordFields($index, $recordFields);
$callback = $this->getRecordFieldsUpdateCallback();
if ($callback) {
$recordFields = call_user_func($callback, $recordFields, $this, $record);
}
return (new \CompositeField($recordFields))->addExtraClass('record');
}

Expand Down Expand Up @@ -244,6 +249,20 @@ public function getPrefixedRecordFieldName($index, $fieldName) {
return sprintf('%s[%s][%s]', $this->getName(), $index, $fieldName);
}

public function handleSubField($fullFieldName) {
$str = substr($fullFieldName, strlen($this->getName()));
if (preg_match('/^\[(\d*)\]/', $str, $matches)) {
$fields = $this->getRecordFields($matches[1]);
$subField = $fields->FieldList()->dataFieldByName($fullFieldName);
if (!$subField) {
$subField = $fields->FieldList()->fieldByName($fullFieldName);
}
$subField->setForm($this->getForm());
return $subField;
}
return null;
}

/**
* @param \DataObjectInterface $record
*/
Expand Down Expand Up @@ -285,7 +304,7 @@ public function setForm($form) {
}

/**
* @param mixed $recordFieldsCallback
* @param callable $recordFieldsCallback
* @return ArrayListField
*/
public function setRecordFieldsCallback($recordFieldsCallback) {
Expand All @@ -294,7 +313,7 @@ public function setRecordFieldsCallback($recordFieldsCallback) {
}

/**
* @return mixed
* @return callable
*/
public function getRecordFieldsCallback() {
$callback = $this->recordFieldsCallback;
Expand All @@ -314,4 +333,20 @@ public function getRecordFieldsCallback() {
}
return $callback;
}

/**
* @param callable $recordFieldsUpdateCallback
* @return ArrayListField
*/
public function setRecordFieldsUpdateCallback($recordFieldsUpdateCallback) {
$this->recordFieldsUpdateCallback = $recordFieldsUpdateCallback;
return $this;
}

/**
* @return callable|null
*/
public function getRecordFieldsUpdateCallback() {
return $this->recordFieldsUpdateCallback;
}
}
34 changes: 34 additions & 0 deletions src/Form/FormExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace zauberfisch\SerializedDataObject\Form;

class FormExtension extends \Extension {
private static $allowed_actions = [
'handleFieldArrayList',
];
// private static $url_handlers = [
// 'field/$FieldName!' => 'handleFieldArrayList',
// ];


/**
* @param \SS_HTTPRequest $request
* @return \FormField
*/
public function handleFieldArrayList($request) {
$field = $this->owner->handleField($request);
if (!$field) {
$fieldName = $request->param('FieldName');
foreach($this->owner->Fields()->dataFields() as $dataField) {
/** @var \FormField|ArrayListField $dataField */
if ($dataField->is_a(ArrayListField::class)) {
if (strpos($fieldName, $dataField->getName()) == 0) {
$field = $dataField->handleSubField($fieldName);
break;
}
}
}
}
return $field;
}
}
58 changes: 58 additions & 0 deletions src/Form/ProxyArrayListField.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace zauberfisch\SerializedDataObject\Form;

use zauberfisch\NamespaceTemplates\Form\CompositeField;

class ProxyArrayListField extends CompositeField {
public function __construct($name, $title = null, $recordClassName) {
$_this = $this;
parent::__construct([
(new ArrayListField($name, $title, $recordClassName))
->setRecordFieldsUpdateCallback(function ($fields, $listField, $record = null) use ($_this) {
foreach($fields as $field) {
$_this->push(new ProxyArrayListField_FieldProxy($field));
}
return $fields;
}),
]);
$this->setName("{$name}_proxy_holder");
}


}

class ProxyArrayListField_FieldProxy extends \DatalessField {
private static $allowed_actions = [
'handleField',
];
private static $url_handlers = [
'' => 'handleField',
];
protected $originalField;

/**
* @param \FormField $originalField
*/
public function __construct($originalField) {
$this->originalField = $originalField;
parent::__construct($originalField->getName());
}


public function handleField(\SS_HTTPRequest $request) {
return $this->originalField;
}

public function Field($properties = []) {
return '';
}

public function FieldHolder($properties = []) {
return '';
}

public function SmallFieldHolder($properties = []) {
return '';
}
}
42 changes: 42 additions & 0 deletions src/Form/UploadField.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace zauberfisch\SerializedDataObject\Form;

use SS_HTTPRequest;
use zauberfisch\SerializedDataObject\DataList;
use zauberfisch\SerializedDataObject\DBField\DataListField;

Expand Down Expand Up @@ -46,4 +47,45 @@ public function setValue($value, $record = null) {
}
return parent::setValue($value, $record);
}

private static $allowed_actions = [
'upload',
];

public function upload(SS_HTTPRequest $request) {
$fieldName = $this->getName();
$baseStrLength = strpos($fieldName, '[');
if ($baseStrLength) {
$postVars = $request->postVars();
$baseName = substr($fieldName, 0, $baseStrLength);
if (isset($postVars[$baseName])) {
$postVars[$fieldName] = $this->flattenFilesArray($postVars[$baseName]);
$request = new SS_HTTPRequest(
$request->httpMethod(),
$request->getURL(),
$request->getVars(),
$postVars
);
}
}
$return = parent::upload($request);
return $return;
}

protected function flattenFilesArray($array) {
$fieldName = $this->getName();
$keys = substr($fieldName, strpos($fieldName, '['));
$keys = trim($keys, '[');
$keys = trim($keys, ']');
$keys = explode('][', $keys);
$return = [];
foreach (['name', 'type', 'tmp_name', 'error', 'size'] as $field) {
$data = $array[$field];
foreach ($keys as $key) {
$data = $data[$key];
}
$return[$field] = $data;
}
return $return;
}
}

0 comments on commit 3ffc742

Please sign in to comment.