mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-23 02:28:44 +02:00
- Form SDK implementation - Basic Forms - Dynamics Forms - Basic Blocks + Data Model Block - Form Compilation - Turbo integration
405 lines
9.3 KiB
PHP
405 lines
9.3 KiB
PHP
<?php
|
|
|
|
/*
|
|
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
|
* @license http://opensource.org/licenses/AGPL-3.0
|
|
*/
|
|
|
|
namespace Combodo\iTop\Forms\Register;
|
|
|
|
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
|
use Combodo\iTop\Forms\Block\Expression\AbstractExpressionFormBlock;
|
|
use Combodo\iTop\Forms\Block\FormBlockException;
|
|
use Combodo\iTop\Forms\Block\FormBlockHelper;
|
|
use Combodo\iTop\Forms\IO\Converter\AbstractConverter;
|
|
use Combodo\iTop\Forms\IO\FormBlockIOException;
|
|
use Combodo\iTop\Forms\IO\FormInput;
|
|
use Combodo\iTop\Forms\IO\FormOutput;
|
|
|
|
/**
|
|
* IO register.
|
|
*
|
|
* @package Combodo\iTop\Forms\Register
|
|
* @since 3.3.0
|
|
*/
|
|
class IORegister
|
|
{
|
|
/** @var array */
|
|
private array $aInputs = [];
|
|
|
|
/** @var array */
|
|
private array $aOutputs = [];
|
|
|
|
/**
|
|
* @param AbstractFormBlock $oFormBlock
|
|
*/
|
|
public function __construct(private readonly AbstractFormBlock $oFormBlock)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* @param string $sName
|
|
* @param string $sType
|
|
* @param bool $bIsArray
|
|
*
|
|
* @return $this
|
|
* @throws FormBlockIOException
|
|
* @throws RegisterException
|
|
*/
|
|
public function AddInput(string $sName, string $sType, bool $bIsArray = false): self
|
|
{
|
|
$oFormInput = new FormInput($sName, $sType, $bIsArray);
|
|
$oFormInput->SetOwnerBlock($this->oFormBlock);
|
|
if (array_key_exists($oFormInput->GetName(), $this->aInputs)) {
|
|
throw new RegisterException('Input already exists '.json_encode($oFormInput->GetName()).' for '.json_encode($this->oFormBlock->GetName()));
|
|
}
|
|
$this->aInputs[$oFormInput->GetName()] = $oFormInput;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Add an input connected to another block.
|
|
*
|
|
* @param string $sName the input name
|
|
* @param string $sOutputBlockName
|
|
* @param string $sOutputName
|
|
*
|
|
* @return $this
|
|
* @throws FormBlockException
|
|
* @throws FormBlockIOException
|
|
* @throws RegisterException
|
|
*/
|
|
public function AddInputDependsOn(string $sName, string $sOutputBlockName, string $sOutputName): self
|
|
{
|
|
$oOutputBlock = $this->oFormBlock->GetParent()->Get($sOutputBlockName);
|
|
$oBlockOutput = $oOutputBlock->GetOutput($sOutputName);
|
|
|
|
$this->AddInput($sName, $oBlockOutput->GetDataType(), $oBlockOutput->IsArray());
|
|
$this->InputDependsOn($sName, $sOutputBlockName, $sOutputName);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Attach an input to a block output.
|
|
*
|
|
* @param string $sInputName the input name
|
|
* @param string $sOutputBlockName the dependency block name
|
|
* @param string $sOutputName the dependency output name
|
|
*
|
|
* @return $this
|
|
* @throws FormBlockException
|
|
* @throws FormBlockIOException
|
|
* @throws RegisterException
|
|
*/
|
|
public function InputDependsOn(string $sInputName, string $sOutputBlockName, string $sOutputName): self
|
|
{
|
|
$oOutputBlock = $this->oFormBlock->GetParent()?->Get($sOutputBlockName);
|
|
if (is_null($oOutputBlock)) {
|
|
throw new RegisterException('Output block not found '.json_encode($sOutputBlockName));
|
|
}
|
|
$oFormInput = $this->GetInput($sInputName);
|
|
$oFormOutput = $oOutputBlock->GetOutput($sOutputName);
|
|
$oFormOutput->BindToInput($oFormInput);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Attach an output to a parent block output.
|
|
*
|
|
* @param string $sOutputName output name
|
|
* @param string $sParentOutputName parent output name
|
|
*
|
|
* @return $this
|
|
* @throws FormBlockIOException
|
|
* @throws RegisterException
|
|
*/
|
|
public function OutputImpactParent(string $sOutputName, string $sParentOutputName): self
|
|
{
|
|
$oFormOutput = $this->GetOutput($sOutputName);
|
|
$oParentFormOutput = $this->oFormBlock->GetParent()->GetOutput($sParentOutputName);
|
|
$oFormOutput->BindToOutput($oParentFormOutput);
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string $sName
|
|
* @param string $sType
|
|
* @param bool $bIsArray
|
|
* @param AbstractConverter|null $oConverter
|
|
*
|
|
* @return void
|
|
* @throws FormBlockIOException
|
|
* @throws RegisterException
|
|
*/
|
|
public function AddOutput(string $sName, string $sType, bool $bIsArray = false, AbstractConverter $oConverter = null): void
|
|
{
|
|
$oFormOutput = new FormOutput($sName, $sType, $bIsArray, $oConverter);
|
|
$oFormOutput->SetOwnerBlock($this->oFormBlock);
|
|
if (array_key_exists($oFormOutput->GetName(), $this->aOutputs)) {
|
|
throw new RegisterException('Output already exists '.json_encode($oFormOutput->GetName()).' for '.json_encode($this->oFormBlock->GetName()).' in block '.FormBlockHelper::GetFormId($this->oFormBlock).' of class '.get_class($this->oFormBlock));
|
|
}
|
|
$this->aOutputs[$oFormOutput->GetName()] = $oFormOutput;
|
|
}
|
|
|
|
/**
|
|
* Get an input.
|
|
*
|
|
* @param string $sName
|
|
*
|
|
* @return FormInput
|
|
* @throws RegisterException
|
|
*/
|
|
public function GetInput(string $sName): FormInput
|
|
{
|
|
if (!$this->HasInput($sName)) {
|
|
throw new RegisterException('Missing input '.json_encode($sName).' for '.json_encode($this->oFormBlock->GetName()));
|
|
}
|
|
|
|
return $this->aInputs[$sName];
|
|
}
|
|
|
|
/**
|
|
* Test input existence.
|
|
*
|
|
* @param string $sName
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function HasInput(string $sName): bool
|
|
{
|
|
return array_key_exists($sName, $this->aInputs);
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function GetInputs(): array
|
|
{
|
|
return $this->aInputs;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function GetBoundInputs(): array
|
|
{
|
|
$aInputs = [];
|
|
|
|
/** @var FormInput $oFormInput */
|
|
foreach ($this->aInputs as $oFormInput) {
|
|
if ($oFormInput->IsBound() || $oFormInput->HasBindingOut()) {
|
|
$aInputs[] = $oFormInput;
|
|
}
|
|
}
|
|
|
|
return $aInputs;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function GetBoundOutputs(): array
|
|
{
|
|
$aOutputs = [];
|
|
|
|
/** @var FormOutput $oFormOutput */
|
|
foreach ($this->aOutputs as $oFormOutput) {
|
|
if ($oFormOutput->IsBound() || $oFormOutput->HasBindingOut()) {
|
|
$aOutputs[] = $oFormOutput;
|
|
}
|
|
}
|
|
|
|
return $aOutputs;
|
|
}
|
|
|
|
/**
|
|
* Get an output.
|
|
*
|
|
* @param string $sName output name
|
|
*
|
|
* @return FormOutput
|
|
* @throws RegisterException
|
|
*/
|
|
public function GetOutput(string $sName): FormOutput
|
|
{
|
|
if (!array_key_exists($sName, $this->aOutputs)) {
|
|
throw new RegisterException('Missing output '.json_encode($sName).' for '.json_encode($this->oFormBlock->GetName()));
|
|
}
|
|
|
|
return $this->aOutputs[$sName];
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function GetOutputs(): array
|
|
{
|
|
return $this->aOutputs;
|
|
}
|
|
|
|
/**
|
|
* Check existence of one or more dependencies.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function HasDependenciesBlocks(): bool
|
|
{
|
|
foreach ($this->aInputs as $oFormInput) {
|
|
if ($oFormInput->IsBound()) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check existence of one or more dependents blocks.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function IsImpactingBlocks(): bool
|
|
{
|
|
/** @var FormOutput $oFormOutput */
|
|
foreach ($this->aOutputs as $oFormOutput) {
|
|
if (count($oFormOutput->GetBindings()) > 0) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Return the dependencies blocks.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function GetImpactedBlocks(): array
|
|
{
|
|
$aBlocks = [];
|
|
|
|
/** @var FormInput $oFormInput */
|
|
foreach ($this->aInputs as $oFormInput) {
|
|
if ($oFormInput->IsBound()) {
|
|
$oBlock = $oFormInput->GetBinding()->oSourceIO->GetOwnerBlock();
|
|
|
|
if ($oBlock instanceof AbstractExpressionFormBlock) {
|
|
foreach ($oBlock->GetBoundInputs() as $oExpressionFormInput) {
|
|
$oBlock = $oExpressionFormInput->GetBinding()->oSourceIO->GetOwnerBlock();
|
|
$sId = FormBlockHelper::GetFormId($oBlock);
|
|
$aBlocks[$sId] = $oBlock;
|
|
}
|
|
}
|
|
|
|
$sId = FormBlockHelper::GetFormId($oBlock);
|
|
$aBlocks[$sId] = $oBlock;
|
|
}
|
|
}
|
|
|
|
return $aBlocks;
|
|
}
|
|
|
|
/**
|
|
* Get bound inputs bindings.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function GetBoundInputsBindings(): array
|
|
{
|
|
$aBindings = [];
|
|
|
|
/** @var FormInput $oFormInput */
|
|
foreach ($this->aInputs as $oFormInput) {
|
|
if ($oFormInput->IsBound()) {
|
|
$aBindings[$oFormInput->GetName()] = $oFormInput->GetBinding();
|
|
}
|
|
}
|
|
|
|
return $aBindings;
|
|
}
|
|
|
|
/**
|
|
* Get bound outputs bindings.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function GetBoundOutputBindings(): array
|
|
{
|
|
$aBindings = [];
|
|
|
|
/** @var FormInput $oFormInput */
|
|
foreach ($this->aOutputs as $oFormOutput) {
|
|
if ($oFormOutput->IsBound()) {
|
|
$aBindings[$oFormOutput->GetName()] = $oFormOutput->GetBinding();
|
|
}
|
|
}
|
|
|
|
return $aBindings;
|
|
}
|
|
|
|
/**
|
|
* Inputs data ready.
|
|
*
|
|
* @param string|null $sType
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function IsInputsDataReady(string $sType = null): bool
|
|
{
|
|
foreach ($this->aInputs as $oFormInput) {
|
|
if ($oFormInput->IsBound()) {
|
|
if (!$oFormInput->IsEventDataReady($sType)) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Compute outputs values.
|
|
*
|
|
* @param string $sEventType
|
|
* @param mixed $oData
|
|
*
|
|
* @return void
|
|
*/
|
|
public function ComputeOutputs(string $sEventType, mixed $oData): void
|
|
{
|
|
/** Iterate throw output @var FormOutput $oFormOutput */
|
|
foreach ($this->aOutputs as $oFormOutput) {
|
|
|
|
// Compute the output value
|
|
$oFormOutput->ComputeValue($sEventType, $oData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Attach an input to a parent block input.
|
|
*
|
|
* @param string $sInputName input name
|
|
* @param string $sParentInputName parent input name
|
|
*
|
|
* @return $this
|
|
* @throws FormBlockException
|
|
* @throws FormBlockIOException
|
|
* @throws RegisterException
|
|
*/
|
|
public function InputDependsOnParent(string $sInputName, string $sParentInputName): self
|
|
{
|
|
$oFormInput = $this->GetInput($sInputName);
|
|
$oParentFormInput = $this->oFormBlock->GetParent()->GetInput($sParentInputName);
|
|
$oParentFormInput->BindToInput($oFormInput);
|
|
|
|
return $this;
|
|
}
|
|
}
|