*/ class Engine { /** * Compiler for processing documents. * * @var \App\Engine\ICompile */ protected $compile; /** * Serializer to convert documents back to whatever line/disk format we * want. * * @var \App\Serialize\ISerialize */ protected $serialize; /** * Unserializer to convert line/disk format documents into documents. * * @var \App\Serialize\IUnserialize */ protected $unserialize; /** * Represents the current document state after any operations called. * * @var \App\Dom\Document */ protected $document; /** * Process a domdocument, applying some higher level operations such as * stacking documents. * * @param string $input_file * @param IOptions $options * @return string */ public function process(string $input_file, IOptions $options): string { $file_helper = new File([dirname(realpath($input_file))]); $files = [$input_file]; $processed = []; for ($i = 0; $i < sizeof($files); $i++) { $document = $this->unserialize->unserialize(file_get_contents($file_helper->resolve($files[$i]))); if (!in_array($files[$i], $processed)) { $additional_files = []; try { $additional_files = $document->getMeta('stack'); } catch (\Exception $ex) { } if (sizeof($additional_files)) { $processed[] = $files[$i]; array_splice($files, $i, 0, $additional_files); $i -= sizeof($additional_files); continue; } } echo '=> '.$files[$i].PHP_EOL; $this->compileDocument($document, $options); } return $this->getOutput(); } /** * Set the compiler to use. * * @param ICompile $compiler * @return Engine */ public function setCompiler(ICompile $compiler): Engine { $this->compile = $compiler; return $this; } /** * Set the serializer to use. * * @param \App\Serialize\ISerialize $serializer * @return Engine */ public function setSerializer(\App\Serialize\ISerialize $serializer): Engine { $this->serialize = $serializer; return $this; } /** * Set the unserializer to use. * * @param \App\Serialize\IUnserialize $unserializer * @return Engine */ public function setUnserializer(\App\Serialize\IUnserialize $unserializer): Engine { $this->unserialize = $unserializer; return $this; } /** * Set the initial compiler state. * * @param \App\Dom\Document $document * @return Engine */ public function setInputDocument(\App\Dom\Document $document): Engine { $this->document = $document; $this->compile->setDocument($document); return $this; } /** * Set the initial compiler state from a serialized string. * * @param string $document_string * @return Engine */ public function setInput(string $document_string): Engine { $document = $this->unserialize->unserialize($document_string); $this->setInputDocument($document); return $this; } /** * Compile a new document, mutating current state. * * @param string $document_string * @param IOptions $options * @return Engine */ public function compile(string $document_string, IOptions $options): Engine { $document = $this->unserialize->unserialize($document_string); $this->compileDocument($document, $options); return $this; } /** * Compile a new document, mutating current state. * * @param \App\Dom\Document $document * @param IOptions $options * @return Engine */ public function compileDocument(\App\Dom\Document $document, IOptions $options): Engine { $this->compile->compile($document, $options); return $this; } /** * Get the document state after all applied compile() calls. * * @return \App\Dom\Document */ public function getOutputDocument(): \App\Dom\Document { return $this->compile->getDocument(); } /** * Get the document state after all applied compile() calls and serialize * it, returning line/disk format. * * @return string */ public function getOutput(): string { $document = $this->getOutputDocument(); return $this->serialize->serialize($document); } }