You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

109 lines
3.2 KiB

<?php
namespace core\forms;
use yii\base\Model;
use yii\helpers\ArrayHelper;
abstract class CompositeForm extends Model
{
/**
* @var Model[]|array[]
*/
private $forms = [];
abstract protected function internalForms(): array;
public function load($data, $formName = null): bool
{
$success = parent::load($data, $formName);
foreach ($this->forms as $name => $form) {
if (is_array($form)) {
$success = Model::loadMultiple($form, $data, $formName === null ? null : $name) && $success;
} else {
$success = $form->load($data, $formName !== '' ? null : $name) && $success;
}
}
return $success;
}
public function validate($attributeNames = null, $clearErrors = true): bool
{
$parentNames = $attributeNames !== null ? array_filter((array)$attributeNames, 'is_string') : null;
$success = parent::validate($parentNames, $clearErrors);
foreach ($this->forms as $name => $form) {
if (is_array($form)) {
$success = Model::validateMultiple($form) && $success;
} else {
$innerNames = $attributeNames !== null ? ArrayHelper::getValue($attributeNames, $name) : null;
$success = $form->validate($innerNames ?: null, $clearErrors) && $success;
}
}
return $success;
}
public function hasErrors($attribute = null): bool
{
if ($attribute !== null) {
return parent::hasErrors($attribute);
}
if (parent::hasErrors($attribute)) {
return true;
}
foreach ($this->forms as $name => $form) {
if (is_array($form)) {
foreach ($form as $i => $item) {
if ($item->hasErrors()) {
return true;
}
}
} else {
if ($form->hasErrors()) {
return true;
}
}
}
return false;
}
public function getFirstErrors(): array
{
$errors = parent::getFirstErrors();
foreach ($this->forms as $name => $form) {
if (is_array($form)) {
foreach ($form as $i => $item) {
foreach ($item->getFirstErrors() as $attribute => $error) {
$errors[$name . '.' . $i . '.' . $attribute] = $error;
}
}
} else {
foreach ($form->getFirstErrors() as $attribute => $error) {
$errors[$name . '.' . $attribute] = $error;
}
}
}
return $errors;
}
public function __get($name)
{
if (isset($this->forms[$name])) {
return $this->forms[$name];
}
return parent::__get($name);
}
public function __set($name, $value)
{
if (in_array($name, $this->internalForms(), true)) {
$this->forms[$name] = $value;
} else {
parent::__set($name, $value);
}
}
public function __isset($name)
{
return isset($this->forms[$name]) || parent::__isset($name);
}
}