Tazya/php-project-lvl2

View on GitHub
src/differ.php

Summary

Maintainability
A
2 hrs
Test Coverage
<?php

namespace gendiff\differ;

use function gendiff\parsers\parse;
use function gendiff\Formatters\plain\renderPlainDiff;
use function gendiff\Formatters\pretty\renderPrettyDiff;
use function gendiff\Formatters\json\renderJsonDiff;

function makeAst($firstProperties, $secondProperties)
{
    $allKeys = array_unique(
        array_merge(
            array_keys($firstProperties),
            array_keys($secondProperties)
        )
    );

    $ast = array_map(function ($key) use (&$iter, $firstProperties, $secondProperties) {
        if (!array_key_exists($key, $firstProperties)) {
            return ['name' => $key, 'type' => 'added', 'value' => $secondProperties[$key]];
        }
        
        if (!array_key_exists($key, $secondProperties)) {
            return ['name' => $key, 'type' => 'deleted', 'value' => $firstProperties[$key]];
        }
        
        $firstProperty = $firstProperties[$key];
        $secondProperty = $secondProperties[$key];

        if ($firstProperty === $secondProperty) {
            return ['name' => $key, 'type' => 'unchanged', 'value' => $firstProperty];
        }

        if (is_array($firstProperty) && is_array($secondProperty)) {
            return ['name' => $key, 'type' => 'parent', 'children' => makeAst($firstProperty, $secondProperty)];
        }

        if ($firstProperty !== $secondProperty) {
            return [
                'name' => $key,
                'type' => 'changed',
                'newValue' => $secondProperty,
                'oldValue' => $firstProperty
            ];
        }
    }, $allKeys);

    return array_values($ast);
}

function getContent($path)
{
    $normalized = str_replace("\\", "/", $path);
    if ($normalized[0] == '/') {
        $currentDirectory = '';
    } else {
        $currentDirectory = getcwd() . "/";
    }
    $fullPath = realpath($currentDirectory . $normalized);

    if (!$fullPath) {
        throw new \Exception("File '$path' not found!");
    }

    $content = file_get_contents($fullPath);

    return $content;
}

function generateDiff(string $firstPath, string $secondPath, $format = "pretty")
{
    $firstFileExt = pathinfo($firstPath, PATHINFO_EXTENSION);
    $secondFileExt = pathinfo($secondPath, PATHINFO_EXTENSION);

    $firstProperties = parse($firstFileExt, getContent($firstPath));
    $secondProperties = parse($secondFileExt, getContent($secondPath));
    
    $ast = makeAst($firstProperties, $secondProperties);

    switch ($format) {
        case 'pretty':
            $diff = renderPrettyDiff($ast);
            break;
        case 'plain':
            $diff = renderPlainDiff($ast);
            break;
        case 'json':
            $diff = renderJsonDiff($ast);
            break;
                
        default:
            throw new \Exception("[Render error] Format '$format' is unknown for rendering");
    }

    return $diff;
}