mrDenisZharkov/project-lvl2-s459

View on GitHub
src/Ast.php

Summary

Maintainability
A
1 hr
Test Coverage
<?php
namespace gendiff\Ast;

use function Funct\Collection\union;

function initNode($key, $type, $beforeValue, $afterValue, $children)
{
    return [
        'key' => $key,
        'type' => $type,
        'beforeValue' => $beforeValue,
        'afterValue' => $afterValue,
        'children' => $children
    ];
}

function parseAst($beforeDataObj, $afterDataObj)
{
    $beforeData = get_object_vars($beforeDataObj);
    $afterData = get_object_vars($afterDataObj);
    
    $keys = union(array_keys($beforeData), array_keys($afterData));
    $ast = array_reduce($keys, function ($acc, $key) use ($beforeData, $afterData) {
        $beforeValue = $beforeData[$key] ?? '';
        $afterValue = $afterData[$key] ?? '';
        $beforeValue = normalizeBoolValue($beforeValue);
        $afterValue = normalizeBoolValue($afterValue);
        if (array_key_exists($key, $beforeData) && array_key_exists($key, $afterData)) {
            if (is_object($beforeValue) && is_object($afterValue)) {
                $acc[] = initNode($key, 'node', null, null, parseAst($beforeValue, $afterValue));
            } elseif ($beforeValue === $afterValue) {
                $acc[] = initNode($key, 'equal', $beforeValue, $afterValue, null);
            } else {
                $acc[] = initNode($key, 'changed', $beforeValue, $afterValue, null);
            }
        } elseif (!array_key_exists($key, $beforeData)) {
            $afterNotObjValue = is_object($afterValue) ? get_object_vars($afterValue) :  $afterValue;
            $acc[] = initNode($key, 'added', null, $afterNotObjValue, null);
        } else {
            $beforeNotObjValue = is_object($beforeValue) ? get_object_vars($beforeValue) :  $beforeValue;
            $acc[] = initNode($key, 'removed', $beforeNotObjValue, null, null);
        }
        return $acc;
    }, []);
    return $ast;
}

function normalizeBoolValue($value)
{
    return is_bool($value) ? ($value = $value ? 'true' : 'false') : $value;
}