-2

I'm trying to implement a RecordsActivity trait like in the Birdboard example on Laracasts. Here's Jeffrey's code updated for Laravel >=5.7:

/**
 * Fetch the changes to the model.
 *
 * @return array|null
 */
protected function activityChanges()
{
    if ($this->wasChanged()) {

        // weirdness here, see below
        dump(
            $this->oldAttributes, 
            $this->getAttributes(), 
            array_diff($this->oldAttributes, $this->getAttributes())
        );

        return [
            'before' => Arr::except(array_diff($this->oldAttributes, $this->getAttributes()), 'updated_at'),
            'after' => Arr::except($this->getChanges(), 'updated_at')
        ];
    }
}

The dump() above produces the below response during the test (without annotations). Nothing changes between the two arrays, and it's obvious that one row is different, but somehow array_diff is failing.

// $this->oldAttributes
array:14 [
  "name" => "890 Gleichner Lights Suite 446"
  "address" => "890 Gleichner Lights Suite 446"
  "city" => "Mantetown"
  "state" => "CT"
  "postal_code" => "00627"
  "active" => false
]

// $this->getAttributes()
array:14 [
  "name" => "890 Gleichner Lights Suite 446"
  "address" => "Changed"
  "city" => "Mantetown"
  "state" => "CT"
  "postal_code" => "00627"
  "active" => false
]

// array_diff($this->oldAttributes, $this->getAttributes())
[]
Erich
  • 2,408
  • 18
  • 40

1 Answers1

1

Check the array_diff

array_diff ( array $array1 , array $array2 [, array $... ] ) :array

Compares array1 against one or more other arrays and returns the values in array1 that are not present in any of the other arrays.

So if one field's value is set empty, change the order cannot work too, for example: set the "address" => "", then array_diff($this->getAttributes(), $this->oldAttributes) will return [] too.

array_diff_assoc ( array $array1 , array $array2 [, array $... ] ) : array

Compares array1 against array2 and returns the difference. Unlike array_diff() the array keys are also used in the comparison.

Use array_diff_assoc is better:

$changes = array_diff_assoc($this->oldAttributes(), $this->getAttributes);
TsaiKoga
  • 12,914
  • 2
  • 19
  • 28
  • +1 for considering the array keys, but this doesn't solve the problem. `array_diff_assoc()` also fails. – Erich Feb 02 '20 at 20:33
  • @Erich the comparison is **key with value**, so it will return `array("address" => "890 Gleichner Lights Suite 446")`. – TsaiKoga Feb 03 '20 at 01:59
  • Right, I understand that, but on my end, it's producing nothing (`[]`) and I'm not sure why. – Erich Feb 03 '20 at 02:08
  • @Erich that's wried, I try those two array with `array_diff_assoc`, and it return what I expect... – TsaiKoga Feb 03 '20 at 02:47
  • I somehow got it working but not sure exactly why. I copied the arrays to local variables and then did `array_diff` on them, which worked. Then I switched it back to the original code, and that works now as well. – Erich Feb 03 '20 at 03:01