<?php namespace Livewire\HydrationMiddleware; use Illuminate\Support\Arr; class HashDataPropertiesForDirtyDetection implements HydrationMiddleware { protected static $propertyHashesByComponentId = []; public static function hydrate($instance, $request) { $data = data_get($request, 'memo.data', []); collect($data)->each(function ($value, $key) use ($instance) { if (is_array($value)) { foreach (Arr::dot($value, $key.'.') as $dottedKey => $value) { static::rehashProperty($dottedKey, $value, $instance); } } else { static::rehashProperty($key, $value, $instance); } }); } public static function dehydrate($instance, $response) { $data = data_get($response, 'memo.data', []); $dirtyProps = collect(static::$propertyHashesByComponentId[$instance->id] ?? []) ->filter(function ($hash, $key) use ($data) { // Only return the propertyHashes/props that have changed. return static::hash(data_get($data, $key)) !== $hash; }) ->keys() ->toArray(); data_set($response, 'effects.dirty', $dirtyProps); } public static function rehashProperty($name, $value, $component) { static::$propertyHashesByComponentId[$component->id][$name] = static::hash($value); } public static function hash($value) { if (! is_null($value) && ! is_string($value) && ! is_numeric($value) && ! is_bool($value)) { if (is_array($value)) { return json_encode($value); } $value = method_exists($value, '__toString') ? (string) $value : json_encode($value); } // Using crc32 because it's fast, and this doesn't have to be secure. return crc32($value ?? ''); } }