reset()->add(...array_values($with)); } public function add(With ...$with): WithCollection { foreach ($with as $singleWith) { $this->with[] = $singleWith; if ($singleWith->isRecursive()) { $this->recursive = true; } } return $this; } public function reset(): WithCollection { $this->recursive = false; $this->with = []; return $this; } public function isEmpty(): bool { return $this->with === []; } public function __toString(): string { if ($this->with === []) { return ''; } $parts = []; foreach ($this->getSortedParts() as $part) { $parts[] = (string)$part; } return sprintf( '%s %s', ($this->recursive ? 'WITH RECURSIVE' : 'WITH'), implode(', ', $parts) ); } /** * @return With[] */ private function getSortedParts(): array { $parts = []; foreach ($this->prepareParts() as $part) { $parts[] = $part['instance']; } return $parts; } /** * @return array */ private function prepareParts(): array { $parts = []; foreach ($this->with as $part) { $parts[$part->getName()] = [ 'instance' => $part, 'before' => [], 'after' => $part->getDependencies(), ]; } return (new DependencyOrderingService())->orderByDependencies($parts); } }