Merge remote-tracking branch 'origin/feature/8772_form_dependencies_manager' into feature/8772_form_dependencies_manager

# Conflicts:
#	sources/Forms/Block/AbstractFormBlock.php
#	sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php
#	templates/application/forms/itop_console_layout.html.twig
This commit is contained in:
Benjamin Dalsass
2025-10-29 13:31:02 +01:00
4 changed files with 51 additions and 7 deletions

View File

@@ -102,6 +102,7 @@ abstract class Controller extends AbstractController
/** @var CsrfTokenManager Csrf manager (from Symfony form component @link https://symfony.com/doc/current/security/csrf.html) */
private CsrfTokenManager $oCsrfTokenManager;
private ?string $sContentType = null;
/**
* Controller constructor.
@@ -529,7 +530,9 @@ abstract class Controller extends AbstractController
$this->AddToPage($this->oTwig->render('application/forms/itop_error.html.twig', ['sControllerError' => $sErrorMsg]));
}
$this->ManageDebugExtensions($aParams);
if ($sPageType === 'html') {
$this->ManageDebugExtensions($aParams);
}
if (!empty($this->aAjaxTabs)) {
$this->oPage->AddTabContainer('TwigBaseTabContainer');
@@ -550,6 +553,7 @@ abstract class Controller extends AbstractController
foreach ($this->aBlockParams as $sKey => $value) {
$this->SetBlockParamToPage($sKey, $value);
}
$this->SetContentTypeToPage();
$this->OutputPage();
}
@@ -733,6 +737,17 @@ abstract class Controller extends AbstractController
$this->aBlockParams = $aBlockParams;
}
/**
* @param string $sContentType
*
* @return void
* @since 3.3.0
*/
public function SetContentType(string $sContentType): void
{
$this->sContentType = $sContentType;
}
/**
* @since 2.7.7 3.0.1 3.1.0 N°4760 method creation
* @see Controller::SetBreadCrumbEntry() to set breadcrumb content (by default will be title)
@@ -934,6 +949,15 @@ abstract class Controller extends AbstractController
$this->oPage->AddAjaxTab($sCode, $sURL, $bCache, $sTitle);
}
private function SetContentTypeToPage(): void
{
if (!is_null($this->sContentType)) {
$this->oPage->SetContentType($this->sContentType);
}
}
/**
* @param string $sKey
* @param $value

View File

@@ -149,8 +149,8 @@ abstract class AbstractFormBlock
*/
public function GetInput(string $sName): FormInput
{
if(!array_key_exists($sName, $this->aFormInputs)) {
throw new FormBlockException('Missing input ' . $sName . ' for ' . $this->sName);
if (!array_key_exists($sName, $this->aFormInputs)) {
throw new FormBlockException('Missing input '.$sName.' for '.$this->sName);
}
return $this->aFormInputs[$sName];
@@ -182,8 +182,8 @@ abstract class AbstractFormBlock
*/
public function GetOutput(string $sName): FormOutput
{
if(!array_key_exists($sName, $this->aFormOutputs)) {
throw new FormBlockException('Missing output ' . $sName . ' for ' . $this->sName);
if (!array_key_exists($sName, $this->aFormOutputs)) {
throw new FormBlockException('Missing output '.$sName.' for '.$this->sName);
}
return $this->aFormOutputs[$sName];
@@ -279,6 +279,7 @@ abstract class AbstractFormBlock
return true;
}
}
return false;
}
@@ -313,6 +314,7 @@ abstract class AbstractFormBlock
$aBindings[$oFormInput->GetName()] = $oFormInput->GetBinding();
}
}
return $aBindings;
}
@@ -343,7 +345,7 @@ abstract class AbstractFormBlock
{
foreach ($this->aFormInputs as $oFormInput) {
if ($oFormInput->IsBound()) {
if(!$oFormInput->IsDataReady()) {
if (!$oFormInput->IsDataReady()) {
return false;
}
}
@@ -374,6 +376,16 @@ abstract class AbstractFormBlock
$this->bIsAddedToForm = $bIsAdded;
}
public function ListBlockNames(): array
{
$aNames = [];
foreach ($this->aSubFormBlocks as $oSubFormBlock) {
$aNames[] = $oSubFormBlock->GetName();
}
return $aNames;
}
/**
* Compute outputs values.
*

View File

@@ -95,7 +95,7 @@ class AttributeValueChoiceFormBlock extends ChoiceFormBlock
if($aValues === null)
return $aOptions;
$aOptions['choices'] = array_flip($aValues);
$aOptions['choices'] = array_flip($aValues ?? []);
return $aOptions;
}

View File

@@ -20,6 +20,14 @@
{{- parent() -}}
{%- endblock form_label -%}
{%- block form_rows -%}
{% for sId,child in form|filter(child => not child.rendered) %}
<div id="block_{{ sId }}" class="ibo-field ibo-content-block ibo-block ibo-field-small">
{{ form_row(child) }}
</div>
{% endfor %}
{%- endblock form_rows -%}
{%- block form_label_content -%}
{{- parent() -}}
{% if with_ai_button is defined and with_ai_button %}