public function addComponent(IComponent $component, $name, $insertBefore = NULL)
{
if ($name === NULL) {
$name = $component->getName();
}
if (is_int($name)) {
$name = (string) $name;
} elseif (!is_string($name)) {
throw new Nette\InvalidArgumentException(sprintf('Component name must be integer or string, %s given.', gettype($name)));
} elseif (!preg_match('#^[a-zA-Z0-9_]+\\z#', $name)) {
throw new Nette\InvalidArgumentException("Component name must be non-empty alphanumeric string, '{$name}' given.");
}
if (isset($this->components[$name])) {
throw new Nette\InvalidStateException("Component with name '{$name}' already exists.");
}
// check circular reference
$obj = $this;
do {
if ($obj === $component) {
throw new Nette\InvalidStateException("Circular reference detected while adding component '{$name}'.");
}
$obj = $obj->getParent();
} while ($obj !== NULL);
// user checking
$this->validateChildComponent($component);
try {
if (isset($this->components[$insertBefore])) {
$tmp = [];
foreach ($this->components as $k => $v) {
if ($k === $insertBefore) {
$tmp[$name] = $component;
}
$tmp[$k] = $v;
}
$this->components = $tmp;
} else {
$this->components[$name] = $component;
}
$component->setParent($this, $name);
} catch (\Exception $e) {
unset($this->components[$name]);
// undo
throw $e;
}
return $this;
}