/** * Creates a component corresponding to the specified tag and optionally sets its published properties. * * <p>This is called by the parser. * * @param string $tagName It may contain an XML namespace prefix, ex: 'x:tag' * @param Component $parent The component's container component. * @param string[] $props A map of property names to property values. * Properties specified via this argument come only from markup attributes, not * from subtags. * @param array|null $bindings A map of attribute names and corresponding databinding expressions. * @param bool $generic If true, an instance of GenericComponent is created. * @param boolean $strict If true, failure to find a component class will throw an exception. * If false, an attempt is made to load a macro with the same name, * @return Component Component instance. For macros, an instance of Macro is returned. * @throws ComponentException * @throws MatisseException */ function createComponentFromTag($tagName, Component $parent, array $props = null, array $bindings = null, $generic = false, $strict = false) { $s = explode(':', $tagName, 2); if (count($s) > 1) { list($prefix, $tagName) = $s; } else { $prefix = ''; } if ($prefix) { throw new MatisseException("XML namespaces are not yet supported.<p>Tag: <kbd><<b>{$prefix}:</b>{$tagName}></kbd>"); } if ($generic) { $component = new GenericHtmlComponent($tagName, $props); return $component; } $class = $this->getClassForTag($tagName); /** @var DocumentContext $this */ if (!$class) { if ($strict) { Component::throwUnknownComponent($this, $tagName, $parent); } // Component class not found. // Convert the tag to a MacroInstance component instance that will attempt to load a macro with the same // name as the tag name. if (is_null($props)) { $props = []; } $props['macro'] = $tagName; $component = new MacroCall(); } else { $component = $this->injector->make($class); } // For both types of components: if (!$component instanceof Component) { throw new ComponentException(null, sprintf("Class <kbd>%s</kbd> is not a subclass of <kbd>Component</kbd>", get_class($component))); } $component->setTagName($tagName); return $component->setup($parent, $this, $props, $bindings); }