BuildForm(); } catch (Exception $e) { throw new FormBlockException('Unable to construct form', 0, $e); } } /** @inheritdoc */ public function GetFormType(): string { return FormType::class; } /** @inheritdoc */ protected function RegisterOptions(OptionsRegister $oOptionsRegister): void { parent::RegisterOptions($oOptionsRegister); $oOptionsRegister->SetOption('compound', true); $oOptionsRegister->SetOptionArrayValue('attr', 'class', 'form'); } /** * Add a child form. * * @param string $sName block name * @param string $sBlockClass block class name * @param array $aOptions options * * @return $this * @throws ReflectionException * @throws FormBlockException */ public function Add(string $sName, string $sBlockClass, array $aOptions = []): AbstractFormBlock { $this->VerifyBlockName($sName); $this->VerifyBlockClassName($sBlockClass); $aOptions['priority'] = -count($this->aChildrenBlocks); $oSubFormBlock = new ($sBlockClass)($sName, $aOptions); $this->aChildrenBlocks[$sName] = $oSubFormBlock; $oSubFormBlock->SetParent($this); return $oSubFormBlock; } /** * @param string $sBlockName * * @return void * @throws FormBlockException */ private function VerifyBlockName(string $sBlockName): void { if (!ctype_alnum(str_replace(['-', '_'], '', $sBlockName))) { throw new FormBlockException("Block name '$sBlockName' is not valid. Only alphanumeric characters, hyphens and underscores are allowed."); } } /** * @param string $sBlockClass * * @return void * @throws FormBlockException * @throws ReflectionException */ private function VerifyBlockClassName(string $sBlockClass): void { $oRef = new ReflectionClass($sBlockClass); if ($oRef->isSubclassOf(AbstractFormBlock::class) === false) { throw new FormBlockException("The block type '$sBlockClass' is not a subclass of AbstractFormBlock."); } } /** * Get the children forms. * * @return array */ public function GetChildren(): array { return $this->aChildrenBlocks; } /** * Return a child block. * * @param string $sName name of the block * * @return AbstractFormBlock */ public function Get(string $sName): AbstractFormBlock { return $this->aChildrenBlocks[$sName]; } /** * Build the form. * * @return void */ protected function BuildForm(): void { } public function GetSubFormBlock(string $sBlockTurboTriggerName): ?AbstractFormBlock { $oBlock = $this; if (preg_match_all('/\[(?[^\[]+)\]/', $sBlockTurboTriggerName, $aMatches)) { foreach ($aMatches['level'] as $level) { $oBlock = $oBlock->Get($level); } } return $oBlock; } public function GetDependenciesMap(): ?DependencyMap { return $this->oDependencyMap; } }