$val) { if (!in_array($key, self::$entityKeys)) { continue; } if ('type' === $key && self::TYPE_MOVIE !== $val && self::TYPE_EPISODE !== $val) { throw new RuntimeException( sprintf( 'Unexpected type value was given. Was expecting \'%1$s or %2$s\' but got \'%3$s\' instead.', self::TYPE_MOVIE, self::TYPE_EPISODE, $val ) ); } if ('meta' === $key && is_string($val)) { if (null === ($val = json_decode($val, true))) { $val = []; } } $this->{$key} = $val; } $this->data = $this->getAll(); } public function diff(): array { $changed = []; foreach ($this->getAll() as $key => $value) { /** * We ignore meta on purpose as it changes frequently. * from one server to another. */ if ('meta' === $key) { continue; } if ($value === ($this->data[$key] ?? null)) { continue; } $changed['new'][$key] = $value ?? 'None'; $changed['old'][$key] = $this->data[$key] ?? 'None'; } return $changed; } public function getAll(): array { return array_intersect_key((array)$this, array_flip(self::$entityKeys)); } public function isChanged(): bool { return count($this->diff()) >= 1; } public function hasGuids(): bool { foreach ($this->getAll() as $key => $val) { if (null !== $this->{$key} && str_starts_with($key, 'guid_')) { return true; } } return false; } public function apply(StateEntity $entity, bool $guidOnly = false): self { if ($this->isEqual($entity)) { return $this; } foreach ($entity->getAll() as $key => $val) { if (true === $guidOnly && !str_starts_with($key, 'guid_')) { continue; } $this->updateValue($key, $entity); } return $this; } private function isEqual(StateEntity $entity): bool { foreach ($this->getAll() as $key => $val) { $checkedValue = $this->isEqualValue($key, $entity); if (false === $checkedValue) { return false; } } return true; } private function isEqualValue(string $key, StateEntity $entity): bool { if ($key === 'updated' || $key === 'watched') { return !($entity->updated > $this->updated && $entity->watched !== $this->watched); } if (null !== ($entity->{$key} ?? null) && $this->{$key} !== $entity->{$key}) { return false; } return true; } private function updateValue(string $key, StateEntity $entity): void { if ($key === 'updated' || $key === 'watched') { if ($entity->updated > $this->updated && $entity->watched !== $this->watched) { $this->updated = $entity->updated; $this->watched = $entity->watched; } return; } if (null !== ($entity->{$key} ?? null) && $this->{$key} !== $entity->{$key}) { $this->{$key} = $entity->{$key}; } } public static function getEntityKeys(): array { return self::$entityKeys; } }