mirror of
https://github.com/e107inc/e107.git
synced 2025-08-04 13:47:31 +02:00
Fix for multi-dimensional field saving.
This commit is contained in:
@@ -709,6 +709,54 @@ class e_parse
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a multi-dimensional array and converts the keys to a list of routing paths.
|
||||||
|
* paths are the key and value are the top most key.
|
||||||
|
* @param array $array
|
||||||
|
* @return false|array
|
||||||
|
*/
|
||||||
|
public function toRoute($array)
|
||||||
|
{
|
||||||
|
$res = $this->_processRoute($array);
|
||||||
|
$tmp = explode("_#_", $res);
|
||||||
|
$ret = [];
|
||||||
|
foreach($tmp as $v)
|
||||||
|
{
|
||||||
|
list($k) = explode('/',$v);
|
||||||
|
$ret[$v] = $k;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _processRoute($array, $prefix='')
|
||||||
|
{
|
||||||
|
$text = [];
|
||||||
|
|
||||||
|
if(is_array($array))
|
||||||
|
{
|
||||||
|
foreach($array as $key=>$val)
|
||||||
|
{
|
||||||
|
if($tag = $this->_processRoute($val, $key.'/'))
|
||||||
|
{
|
||||||
|
$add = $tag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$add = $key;
|
||||||
|
}
|
||||||
|
|
||||||
|
$text[] = $prefix.$add;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('_#_',$text);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function toForm($text)
|
public function toForm($text)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@@ -2718,81 +2718,65 @@ class e_front_model extends e_model
|
|||||||
|
|
||||||
if(is_array($key))
|
if(is_array($key))
|
||||||
{
|
{
|
||||||
$ret = array();
|
$ret = [];
|
||||||
foreach ($key as $k=>$v)
|
|
||||||
|
foreach($this->_data_fields as $fld => $type)
|
||||||
{
|
{
|
||||||
if($this->isValidFieldKey($k))
|
list($field) = explode("/", $fld); // ie the field being posted as an array.
|
||||||
{
|
|
||||||
$ret[$k] = $this->sanitize($k, $v);
|
if(!isset($key[$field]))
|
||||||
// $ret[$k] = is_array($v) ? $this->sanitize($v) : $this->sanitize($k, $v);
|
{
|
||||||
}
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(strpos($fld, '/') !== false) // multi-dimensional array field key name.
|
||||||
|
{
|
||||||
|
$md = explode('/', $fld); // split the field name
|
||||||
|
$value = $key[$field];
|
||||||
|
foreach($md as $f) // loop through the path (depth/of/array) to check $value[x][y][z] etc.
|
||||||
|
{
|
||||||
|
if(isset($value[$f]))
|
||||||
|
{
|
||||||
|
if(is_array($value[$f]))
|
||||||
|
{
|
||||||
|
$value = $value[$f];
|
||||||
|
}
|
||||||
|
else // the actual field being saved. .
|
||||||
|
{
|
||||||
|
// FIXME add the sanitized value into the end of the array.
|
||||||
|
$sanitized = $this->sanitizeValue($type, $value[$f], $fld);
|
||||||
|
$ret[$field] = $key[$field];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else // regular field.
|
||||||
|
{
|
||||||
|
$ret[$field] = $this->sanitize($field, $key[$field]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$type = $this->isValidFieldKey($key))
|
|
||||||
|
if(!isset($this->_data_fields[$key]))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
$type = $this->_data_fields[$key];
|
||||||
// $type = $this->_data_fields[$key];
|
|
||||||
if(null === $value)
|
if(null === $value)
|
||||||
{
|
{
|
||||||
$value = $this->getPostedData($key);
|
$value = $this->getPostedData($key);
|
||||||
}
|
}
|
||||||
|
|
||||||
$ret = null; // default
|
|
||||||
|
|
||||||
switch ($type)
|
return $this->sanitizeValue($type, $value, $key);
|
||||||
{
|
|
||||||
case 'int':
|
|
||||||
case 'integer':
|
|
||||||
//return intval($this->toNumber($value));
|
|
||||||
$ret = (int) $tp->toNumber($value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'safestr':
|
|
||||||
$ret = $tp->filter($value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'str':
|
|
||||||
case 'string':
|
|
||||||
case 'array':
|
|
||||||
$type = $this->getFieldInputType($key);
|
|
||||||
$ret = $tp->toDB($value, false, false, 'model', array('type'=>$type, 'field'=>$key));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'json':
|
|
||||||
if(!empty($value))
|
|
||||||
{
|
|
||||||
$ret = e107::serialize($value,'json');
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'code':
|
|
||||||
$ret = $tp->toDB($value, false, false, 'pReFs');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'float':
|
|
||||||
// return $this->toNumber($value);
|
|
||||||
$ret = $tp->toNumber($value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'bool':
|
|
||||||
case 'boolean':
|
|
||||||
$ret = ($value ? true : false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'model':
|
|
||||||
$ret = $value->mergePostedData(false, true, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'null':
|
|
||||||
$ret = ($value ? $tp->toDB($value) : null);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -2963,6 +2947,70 @@ class e_front_model extends e_model
|
|||||||
|
|
||||||
var_dump($ret);
|
var_dump($ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $type
|
||||||
|
* @param $value
|
||||||
|
* @param $key
|
||||||
|
* @return array|bool|float|int|mixed|string|null
|
||||||
|
*/
|
||||||
|
private function sanitizeValue($type, $value, $key)
|
||||||
|
{
|
||||||
|
|
||||||
|
$ret = null; // default
|
||||||
|
$tp = e107::getParser();
|
||||||
|
|
||||||
|
switch($type)
|
||||||
|
{
|
||||||
|
case 'int':
|
||||||
|
case 'integer':
|
||||||
|
//return intval($this->toNumber($value));
|
||||||
|
$ret = (int) $tp->toNumber($value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'safestr':
|
||||||
|
$ret = $tp->filter($value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'str':
|
||||||
|
case 'string':
|
||||||
|
case 'array':
|
||||||
|
$type = $this->getFieldInputType($key);
|
||||||
|
$ret = $tp->toDB($value, false, false, 'model', array('type' => $type, 'field' => $key));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'json':
|
||||||
|
if(!empty($value))
|
||||||
|
{
|
||||||
|
$ret = e107::serialize($value, 'json');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'code':
|
||||||
|
$ret = $tp->toDB($value, false, false, 'pReFs');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'float':
|
||||||
|
// return $this->toNumber($value);
|
||||||
|
$ret = $tp->toNumber($value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'bool':
|
||||||
|
case 'boolean':
|
||||||
|
$ret = ($value ? true : false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'model':
|
||||||
|
$ret = $value->mergePostedData(false, true, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'null':
|
||||||
|
$ret = ($value ? $tp->toDB($value) : null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME - move e_model_admin to e_model_admin.php
|
//FIXME - move e_model_admin to e_model_admin.php
|
||||||
|
@@ -26,11 +26,14 @@
|
|||||||
'myfield' => 'str',
|
'myfield' => 'str',
|
||||||
'myfield2' => 'int',
|
'myfield2' => 'int',
|
||||||
'myfield3' => 'str',
|
'myfield3' => 'str',
|
||||||
'other/active' => 'bool',
|
'myfield4' => 'json',
|
||||||
'other/bla/active' => 'array',
|
'myfield5' => 'array',
|
||||||
|
'myfield6' => 'str',
|
||||||
'gateways/other' => 'str',
|
'gateways/other' => 'str',
|
||||||
'gateways/paypal/active' => 'int',
|
'gateways/paypal/active' => 'int',
|
||||||
'gateways/paypal/title' => 'str',
|
'gateways/paypal/title' => 'str',
|
||||||
|
'other/active' => 'bool',
|
||||||
|
'other/bla/active' => 'array',
|
||||||
'another/one/active' => 'bool',
|
'another/one/active' => 'bool',
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -38,6 +41,8 @@
|
|||||||
$this->model->setDataFields($this->dataFields);
|
$this->model->setDataFields($this->dataFields);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
public function testIsValidFieldKey()
|
public function testIsValidFieldKey()
|
||||||
{
|
{
|
||||||
@@ -58,7 +63,7 @@
|
|||||||
*/
|
*/
|
||||||
public function testSanitize()
|
public function testSanitize()
|
||||||
{
|
{
|
||||||
|
// test simple text field.
|
||||||
$result = $this->model->sanitize('myfield', 'My Field Value');
|
$result = $this->model->sanitize('myfield', 'My Field Value');
|
||||||
$this->assertSame('My Field Value', $result);
|
$this->assertSame('My Field Value', $result);
|
||||||
|
|
||||||
@@ -66,9 +71,38 @@
|
|||||||
$result = $this->model->sanitize(array('myfield' => 'My Field Value'));
|
$result = $this->model->sanitize(array('myfield' => 'My Field Value'));
|
||||||
$this->assertSame(array( 'myfield' => 'My Field Value' ), $result);
|
$this->assertSame(array( 'myfield' => 'My Field Value' ), $result);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// test posting of array and conversion to json.
|
||||||
|
$posted = array('myfield4' => array('level1' => array('level2' => 'level2 value')) );
|
||||||
|
$expected = array (
|
||||||
|
'myfield4' => '{
|
||||||
|
"level1": {
|
||||||
|
"level2": "level2 value"
|
||||||
|
}
|
||||||
|
}',
|
||||||
|
);
|
||||||
|
$result = $this->model->sanitize($posted);
|
||||||
|
|
||||||
|
$this->assertSame($expected, $result);
|
||||||
|
|
||||||
|
// test posting of array returned as array.
|
||||||
|
$posted = array('myfield5' => array('level1' => array('level2' => 'level2 value')) );
|
||||||
|
$result = $this->model->sanitize($posted);
|
||||||
|
$this->assertSame($posted, $result);
|
||||||
|
|
||||||
|
|
||||||
|
// test posting of array returned as array.
|
||||||
|
$posted = array('myfield6' => array('opt1', 'opt2', 'opt3'));
|
||||||
|
$result = $this->model->sanitize($posted);
|
||||||
|
$this->assertSame($posted, $result);
|
||||||
|
|
||||||
|
|
||||||
|
// test undefined field.
|
||||||
$result = $this->model->sanitize('non_field', 1);
|
$result = $this->model->sanitize('non_field', 1);
|
||||||
$this->assertNull($result);
|
$this->assertNull($result);
|
||||||
|
|
||||||
|
// test multi-dimensional field.
|
||||||
$result = $this->model->sanitize('gateways/paypal/active', 1);
|
$result = $this->model->sanitize('gateways/paypal/active', 1);
|
||||||
$this->assertSame(1, $result);
|
$this->assertSame(1, $result);
|
||||||
|
|
||||||
@@ -77,13 +111,13 @@
|
|||||||
array (
|
array (
|
||||||
'paypal' =>
|
'paypal' =>
|
||||||
array (
|
array (
|
||||||
'active' => '0',
|
|
||||||
'title' => 'PayPal Express' ,
|
'title' => 'PayPal Express' ,
|
||||||
'icon' => 'fa-paypal',
|
'icon' => 'fa-paypal',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Real example from vstore prefs. key becomes multi-dimensional array when posted.
|
// Real example from vstore prefs. key becomes multi-dimensional array when posted.
|
||||||
$posted = array(
|
$posted = array(
|
||||||
'myfield' => 'my string',
|
'myfield' => 'my string',
|
||||||
@@ -96,7 +130,7 @@
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
'other' => array(
|
'other' => array(
|
||||||
'active' => 1,
|
'active' => 5,
|
||||||
|
|
||||||
),
|
),
|
||||||
'another' => array(
|
'another' => array(
|
||||||
@@ -112,6 +146,7 @@
|
|||||||
array (
|
array (
|
||||||
'active' => 1, // converted to int.
|
'active' => 1, // converted to int.
|
||||||
'title' => 'PayPal Express',
|
'title' => 'PayPal Express',
|
||||||
|
// icon removed - as not valid.
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'other' =>
|
'other' =>
|
||||||
@@ -127,7 +162,7 @@
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// @todo FIXME - doesn't pass. More accurate check required.
|
// @todo FIXME - doesn't pass. More accurate check has been made, but not injected into the array yet.
|
||||||
$result = $this->model->sanitize($posted);
|
$result = $this->model->sanitize($posted);
|
||||||
// $this->assertSame($expected, $result);
|
// $this->assertSame($expected, $result);
|
||||||
|
|
||||||
@@ -136,7 +171,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testSanitizeCustomFields()
|
public function testCustomFieldsSantizie()
|
||||||
{
|
{
|
||||||
$dataFields = array ( 'chapter_id' => 'int', 'chapter_icon' => 'str', 'chapter_parent' => 'str', 'chapter_name' => 'str', 'chapter_template' => 'str', 'chapter_meta_description' => 'str', 'chapter_meta_keywords' => 'str', 'chapter_sef' => 'str', 'chapter_manager' => 'int', 'chapter_order' => 'str', 'chapter_visibility' => 'int', 'chapter_fields' => 'json', 'chapter_image' => 'str', );
|
$dataFields = array ( 'chapter_id' => 'int', 'chapter_icon' => 'str', 'chapter_parent' => 'str', 'chapter_name' => 'str', 'chapter_template' => 'str', 'chapter_meta_description' => 'str', 'chapter_meta_keywords' => 'str', 'chapter_sef' => 'str', 'chapter_manager' => 'int', 'chapter_order' => 'str', 'chapter_visibility' => 'int', 'chapter_fields' => 'json', 'chapter_image' => 'str', );
|
||||||
$this->model->setDataFields($dataFields);
|
$this->model->setDataFields($dataFields);
|
||||||
@@ -153,7 +188,6 @@
|
|||||||
'chapter_manager' => 254,
|
'chapter_manager' => 254,
|
||||||
'chapter_order' => '0',
|
'chapter_order' => '0',
|
||||||
'chapter_visibility' => 0,
|
'chapter_visibility' => 0,
|
||||||
'chapter_image' => '',
|
|
||||||
'chapter_fields' => '{
|
'chapter_fields' => '{
|
||||||
"__tabs__": {
|
"__tabs__": {
|
||||||
"additional": "Custom Fields 10"
|
"additional": "Custom Fields 10"
|
||||||
@@ -261,6 +295,7 @@
|
|||||||
"help": ""
|
"help": ""
|
||||||
}
|
}
|
||||||
}',
|
}',
|
||||||
|
'chapter_image' => '',
|
||||||
);
|
);
|
||||||
$result = $this->model->sanitize($posted);
|
$result = $this->model->sanitize($posted);
|
||||||
$this->assertSame($expected, $result);
|
$this->assertSame($expected, $result);
|
||||||
|
@@ -33,6 +33,38 @@
|
|||||||
$this->tp->init();
|
$this->tp->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testToRoute()
|
||||||
|
{
|
||||||
|
|
||||||
|
$posted = array(
|
||||||
|
'myfield' => array(
|
||||||
|
'computer' => array(
|
||||||
|
'apple' => array('imac' => '1')
|
||||||
|
),
|
||||||
|
'os' => array(
|
||||||
|
'microsoft' => array('windows' => 'xp')
|
||||||
|
)
|
||||||
|
),
|
||||||
|
'myfield2' => array(
|
||||||
|
'house' => array('car' => 'red')
|
||||||
|
),
|
||||||
|
'myfield3' => 'string',
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
$expected = array (
|
||||||
|
'myfield/computer/apple/imac' => 'myfield',
|
||||||
|
'myfield/os/microsoft/windows' => 'myfield',
|
||||||
|
'myfield2/house/car' => 'myfield2',
|
||||||
|
'myfield3' => 'myfield3',
|
||||||
|
);
|
||||||
|
|
||||||
|
$result = $this->tp->toRoute($posted);
|
||||||
|
$this->assertSame($expected, $result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function testStripBlockTags()
|
public function testStripBlockTags()
|
||||||
{
|
{
|
||||||
$tests = array(
|
$tests = array(
|
||||||
|
Reference in New Issue
Block a user