mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-27 06:04:12 +01:00
237 lines
5.5 KiB
PHP
237 lines
5.5 KiB
PHP
<?php
|
|
/*
|
|
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
|
* @license http://opensource.org/licenses/AGPL-3.0
|
|
*/
|
|
|
|
namespace Combodo\iTop\Forms\FormBuilder;
|
|
|
|
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
|
use Combodo\iTop\Forms\Block\Expression\ExpressionFormBlock;
|
|
use Combodo\iTop\Forms\Block\FormBlock;
|
|
use Combodo\iTop\Forms\Block\IO\FormBinding;
|
|
use Combodo\iTop\Forms\Block\IO\FormInput;
|
|
use Combodo\iTop\Forms\Block\IO\FormOutput;
|
|
|
|
/**
|
|
* Dependencies handler.
|
|
*
|
|
*/
|
|
class DependencyMap
|
|
{
|
|
/** @var array array of blocks impacted by dependence */
|
|
private array $aBlocksImpactedBy = [];
|
|
|
|
/** @var array array of binding */
|
|
private array $aBindings = [];
|
|
|
|
/** @var array array of binding (OUT > OUT) grouped by block and output name */
|
|
private array $aBindingsOutputToInput = [];
|
|
|
|
/** @var array array of binding (IN > IN) grouped by block and output name */
|
|
private array $aBindingsInputToInput = [];
|
|
|
|
/** @var array array of binding (OUT > OUT) grouped by block and output name */
|
|
private array $aBindingsOutputToOutputs = [];
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param array $aBlocksWithDependencies
|
|
*/
|
|
public function __construct(private readonly array $aBlocksWithDependencies)
|
|
{
|
|
// Initialization
|
|
$this->Init();
|
|
}
|
|
|
|
/**
|
|
* Initialize.
|
|
*
|
|
* @return void
|
|
*/
|
|
private function Init(): void
|
|
{
|
|
/** Iterate throw blocks with dependencies... @var AbstractFormBlock $oDependentBlock */
|
|
foreach ($this->aBlocksWithDependencies as $oDependentBlock) {
|
|
|
|
/** Iterate throw the block inputs bindings... @var FormBinding $oBinding**/
|
|
foreach ($oDependentBlock->GetBoundInputsBindings() as $oBinding) {
|
|
|
|
// OUT > IN
|
|
if($oBinding->oSourceIO instanceof FormOutput
|
|
&& $oBinding->oDestinationIO instanceof FormInput){
|
|
$this->AddBindingToMap($this->aBindingsOutputToInput, $oBinding);
|
|
$this->AddToBlockImpactedBy($oBinding->oSourceIO->GetOwnerBlock()->GetName(), $oDependentBlock);
|
|
}
|
|
|
|
// IN > IN
|
|
if($oBinding->oSourceIO instanceof FormInput
|
|
&& $oBinding->oDestinationIO instanceof FormInput){
|
|
$this->AddBindingToMap($this->aBindingsInputToInput, $oBinding);
|
|
}
|
|
|
|
}
|
|
|
|
/** Iterate throw the block inputs connections... @var FormBinding $oBinding**/
|
|
foreach ($oDependentBlock->GetBoundOutputBindings() as $oBinding) {
|
|
|
|
// OUT > OUT
|
|
if($oBinding->oSourceIO instanceof FormOutput
|
|
&& $oBinding->oDestinationIO instanceof FormOutput){
|
|
$this->AddBindingToMap($this->aBindingsOutputToOutputs, $oBinding);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Add a binding to a map.
|
|
*
|
|
* @param array $map
|
|
* @param FormBinding $oBinding
|
|
*
|
|
* @return void
|
|
*/
|
|
private function AddBindingToMap(array &$map, FormBinding $oBinding): void
|
|
{
|
|
// Binding information
|
|
$sBlockName = $oBinding->oSourceIO->GetOwnerBlock()->GetName();
|
|
$sIOName = $oBinding->oSourceIO->GetName();
|
|
|
|
// initialize map
|
|
if (!isset($map[$sBlockName])) {
|
|
$map[$sBlockName] = [];
|
|
}
|
|
if (!isset($map[$sBlockName][$sIOName])) {
|
|
$map[$sBlockName][$sIOName] = [];
|
|
}
|
|
|
|
// add to map
|
|
$map[$sBlockName][$sIOName][] = $oBinding;
|
|
$this->aBindings[] = $oBinding;
|
|
}
|
|
|
|
/**
|
|
* @param string $sDependsOnName
|
|
* @param AbstractFormBlock $oImpactedBlock
|
|
*
|
|
* @return void
|
|
*/
|
|
private function AddToBlockImpactedBy(string $sDependsOnName, AbstractFormBlock $oImpactedBlock): void
|
|
{
|
|
// Initialize array for this dependence
|
|
if(!array_key_exists($sDependsOnName, $this->aBlocksImpactedBy)){
|
|
$this->aBlocksImpactedBy[$sDependsOnName] = [];
|
|
}
|
|
|
|
// Add the block
|
|
$this->aBlocksImpactedBy[$sDependsOnName][$oImpactedBlock->GetName()] = $oImpactedBlock;
|
|
|
|
// TODO
|
|
if($oImpactedBlock instanceof ExpressionFormBlock){
|
|
foreach($oImpactedBlock->GetOutputs() as $oOutput){
|
|
foreach($oOutput->GetBindings() as $oBinding){
|
|
$this->AddToBlockImpactedBy($sDependsOnName, $oBinding->oDestinationIO->GetOwnerBlock());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function GetImpactingBlocksWithoutDependencies(): array
|
|
{
|
|
$aResult = [];
|
|
|
|
// Iterate throw binding OUT > IN
|
|
foreach(array_keys($this->aBindingsOutputToInput) as $sOutputBlockName) {
|
|
|
|
// Exclude block containing dependencies
|
|
if(!array_key_exists($sOutputBlockName, $this->aBlocksWithDependencies)){
|
|
$aResult[] = $sOutputBlockName;
|
|
}
|
|
}
|
|
|
|
return $aResult;
|
|
}
|
|
|
|
/**
|
|
* Get block impacted by a given block.
|
|
* The blocks can be filtered using a callable.
|
|
*
|
|
* @param string $sBlockName
|
|
* @param callable|null $oFilter
|
|
*
|
|
* @return array|null
|
|
*/
|
|
public function GetBlocksImpactedBy(string $sBlockName, callable $oFilter = null): ?array
|
|
{
|
|
if(!array_key_exists($sBlockName, $this->aBlocksImpactedBy)){
|
|
return null;
|
|
}
|
|
$aBlocks = $this->aBlocksImpactedBy[$sBlockName];
|
|
|
|
// Filtering
|
|
if($oFilter !== null){
|
|
$aBlocks = array_filter($aBlocks, $oFilter);
|
|
}
|
|
|
|
return $aBlocks;
|
|
}
|
|
|
|
/**
|
|
* Check if a block impacts other blocks.
|
|
*
|
|
* @param string $sBlockName
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function HasBlocksImpactedBy(string $sBlockName): bool
|
|
{
|
|
return $this->GetBlocksImpactedBy($sBlockName) !== null;
|
|
}
|
|
|
|
/**
|
|
* Get bindings OUT > IN.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function GetOutputToInputs(): array
|
|
{
|
|
return $this->aBindingsOutputToInput;
|
|
}
|
|
|
|
/**
|
|
* Get bindings IN > IN.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function GetInputToInputs(): array
|
|
{
|
|
return $this->aBindingsInputToInput;
|
|
}
|
|
|
|
/**
|
|
* Get bindings OUT > OUT.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function GetOutputToOutputs(): array
|
|
{
|
|
return $this->aBindingsOutputToOutputs;
|
|
}
|
|
|
|
/**
|
|
* Get all bindings.
|
|
*
|
|
* @return array
|
|
*/
|
|
public function GetAllBindings()
|
|
{
|
|
return $this->aBindings;
|
|
}
|
|
} |