1 回答
TA贡献1773条经验 获得超3个赞
我弄清楚并提出一些起点:
// Enum class for field types
final class InputTypeEnum {
const STRING_TYPE = 1;
const INTEGER_TYPE = 2;
const DECIMAL_TYPE = 3;
const DATE_TYPE = 4;
const DATE_EMAIL = 7;
}
// Here is class to flat the rules.
class RulesFlattener {
const ATTRIBUTE_KEY = 'attribute_key';
const CHILD_KEY = 'children';
private $input;
private $output = [];
// This array keeps map to translate rules
private $availableRules = [
'is_required' => 'required',
'input_type_id' => [
InputTypeEnum::STRING_TYPE => 'string',
InputTypeEnum::INTEGER_TYPE => 'integer',
InputTypeEnum::DECIMAL_TYPE => 'numeric',
InputTypeEnum::DATE_TYPE => 'date',
InputTypeEnum::DATE_EMAIL => 'email',
]
];
public function __construct($input) {
$this->input = $input;
}
private function extractRules($row) {
$rules = [];
foreach($row as $k => $v) {
if(isset($this->availableRules[$k])) {
$mappedRule = $this->availableRules[$k];
if(is_array($mappedRule)) {
$rule = $mappedRule[$v] ?? null;
} else {
$rule = $mappedRule;
}
$rules[] = $rule;
}
}
return array_unique($rules);
}
public function parse() {
return $this->parseRow($this->input);
}
private function parseRow($input, $parentKey = null) {
$output = [];
foreach ($input as $row) {
// Keep name of current attribute (for recursion)
$currentAttribute = $row[self::ATTRIBUTE_KEY] ?? null;
// If you want get more nested rules like product.*.photos.*.url use this:
// $currentAttribute = ( $parentKey ? $parentKey.'.*.':'') . $row[self::ATTRIBUTE_KEY] ?? null;
foreach($row as $k => $v) {
switch($k) {
case self::ATTRIBUTE_KEY:
$rules = $this->extractRules($row);
$output[($parentKey?$parentKey.'.*.':'').$v] = implode('|', $rules);
break;
case self::CHILD_KEY:
$output = array_merge($output, $this->parseRow($row[$k], $currentAttribute));
break;
}
}
}
return $output;
}
}
现在您可以将其用作:
$dataIn = [
[
"id" => 36,
"attribute_key" => "amount",
"attribute_value" => "Amount",
"input_type_id" => 3,
"is_required" => 1,
"parent_id" => null,
],
[
"id" => 37,
"attribute_key" => "products",
"attribute_value" => "Products",
"input_type_id" => 7,
"is_required" => 1,
"parent_id" => null,
"event" => null,
"children" => [
[
"id" => 38,
"attribute_key" => "product_name",
"attribute_value" => "Product Name",
"input_type_id" => 1,
"is_required" => 1,
"parent_id" => 37,
],
[
"id" => 39,
"attribute_key" => "price",
"attribute_value" => "Price",
"input_type_id" => 3,
"is_required" => 1,
"parent_id" => 37,
]
]
]
];
$flat = new RulesFlattener($dataIn);
$rules = $flat->parse();
我得到这个输出:
Array
(
[amount] => numeric|required
[products] => email|required
[products.*.product_name] => string|required
[products.*.price] => numeric|required
)
- 1 回答
- 0 关注
- 88 浏览
添加回答
举报