/** * Build a ContentType object * * This method takes the root (a node) of the page's content tree (records from the contents table)) * and transforms it into a corresponding tree of content elements for rendering. * * The database fields have the following meaning: * * `name` - a page-wide unique name (id) for the element. SHOULD be used as id attribute. * `content_type` - fully qualified classname of the content element. * `content_args` - constructor parameters for the content element. * `component` - name of the entity containing data for the content element. * `selection` - selection criteria for the data entity. * `params` - additional parameters for use by the layout file. * * @param Content $root * * @return ContentTypeInterface[] */ private function toContentType($root) { #echo "<pre>" . __METHOD__ . ' ' . $this->dumpEntity($root) . "\n"; #echo "Data selection: " . $root->component . ' ' . print_r($root->selection, true) . "\n"; $contentType = $root->contentType; $data = $this->findData($root->component, $root->selection); $reflector = new \ReflectionClass($contentType); $constructor = $reflector->getConstructor(); $constructorParameters = null; if (!empty($constructor)) { $constructorParameters = $constructor->getParameters(); } $all = []; foreach (array_values($data) as $index => $item) { #echo "<pre>"; #echo "Data item: " . $this->dumpEntity($item) . "\n"; /** @var AbstractContentType $content */ $providedArguments = empty($root->contentArgs) ? [] : get_object_vars($root->contentArgs); $actualArguments = []; foreach ($constructorParameters as $parameter) { $name = $parameter->getName(); $defaultValue = $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : null; if ($name == 'item') { $defaultValue = $item; } $actualArguments[$name] = isset($providedArguments[$name]) ? $providedArguments[$name] : $defaultValue; } $content = $reflector->newInstanceArgs($actualArguments); $content->setId($index == 0 ? $root->name : $root->name . '-' . $index); $content->setParameters($root->params); if (!empty($root->customCss)) { $this->output->addCss($content->getId(), $root->customCss); } #echo "Content: " . get_class($content) . "\n"; if ($content instanceof CompoundTypeInterface) { /** @noinspection PhpUndefinedFieldInspection */ foreach ($root->children as $node) { #echo "<pre>"; #echo "Child: " . $node->name . " (" . $node->contentType . ")\n"; foreach ($this->toContentType($node) as $child) { #echo "Result: " . get_class($child) . "\n"; $content->add($child); } #echo "</pre>"; } } $all[] = $content; #echo "</pre>"; } #echo "</pre>"; return $all; }