old = $old_value; $this->new = $new_value; $this->props_linked_to_parent = $props_linked_to_parent; } public function setCompareRelated(bool $compareRelated) { $this->_compare_related = $compareRelated; return $this; } public function getResult() { if (!is_null($this->_result)) { return $this->_result; } $result = []; if (!is_null($this->old)) { $props = array_values(array_unique(array_diff(ArrayHelper::merge( EntitiesComparator::getNonRelationProps($this->old), EntitiesComparator::getNonRelationProps($this->new) ), $this->props_linked_to_parent))); foreach ($props as $prop) { $result[$prop] = new FieldComparisonResult($this->old, $this->new, $prop); } if ($this->old instanceof IHaveVirtualPropsToCompare || $this->new instanceof IHaveVirtualPropsToCompare) { $old_virtual_props = $this->old->virtualProps ?? []; $new_virtual_props = $this->new->virtualProps ?? []; $virtual_prop_names = array_values(array_unique( ArrayHelper::merge( array_keys($old_virtual_props), array_keys($new_virtual_props) ) )); foreach ($virtual_prop_names as $virtual_prop_name) { $result[$virtual_prop_name] = new FieldComparisonResult($this->old, $this->new, $virtual_prop_name); } } if ($this->_compare_related && ($this->old instanceof IHasRelations || $this->new instanceof IHasRelations)) { $first_relations = ArrayHelper::getValue($this->old, 'relationsInfo', []); $second_relations = ArrayHelper::getValue($this->new, 'relationsInfo', []); $max_count = max(count($first_relations), count($second_relations)); for ($i = 0; $i < $max_count; $i++) { $relation = $first_relations[$i] ?? null; if (!$relation) { $relation = $second_relations[$i] ?? null; } if ($relation->ignore_in_comparison) { continue; } $first_children = ArrayHelper::getValue($first_relations, "{$i}.related"); $second_children = ArrayHelper::getValue($second_relations, "{$i}.related"); if ($relation instanceof OneToOneRelationPresenter) { if (!$first_children) { $first_children = null; } if (!$second_children) { $second_children = null; } $result[$relation->relation_label] = EntitiesComparator::compare( $this->filterArchived($first_children), $this->filterArchived($second_children), $relation->getChildColumnsInvolvedInRelation() ); } else { $result[$relation->relation_label] = EntitiesComparator::compareArrays( $this->filterArchived($first_children ?? []), $this->filterArchived($second_children ?? []), $relation->getChildColumnsInvolvedInRelation() ); } } } } elseif ($this->new) { $result = true; } $this->_result = $result; return $result; } protected function filterArchived($data) { if (is_array($data)) { return array_values(array_filter($data, function ($el) { if ($el instanceof ArchiveModelInterface) { return $el->{$el::getArchiveColumn()} != $el::getArchiveValue(); } return true; })); } else { if ($data instanceof ArchiveModelInterface) { return $data->{$data::getArchiveColumn()} != $data::getArchiveValue() ? $data : null; } return $data; } } public function getLeftEntity() { return $this->old; } public function getRightEntity() { return $this->new; } public function getDifferences(): array { $return = []; $comparison_result = $this->getResult(); if ($comparison_result) { if ($this->old) { $entity = $this->old; if (ArrayHelper::isAssociative($comparison_result)) { foreach ($comparison_result as $prop => $prop_result) { if ($prop_result) { if (is_array($prop_result)) { $diffs = array_values( array_filter( array_map( function ($res) { return $res->getDifferences(); }, $prop_result ), function ($res) { return !!$res; } ) ); } else { $diffs = $prop_result->getDifferences(); } if ($diffs) { if ($prop_result instanceof FieldComparisonResult) { $return = ArrayHelper::merge($return, $diffs); } else { $return[$entity->getAttributeLabel($prop)] = $diffs; } } } } } else { foreach ($comparison_result as $item) { if ($item) { $diffs = $item->getDifferences(); if ($diffs) { $return[] = $diffs; } } } } } } return $return; } }