Giter Site home page Giter Site logo

json-diff's People

Contributors

cedric-anne avatar jakobw avatar jsoncarmock avatar on2 avatar outdooracorn avatar owebboy avatar remicollet avatar silvan-wmde avatar techieforfun avatar vearutop avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

json-diff's Issues

JsonDiff from dictionary like array, getting duplicated path removal operations

Given diff from two arrays:

$array1 = json_decode('{"someData":{"1":{"s":"e","val":0.01009999999999999960309526869650653679855167865753173828125,"eIds":["38","191"]},"2":{"s":"y"},"3":{"s":"y"},"4":{"s":"y"},"5":{"s":"y"},"6":{"s":"y"},"24":{"s":"n"},"32":{"s":"y"},"37":{"s":"y"},"61":{"s":"y"},"62":{"s":"y"},"63":{"s":"y"},"64":{"s":"y"},"79":{"s":"y"},"80":{"s":"y"},"81":{"s":"y"},"82":{"s":"y"},"83":{"s":"y"},"84":{"s":"y"},"85":{"s":"y"},"86":{"s":"y"},"88":{"s":"e","eIds":["54"]},"89":{"s":"e","eIds":["54"]},"107":{"s":"y"},"108":{"s":"y"},"109":{"s":"y"},"113":{"s":"y"},"114":{"s":"y"},"122":{"s":"y"},"123":{"s":"y"},"126":{"s":"y"},"127":{"s":"y"},"128":{"s":"y"},"129":{"s":"y"},"130":{"s":"y"},"131":{"s":"y"},"132":{"s":"y"},"133":{"s":"y"},"158":{"s":"y"},"159":{"s":"y"},"160":{"s":"y"},"161":{"s":"y"},"162":{"s":"y"},"165":{"s":"y"},"166":{"s":"y"},"173":{"s":"y"},"174":{"s":"y"},"175":{"s":"y"},"176":{"s":"y"},"177":{"s":"y"},"178":{"s":"y"},"179":{"s":"y"},"181":{"s":"y"},"184":{"s":"y"},"185":{"s":"y"},"186":{"s":"y"},"187":{"s":"y"},"188":{"s":"y"},"191":{"s":"e","eIds":["54"]},"196":{"s":"y"},"197":{"s":"y"},"198":{"s":"y"},"200":{"s":"y"},"202":{"s":"y"},"203":{"s":"y"},"204":{"s":"y"},"205":{"s":"y"},"206":{"s":"y"},"207":{"s":"y"},"208":{"s":"y"},"209":{"s":"y"},"210":{"s":"y"},"211":{"s":"y"},"220":{"s":"y"},"221":{"s":"y"},"222":{"s":"y"},"223":{"s":"y"},"224":{"s":"y"},"225":{"s":"y"},"226":{"s":"y"},"227":{"s":"y"},"228":{"s":"y"},"229":{"s":"y"},"257":{"s":"y"},"258":{"s":"y"},"259":{"s":"y"},"260":{"s":"y"},"261":{"s":"y"},"262":{"s":"y"},"263":{"s":"y"},"264":{"s":"y"},"265":{"s":"y"},"266":{"s":"y"},"267":{"s":"y"},"268":{"s":"y"},"269":{"s":"y"},"270":{"s":"y"},"271":{"s":"y"},"272":{"s":"y"},"273":{"s":"y"},"274":{"s":"y"},"275":{"s":"y"},"276":{"s":"y"},"277":{"s":"y"},"278":{"s":"y"},"279":{"s":"y"},"280":{"s":"y"},"281":{"s":"y"},"282":{"s":"y"},"283":{"s":"y"},"284":{"s":"y"},"285":{"s":"y"},"286":{"s":"y"},"287":{"s":"y"},"308":{"s":"y"},"309":{"s":"y"},"317":{"s":"y"},"320":{"s":"y"},"321":{"s":"y"},"322":{"s":"y"},"327":{"s":"y"},"328":{"s":"y"},"329":{"s":"y"},"330":{"s":"y"},"331":{"s":"y"},"336":{"s":"y"},"337":{"s":"y"},"342":{"s":"y"},"343":{"s":"n","val":100},"350":{"s":"y"},"352":{"s":"y"},"353":{"s":"y"},"358":{"s":"y"},"364":{"s":"y"},"365":{"s":"y"},"371":{"s":"e","eIds":["54"]},"380":{"s":"y"},"381":{"s":"y"},"382":{"s":"y"},"408":{"s":"y"},"409":{"s":"y"},"410":{"s":"y"},"411":{"s":"y"},"419":{"s":"y"},"420":{"s":"y"},"421":{"s":"n"},"430":{"s":"y"},"431":{"s":"y"},"432":{"s":"y"},"433":{"s":"y"},"434":{"s":"y"},"435":{"s":"y"},"436":{"s":"y"},"437":{"s":"y"}}}', true);
$array2 = json_decode('{"someData":{"22":{"s":"e","eIds":["48"]},"23":{"s":"e","eIds":["235"]}}}', true);

$r = new \Swaggest\JsonDiff\JsonDiff($array1, $array2,  \Swaggest\JsonDiff\JsonDiff::REARRANGE_ARRAYS);

$patchArray = json_decode(json_encode($r->getPatch()), true);

foreach ($patchArray as $array) {
	echo json_encode($array) . "\n\n";
}

I get this result:

{"op":"remove","path":"/someData/1"}

{"op":"remove","path":"/someData/1"}

{"op":"remove","path":"/someData/1"}

{"op":"remove","path":"/someData/1"}

{"op":"remove","path":"/someData/1"}

{"op":"remove","path":"/someData/1"}

{"op":"remove","path":"/someData/18"}

{"op":"remove","path":"/someData/25"}

{"op":"remove","path":"/someData/29"}

{"op":"remove","path":"/someData/52"}

{"op":"remove","path":"/someData/52"}

{"op":"remove","path":"/someData/52"}

{"op":"remove","path":"/someData/52"}

{"op":"remove","path":"/someData/66"}

{"op":"remove","path":"/someData/66"}

{"op":"remove","path":"/someData/66"}

{"op":"remove","path":"/someData/66"}

{"op":"remove","path":"/someData/66"}

{"op":"remove","path":"/someData/66"}

{"op":"remove","path":"/someData/66"}

{"op":"remove","path":"/someData/66"}

{"op":"remove","path":"/someData/67"}

{"op":"remove","path":"/someData/67"}

{"op":"remove","path":"/someData/84"}

{"op":"remove","path":"/someData/84"}

{"op":"remove","path":"/someData/84"}

{"op":"remove","path":"/someData/87"}

{"op":"remove","path":"/someData/87"}

{"op":"remove","path":"/someData/94"}

{"op":"remove","path":"/someData/94"}

{"op":"remove","path":"/someData/96"}

{"op":"remove","path":"/someData/96"}

{"op":"remove","path":"/someData/96"}

{"op":"remove","path":"/someData/96"}

{"op":"remove","path":"/someData/96"}

{"op":"remove","path":"/someData/96"}

{"op":"remove","path":"/someData/96"}

{"op":"remove","path":"/someData/96"}

{"op":"remove","path":"/someData/120"}

{"op":"remove","path":"/someData/120"}

{"op":"remove","path":"/someData/120"}

{"op":"remove","path":"/someData/120"}

{"op":"remove","path":"/someData/120"}

{"op":"remove","path":"/someData/122"}

{"op":"remove","path":"/someData/122"}

{"op":"remove","path":"/someData/128"}

{"op":"remove","path":"/someData/128"}

{"op":"remove","path":"/someData/128"}

{"op":"remove","path":"/someData/128"}

{"op":"remove","path":"/someData/128"}

{"op":"remove","path":"/someData/128"}

{"op":"remove","path":"/someData/128"}

{"op":"remove","path":"/someData/129"}

{"op":"remove","path":"/someData/131"}

{"op":"remove","path":"/someData/131"}

{"op":"remove","path":"/someData/131"}

{"op":"remove","path":"/someData/131"}

{"op":"remove","path":"/someData/131"}

{"op":"remove","path":"/someData/133"}

{"op":"remove","path":"/someData/137"}

{"op":"remove","path":"/someData/137"}

{"op":"remove","path":"/someData/137"}

{"op":"remove","path":"/someData/138"}

{"op":"remove","path":"/someData/139"}

{"op":"remove","path":"/someData/139"}

{"op":"remove","path":"/someData/139"}

{"op":"remove","path":"/someData/139"}

{"op":"remove","path":"/someData/139"}

{"op":"remove","path":"/someData/139"}

{"op":"remove","path":"/someData/139"}

{"op":"remove","path":"/someData/139"}

{"op":"remove","path":"/someData/139"}

{"op":"remove","path":"/someData/139"}

{"op":"remove","path":"/someData/147"}

{"op":"remove","path":"/someData/147"}

{"op":"remove","path":"/someData/147"}

{"op":"remove","path":"/someData/147"}

{"op":"remove","path":"/someData/147"}

{"op":"remove","path":"/someData/147"}

{"op":"remove","path":"/someData/147"}

{"op":"remove","path":"/someData/147"}

{"op":"remove","path":"/someData/147"}

{"op":"remove","path":"/someData/147"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/174"}

{"op":"remove","path":"/someData/194"}

{"op":"remove","path":"/someData/194"}

{"op":"remove","path":"/someData/201"}

{"op":"remove","path":"/someData/203"}

{"op":"remove","path":"/someData/203"}

{"op":"remove","path":"/someData/203"}

{"op":"remove","path":"/someData/207"}

{"op":"remove","path":"/someData/207"}

{"op":"remove","path":"/someData/207"}

{"op":"remove","path":"/someData/207"}

{"op":"remove","path":"/someData/207"}

{"op":"remove","path":"/someData/211"}

{"op":"remove","path":"/someData/211"}

{"op":"remove","path":"/someData/215"}

{"op":"remove","path":"/someData/215"}

{"op":"remove","path":"/someData/221"}

{"op":"remove","path":"/someData/222"}

{"op":"remove","path":"/someData/222"}

{"op":"remove","path":"/someData/226"}

{"op":"remove","path":"/someData/231"}

{"op":"remove","path":"/someData/231"}

{"op":"remove","path":"/someData/236"}

{"op":"remove","path":"/someData/244"}

{"op":"remove","path":"/someData/244"}

{"op":"remove","path":"/someData/244"}

{"op":"remove","path":"/someData/269"}

{"op":"remove","path":"/someData/269"}

{"op":"remove","path":"/someData/269"}

{"op":"remove","path":"/someData/269"}

{"op":"remove","path":"/someData/276"}

{"op":"remove","path":"/someData/276"}

{"op":"remove","path":"/someData/276"}

{"op":"remove","path":"/someData/284"}

{"op":"remove","path":"/someData/284"}

{"op":"remove","path":"/someData/284"}

{"op":"remove","path":"/someData/284"}

{"op":"remove","path":"/someData/284"}

{"op":"remove","path":"/someData/284"}

{"op":"remove","path":"/someData/284"}

{"op":"remove","path":"/someData/284"}

{"value":{"s":"e","eIds":["48"]},"op":"add","path":"/someData/22"}

{"value":{"s":"e","eIds":["235"]},"op":"add","path":"/someData/23"}

Why am I getting duplicate remove operations?
E.g.

{"op":"remove","path":"/someData/284"}

{"op":"remove","path":"/someData/284"}

Using the:

"name": "swaggest/json-diff",
            "version": "v3.7.0",
            "source": {
                "type": "git",
                "url": "https://github.com/swaggest/json-diff.git",
                "reference": "53c412ad8e3fc1293d4e6fdf06f7839698ad897d"
            },

'Swaggest\\JsonDiff\\Exception' with message 'Key not found: key'

Hello, I'm getting the following error:

Exception/Stack Trace:

PHP Fatal error:  Uncaught exception 'Swaggest\\JsonDiff\\Exception' with message 
'Invalid key for array operation' in /usr/local/src/placelocal/vendor/swaggest/json-diff/src/JsonPointer.php:120
Stack trace:
#0 /usr/local/src/placelocal/vendor/swaggest/json-diff/src/JsonPatch.php(121): Swaggest\\JsonDiff\\JsonPointer::add(Object(stdClass), Array, 'missing value', false)
#1 /usr/local/src/placelocal/public_html/test.php(34): Swaggest\\JsonDiff\\JsonPatch->apply(Object(stdClass))
#2 {main}
  thrown in /usr/local/src/placelocal/vendor/swaggest/json-diff/src/JsonPointer.php on line 120

Using php5.6, v3.4.0

Test Code:

$old = [
    "key" => "diffvalue",
    "nestedKey" => ["nestedKey" => "nesteddiffValue"],
    "unchanged" => "value",
    "new key" => "new value",
    "new array" => ["new value3", "new value2"],
    "notMissingKey" => [],
    "appendKey" => ["value1", "value2"]
];
$new = [
    "key" => "value",
    "nestedKey" => ["nestedKey2" => "nestedValue"],
    "unchanged" => "value",
    "missingKey" => ["missingkey's child key" => "missing value"],
    "notMissingKey" => ["nmk:missingkey" => "missing value", "nmk:missingkey2" => "missing value 2"],
    "appendKey" => ["value1"]
];

$diff = new \Swaggest\JsonDiff\JsonDiff(json_decode(json_encode($old)), json_decode(json_encode($new)));
$patch = $diff->getPatch();

$test = json_decode(json_encode($old));
$patch->apply($test);

Thank you ๐Ÿ‘

I just want to thank you for json-diff, I was looking for such a tool to highlight what has been modified in a JSON file compared to an original file and, youhou!, json-diff does it perfectly. Thank you! Thank you very much!

For info, I've built a Powershell script based on your tool today: https://github.com/cavo789/json-tools

Christophe

Removing an item from the array when option REARRANGE_ARRAYS is enabled

Hi!

I use JsonDiff with REARRANGE_ARRAYS option to minimize the difference. It works fine when it comes to adding a new item to the array. But with removing it produces cascade replaces.

For example, I have 2 JSON to compare:
Original:

{
    "my_array": [
        {
            "key": "qwerty"
        },
        {
            "key": "asdfg"
        },
        {
            "key": "zxcvb"
        }
    ]
}

New:

{
    "my_array": [
        {
            "key": "asdfg"
        },
        {
            "key": "zxcvb"
        }
    ]
}

I'd like to have JSON Patch like that:

[
    {
        "op": "remove",
        "path": "/my_array/0"
    }
]

but I get:

[
    {
        "value": "qwerty",
        "op": "test",
        "path": "/my_array/0/key"
    },
    {
        "value": "asdfg",
        "op": "replace",
        "path": "/my_array/0/key"
    },
    {
        "value": "asdfg",
        "op": "test",
        "path": "/my_array/1/key"
    },
    {
        "value": "zxcvb",
        "op": "replace",
        "path": "/my_array/1/key"
    },
    {
        "op": "remove",
        "path": "/my_array/2"
    }
]

I suggest not to use array_values here:
$newRearranged = array_values($newRearranged);
because it breaks original indexes

Can you fix it please?

Thanks a lot!

Add option for exclute test operation

Could be usefull add ability to disable test operation in JsonDiff
some node classes like fast-json-patch work also without and in websocket comunication can reduce traffic with large amount of change

if ($this->jsonPatch !== null) {
    if ( ! self::SKIP_TEST_ENTRIES ) {
        $this->jsonPatch->op(new Test($this->path, $original));
    }
    $this->jsonPatch->op(new Replace($this->path, $new));
}

Unwanted count() exception in JsonPointer.php

Comparing two structured JSON I often get this exception:

count(): Argument #1 ($value) must be of type Countable|array, string given

raised at line 152 of file JsonPointer.php:
....

                    if (0 === ($flags & self::TOLERATE_ASSOCIATIVE_ARRAYS)) {
                        **if ($intKey > count($ref) && 0 === ($flags & self::RECURSIVE_KEY_CREATION)) {** 
                            throw new JsonPointerException('Index is greater than number of items in array');
                        } elseif ($intKey < 0) {
                            throw new JsonPointerException('Negative index');
                        }
                    }

....

I am calling jsonDiff in this way:

                    $diff = new JsonDiff(
                        $jsonTarget,
                        $jsonNew,
                        JsonDiff::REARRANGE_ARRAYS +
                            JsonDiff::COLLECT_MODIFIED_DIFF
                    );

with these two objects (first is Target, second is New), that are obviously differents:

TARGET
[["' POT NOODLE 500011820348 ยฃ0.80D'","NOODLE","",[""],"","1","DRY PASTA AND RICE"],["' STIR FRY 501033820008 ยฃ0.75D'","LETTUCE","",[""],"","1","VEGETABLES"],["' CB SOUP 500023286522 ยฃ1.00D'","VEGETABLE SOUP","",["BOTTIGLIA","1.00 L"],"","1","VEGETABLES"],["' KIDNEY BEANS 505244916778 ยฃ0.33D ยฃ1.00D'","BEANS","",[""],"1.00","1","LEGUMES"],["' GRAVY 505717209125 ยฃ0.28D'","FILLETS","",[""],"","1","MEATS READY TO BE COOKED"],["' BAKED BEANS 505244916772 ยฃ2.00D'","BEANS","",[""],"","1","LEGUMES"],["' COFFEE 844529032622'","COFFEE","",["844529032622 L"],"","1","COFFEE AND INFUSIONS"],["' CHOCOLATE 505407086455'","CHOCOLATE","",[""],"","1","CHOCOLATE AND CHOCOLATES"],["' KITCHEN ROLL 800426021048 ยฃ4.75V'","REGINA KITCHEN ROLL","REGINA",["800426021048 METRI"],"","1","HOME CARE"],["' TABLE SALT 501998910311 ยฃ0.95D'","SALT","",[""],"","1","SAUCES AND CONDIMENTS"],["' RED WINE 780432074610 ยฃ8.00V'","WINE","",["x 780432074610"],"","1","ALCOHOLIC BEVERAGES"]]

NEW
[[" PUI NUUULE ยฃ0.80D","BURGER","",[""],"","1","MEATS READY TO BE COOKED"],[" POT NOODLE 500011820348 ยฃ0.75D","NOODLE","",[""],"","1","DRY PASTA AND RICE"],[" CB SOUP 500023286522","VEGETABLE SOUP","",["BOTTIGLIA"],"","1","VEGETABLES"],[" KIDNEY BEANS 505244916778","BEANS","",[""],"","1","LEGUMES"],[" ยฃ1.00D","KIWI","",[""],"","1","FRUIT"],[" GRAVY 505717209125","FILLETS","",[""],"","1","MEATS READY TO BE COOKED"],[" BAKED BEANS","BEANS","",[""],"","1","LEGUMES"],[" 844529032622 ยฃ2.00D","KIWI","",[""],"","1","FRUIT"],[" COFFEE","COFFEE","",[""],"","1","COFFEE AND INFUSIONS"],[" CHOCOLATE 505407086455 ยฃ1.29V","CHOCOLATE","",[""],"","1","CHOCOLATE AND CHOCOLATES"],[" KITCHEN ROLL 800426021048","REGINA KITCHEN ROLL","REGINA",[""],"","1","HOME CARE"],[" TABLE SALT 501998910311 ยฃ0.95D","SALT","",[""],"","1","SAUCES AND CONDIMENTS"],[" RED WINE 780432074610 ยฃ8.00V","WINE","",["x 780432074610"],"","1","ALCOHOLIC BEVERAGES"]]

Is there a way to avoid /solve this ?

I am runnig PHO 8.1.10

Thanks

Issue with comparing arrays

Hi,

Sorry to bother you again. But when comparing two JSON objects, there is still a problem if the two contain an array whose contents are the same but do not appear in the same order in the array. Enclosed two JSON documents for testing.

Is there a chance to get a fix for this?

Thanks a lot
Christian

Archiv.zip

getPatch with REARRANGE_ARRAYS is not returning the correct paths when items are removed from an array

TEST

$previous = ['Apples', 'Oranges', 'Bananas', 'Grapes'];
$current = ['Apples', 'Grapes'];
$JsonDiff = new JsonDiff($previous, $current, JsonDiff::REARRANGE_ARRAYS);
$patch = json_decode(json_encode($JsonDiff->getPatch()), true) ?: [];
print_r($patch);

EXPECTED RESULT

When the [1] and [2] position items in the array are successfully removed the patch accurately reflects this
Array ( [0] => Array ( [op] => remove [path] => /1 ) [1] => Array ( [op] => remove [path] => /2) )

ACTUAL RESULT

When [1] and [2] position items in the array are successfully removed the patch only reflects the first item and it's repeated twice. There is no reference to the second item anywhere in the patch response
Array ( [0] => Array ( [op] => remove [path] => /1 ) [1] => Array ( [op] => remove [path] => /1) )

Class "Swaggest\JsonDiff\JsonDiff" not found

local.ERROR: Class "Swaggest\JsonDiff\JsonDiff" not found {"exception":"[object] (Error(code: 0): Class "Swaggest\JsonDiff\JsonDiff" not found at

Composer.json:

{
  "name": "laravel/laravel",
  "type": "project",
  "description": "The Laravel Framework.",
  "keywords": [
	"framework",
	"laravel"
  ],
  "license": "MIT",
  "require": {
    "php": "^8.1",
    "ext-curl": "*",
    "ext-json": "*",
    "ext-openssl": "*",
    "ext-pdo": "*",
    "aws/aws-sdk-php-laravel": "~3.0",
    "darkaonline/l5-swagger": "^8.0",
    "doctrine/dbal": "^3.1",
    "fruitcake/laravel-cors": "^3.0",
    "gamegos/jws": "^1.0",
    "goetas-webservices/xsd-reader": "^0.3.6",
    "guzzlehttp/guzzle": "^7.0.1",
    "intervention/image": "^2.5",
    "laravel/framework": "^9.0",
    "laravel/octane": "^1.2",
    "laravel/telescope": "^4.7",
    "laravel/tinker": "^2.5",
    "league/flysystem-aws-s3-v3": "^3.0",
    "maatwebsite/excel": "^3.1",
    "monarobase/country-list": "^3.2",
    "namshi/jose": "^7.2",
    "owen-it/laravel-auditing": "^13.0",
    "php-open-source-saver/jwt-auth": "^2.0",
    "phpseclib/phpseclib": "^3.0",
    "predis/predis": "^2.0",
    "pusher/pusher-php-server": "^7.0",
    "s-ichikawa/laravel-sendgrid-driver": "^4.0",
    "scotteh/php-goose": "^1.1",
    "sentry/sentry-laravel": "^2.11",
    "spatie/laravel-ignition": "^1.0",
    "spatie/laravel-permission": "^5.5",
    "swaggest/json-diff": "^3.9",
    "thedoctor0/laravel-mailjet-driver": "2.0.0",
    "twilio/sdk": "^6.34",
    "vlucas/phpdotenv": "^5.2",
    "voku/portable-utf8": "^6.0",
    "voku/simple_html_dom": "^4.7",
    "zircote/swagger-php": "^4.4"
  },
  "require-dev": {
    "barryvdh/laravel-ide-helper": "^2.9",
    "fakerphp/faker": "^1.13",
    "kitloong/laravel-migrations-generator": "^6.0",
    "mockery/mockery": "^1.3.1",
    "nunomaduro/collision": "^6.1",
    "nunomaduro/larastan": "^2.0",
    "nunomaduro/phpinsights": "^2.4",
    "phpunit/phpunit": "^9.5",
    "rector/rector": "^0.14.0"
  },
  "config": {
	"optimize-autoloader": true,
	"preferred-install": "dist",
	"sort-packages": true,
    "allow-plugins": {
      "dealerdirect/phpcodesniffer-composer-installer": true
    }
  },
  "extra": {
	"laravel": {
	  "dont-discover": [
		"laravel/dusk"
	  ]
	}
  },
  "autoload": {
	"psr-4": {
	  "App\\": "app/",
	  "Database\\Factories\\": "database/factories/",
	  "Database\\Seeders\\": "database/seeds"
	},
	"classmap": [
	  "database/seeds"
	],
	"files": [
	  "app/helpers.php"
	]
  },
  "autoload-dev": {
	"psr-4": {
	  "Tests\\": "tests/"
	}
  },
  "minimum-stability": "dev",
  "prefer-stable": true,
  "scripts": {
	"post-autoload-dump": [
	  "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump"
	],
	"post-root-package-install": [
	  "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
	],
	"post-create-project-cmd": [
	  "@php artisan key:generate --ansi"
	],
	"phpstan": "phpstan analyse --ansi",
	"rector": "rector process app --ansi",
	"insights": "./vendor/bin/phpinsights --no-interaction"
  }
}

The import:

use Swaggest\JsonDiff\JsonDiff;

getModifiedDiff()

i'm sending those 2 json objects
{"output": [{"text": "ู‚ูŽู„ูŽู…", "type": "text"}], "answers": [{"text": "ู€ู…", "correct": true}, {"text": "ู…", "correct": false}, {"text": "ู€ู…ู€", "correct": false}, {"text": "ู…ู€", "correct": false}], "question": [{"text": "ู‚ูŽู„ูŽู€....", "type": "text", "translation": ""}], "answersType": "text", "questionText": "Harfin uygun yazฤฑlฤฑลŸฤฑnฤฑ seรงiniz"}

{"questionText":"Harfin uygun yaz\u0131l\u0131\u015f\u0131n\u0131 se\u00e7iniz","question":[{"type":"text","text":"\u0642\u064e\u0644\u064e\u0640....","translation":"","upload":""}],"answersType":"text","answers":[{"text":"\u0640\u0645","correct":true,"upload":"a0vA206.mp4","image":""},{"text":"\u0645","correct":false,"upload":"a0vA207.mp4","image":""},{"text":"\u0640\u0645\u0640","correct":false,"upload":"","image":""},{"text":"\u0645\u0640","correct":false,"upload":"","image":""}],"output":[{"type":"text","text":"\u0642\u064e\u0644\u064e\u0645","upload":""}]}

and using jsonDiff with this flags
JsonDiff::REARRANGE_ARRAYS + JsonDiff::COLLECT_MODIFIED_DIFF

when i call getModifiedDiff() it showed null array even it's obvious there is a difference between 2 json

Enhancement: Include failed operation in Exception

Hi!

Thanks for an awesome project!

We have som Diffs with a lot of operations in each patch, and the exception can be a little hard to troubleshoot.

Would you be interested in a PR that includes the failed operation in the exception?

Library only works with stdClass not with associative arrays

We we're looking into replacing our use of https://github.com/mikemccabe/json-patch-php with this library because it seemed to be better maintained. But we found a blocking problem.

It appears this library only works correctly with stdClass representations of decoded json data but not with associative arrays which is what you get when you do json_decode($json, true). It seems very counter-intuitive because it's often easier to work with arrays than with stdClass.

To illustrate the problem I modified the decoding in the example from the readme and it starts failing.

$diff = new JsonDiff(json_decode($originalJson, true), json_decode($newJson, true));
$this->assertEquals(json_decode($patchJson, true), $diff->getPatch()->jsonSerialize()); 
// this does not succeed because it returns the json diff with stdClass instead of array 
// which would work for jsonSerialize as well theoretically, see https://github.com/swaggest/json-diff/blob/master/src/JsonPatch.php#L108

$original = json_decode($originalJson, true);
$patch = JsonPatch::import(json_decode($patchJson, true)); 
// import seems to work also with array, see https://github.com/swaggest/json-diff/blob/dadb65fbc6888c9066c9eb167a98a721eb0f63a1/src/JsonPatch.php#L54
$patch->apply($original); 
// apply fails because the it tries to access fields as properties on $original as stdClass
// instead of as elements of an array

Improve JsonPatch exceptions

Hi! ๐Ÿ‘‹

As mentioned in #49 we (@wmde) are using json-diff in the context of a PATCH endpoint in our REST API. We realized that some changes to the exceptions thrown by JsonPatch would allow us to provide more helpful error responses to our users.

The concrete improvements we're thinking of are:

  1. More exception types for different types of errors (similar to #49), e.g. some sort of MissingFieldException and InvalidOperationException thrown by JsonPatch::import() to tell the two error cases apart
  2. Include details about the error in the exception if possible. For most (all?) error cases would be the failed operation (related to #45), but potentially also additional information, e.g. the actual value that caused a test operation to fail.

If this generally sound useful, we'd be happy to submit a PR.

Question: Visualise the difference

First of all its a great plugin, works like a charm.

I have a question is there an easy way to visualize the difference on browser similar like this PR: https://github.com/swaggest/json-diff/pull/39/files

I found some other node plugins that can show the difference.
But as I'm using this plugin on the backend so i want to use this same plugin to visualize the difference, to make it consistent.

Thanks,

Usman

Fails when removing multiple elements from array

When you remove more than one element from an array, it breaks.

A test case:

source

[{"name":"a"},{"name":"b"},{"name":"c"}]

target:

[{"name":"a"}]

Error:

Uncaught exception 'Swaggest\JsonDiff\Exception' with message 'Key not found: 2' in /var/www/alquilerargentina/vendor/swaggest/json-diff/src/JsonPointer.php:185

note: pretty similar to this one java-json-tools/json-patch#11

Remove last elemnt followed by add converting to associative array

Removing the last element of an array by index followed by adding a new element converts the object to an associative array with numeric indices.

This patch

[
  {"op":"add","path":"","value":["a","b","c","d"]},
  {"op":"remove","path":"\/3"},
  {"op":"add","path":"\/-","value":"e"}
]

should produce (an array)

[
  "a",
  "b",
  "c",
  "e"
]

but does produce (an object)

{
  "0":"a",
  "1":"b",
  "2":"c",
  "4":"e"
}

php code snipit

$reportData = json_decode('{}');
$patch = JsonPatch::import(json_decode('[{"op":"add","path":"","value":["a","b","c","d"]},{"op":"remove","path":"\/3","value":""},{"op":"add","path":"\/-","value":"e"}]'));
$patch->apply($reportData);

print(json_encode($reportData));

If the last element is removed

[
  "op":"remove",
  "path":"\/4"
]

the output object becomes an array again.
This holds true for however many elements are added (ie add 10, remove 1, and the object is an array again).

Warning: A non-numeric value encountered

$actualKey -= $removedOffset;

This line seems to be a causing an error when i pass 2 associative arrays, when i comment it out it works fine.

Here is an example of what im seeing trigger the error:

        $r = new JsonDiff(
            ["name" => "Test"],
            [],
            JsonDiff::REARRANGE_ARRAYS
        );

Running PHP 7.2.8

Invalid key for array operation

Hi! I'm getting this exception when applying a patch to this GeoJSON

$json1 = <<<JSON
    {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": {},
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              [
                [
                  0.582275390625,
                  43.04881979669318
                ],
                [
                  0.97503662109375,
                  43.04881979669318
                ],
                [
                  0.97503662109375,
                  43.29120116988416
                ],
                [
                  0.582275390625,
                  43.29120116988416
                ],
                [
                  0.582275390625,
                  43.04881979669318
                ]
              ]
            ]
          }
        },
        {
          "type": "Feature",
          "properties": {},
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              [
                [
                  0.9722900390624999,
                  42.97049193148623
                ],
                [
                  1.329345703125,
                  42.97049193148623
                ],
                [
                  1.329345703125,
                  43.29120116988416
                ],
                [
                  0.9722900390624999,
                  43.29120116988416
                ],
                [
                  0.9722900390624999,
                  42.97049193148623
                ]
              ]
            ]
          }
        },
        {
          "type": "Feature",
          "properties": {
            "stroke": "#555555",
            "stroke-width": 2,
            "stroke-opacity": 1,
            "fill": "#555555",
            "fill-opacity": 0.5
          },
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              [
                [
                  0.8778762817382812,
                  42.97275278822627
                ],
                [
                  0.8205413818359375,
                  42.945365709261324
                ],
                [
                  0.8758163452148438,
                  42.9224919308288
                ],
                [
                  0.91461181640625,
                  42.94234987312984
                ],
                [
                  0.8778762817382812,
                  42.97275278822627
                ]
              ]
            ]
          }
        },
        {
          "type": "Feature",
          "properties": {
            "stroke": "#555555",
            "stroke-width": 2,
            "stroke-opacity": 1,
            "fill": "#555555",
            "fill-opacity": 0.7,
            "dinasty": "qi"
          },
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              [
                [
                  0.8778762817382812,
                  42.97325518954874
                ],
                [
                  0.9156417846679686,
                  42.94234987312984
                ],
                [
                  0.9578704833984375,
                  42.934055561994754
                ],
                [
                  0.9836196899414061,
                  42.96697487803267
                ],
                [
                  0.9348678588867186,
                  42.98857645832184
                ],
                [
                  0.8778762817382812,
                  42.97325518954874
                ]
              ]
            ]
          }
        }
      ]
    }
JSON;

$json2 = <<<JSON
    {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": {},
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              [
                [
                  0.582275390625,
                  43.04881979669318
                ],
                [
                  0.97503662109375,
                  43.04881979669318
                ],
                [
                  0.97503662109375,
                  43.29120116988416
                ],
                [
                  0.582275390625,
                  43.29120116988416
                ],
                [
                  0.582275390625,
                  43.04881979669318
                ]
              ]
            ]
          }
        },
        {
          "type": "Feature",
          "properties": {
            "stroke": "#555555",
            "stroke-width": 2,
            "stroke-opacity": 1,
            "fill": "#555555",
            "fill-opacity": 0.5
          },
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              [
                [
                  0.8778762817382812,
                  42.97275278822627
                ],
                [
                  0.8205413818359375,
                  42.945365709261324
                ],
                [
                  0.8758163452148438,
                  42.9224919308288
                ],
                [
                  0.91461181640625,
                  42.94234987312984
                ],
                [
                  0.8778762817382812,
                  42.97275278822627
                ]
              ]
            ]
          }
        }
      ]
    }
JSON;

$diff = new JsonDiff(json_decode($json1), json_decode($json2));
$exportedPatch = $diff->getPatch()->export($diff->getPatch());

$patch = JsonPatch::import($exportedPatch);

dd($patch->apply($json1));

Difference ignoring order of elements in an array.

Hi,

is there a way to get the difference between two JSON objects while ignoring the order of elements in an array. For instance, the following example currently returns 4 differences but should return 0.

$diff = new \Swaggest\JsonDiff\JsonDiff( json_decode('{"data": [{"A": 1},{"B": 2}]}'), json_decode('{"data": [{"B": 2},{"A": 1}]}'), \Swaggest\JsonDiff\JsonDiff::REARRANGE_ARRAYS ); echo "\n" . $diff->getDiffCnt() . "\n";

Thanks!

Wrong indexes of removed array items

Hello!
Here is the situation: I have 3 items in origin array and remove last 2 of them. In exported patch there are 2 removes, but with similar indexes. This issue does not appear on added items.

Example.
Origin JSON.

{
  "companies": {
    "list": [
      {
        "name": "Company 1",
        "orgnumber": "111"
      }, {
        "name": "Company 2",
        "orgnumber": "222"
      }, {
        "name": "Company 3",
        "orgnumber": "333"
      }
    ]
  },
  "contacts": {
    "list": [
      {
        "name": "Ivan",
        "phone": "11111"
      }
    ]
  }
}

New JSON.

{
  "companies": {
    "list": [
      {
        "name": "Company 1",
        "orgnumber": "111"
      }
    ]
  },
  "contacts": {
    "list": [
      {
        "name": "Ivan",
        "phone": "11111"
      },
      {
        "name": "Petr",
        "phone": "22222"
      },
      {
        "name": "Victor",
        "phone": "33333"
      }
    ]
  }
}

Code

$r = new Swaggest\JsonDiff\JsonDiff((json_decode(file_get_contents('origin.json'))), (json_decode(file_get_contents('new.json'))));
print_r(Swaggest\JsonDiff\JsonPatch::export($r->getPatch()));

Output

Array
(
    [0] => stdClass Object
        (
            [op] => remove
            [path] => /companies/list/1
        )

    [1] => stdClass Object
        (
            [op] => remove
            [path] => /companies/list/1
        )

    [2] => stdClass Object
        (
            [value] => stdClass Object
                (
                    [name] => Petr
                    [phone] => 22222
                )

            [op] => add
            [path] => /contacts/list/1
        )

    [3] => stdClass Object
        (
            [value] => stdClass Object
                (
                    [name] => Victor
                    [phone] => 33333
                )

            [op] => add
            [path] => /contacts/list/2
        )

)

Companies with indexes 1 and 2 are removed, but it paths both indexes are 1.
At the same time paths of added items in Contacts are ok (1 and 2).
Or I miss something?

Thanks in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.