Я понял это и сделал отправную точку:
// 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
)