diff --git a/datamodels/2.x/itop-portal-base/portal/src/controllers/objectcontroller.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/controllers/objectcontroller.class.inc.php index b6b677349..e1312c60e 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/controllers/objectcontroller.class.inc.php +++ b/datamodels/2.x/itop-portal-base/portal/src/controllers/objectcontroller.class.inc.php @@ -825,6 +825,12 @@ class ObjectController extends AbstractController $sTargetObjectClass = $oRemoteAttDef->GetTargetClass(); } } + elseif ($oTargetAttDef->GetEditClass() === 'CustomFields') + { + $oRequestTemplate = $oHostObject->Get($sTargetAttCode); + $oTemplateFieldSearch = $oRequestTemplate->GetForm()->GetField('user_data')->GetForm()->GetField($sFieldId)->GetSearch(); + $sTargetObjectClass = $oTemplateFieldSearch->GetClass(); + } else { throw new Exception('Search from attribute can only apply on AttributeExternalKey or AttributeLinkedSet objects, ' . get_class($oTargetAttDef) . ' given.'); @@ -840,9 +846,11 @@ class ObjectController extends AbstractController } // - Retrieving scope search + // Note : This do NOT apply to custom fields as the portal administrator is not supposed to know which objects will be put in the templates. + // It is the responsability of the template designer to write the right query so the user see only what he should. $oScopeSearch = $oApp['scope_validator']->GetScopeFilterForProfiles(UserRights::ListProfiles(), $sTargetObjectClass, UR_ACTION_READ); $aInternalParams = array(); - if ($oScopeSearch === null) + if (($oScopeSearch === null) && ($oTargetAttDef->GetEditClass() !== 'CustomFields')) { IssueLog::Info(__METHOD__ . ' at line ' . __LINE__ . ' : User #' . UserRights::GetUserId() . ' has no scope query for ' . $sTargetObjectClass . ' class.'); $oApp->abort(404, Dict::S('UI:ObjectDoesNotExist')); @@ -857,6 +865,11 @@ class ObjectController extends AbstractController { $oSearch = $oScopeSearch; } + elseif ($oTargetAttDef->GetEditClass() === 'CustomFields') + { + // Note : $oTemplateFieldSearch has been defined in the "Retrieving target object class from attcode" part, it is not available otherwise + $oSearch = $oTemplateFieldSearch; + } // - Filtering objects to ignore if (($aObjectIdsToIgnore !== null) && (is_array($aObjectIdsToIgnore))) @@ -869,7 +882,7 @@ class ObjectController extends AbstractController } $oSearch->AddConditionExpression(new BinaryExpression(new FieldExpression('id', $oSearch->GetClassAlias()), 'NOT IN', new ListExpression($aExpressions))); } - + // - Adding query condition $aInternalParams['this'] = $oHostObject; if ($sQuery !== null) @@ -898,7 +911,12 @@ class ObjectController extends AbstractController } // - Intersecting with scope constraints - $oSearch = $oSearch->Intersect($oScopeSearch); + // Note : This do NOT apply to custom fields as the portal administrator is not supposed to know which objects will be put in the templates. + // It is the responsability of the template designer to write the right query so the user see only what he should. + if (($oScopeSearch !== null) && ($oTargetAttDef->GetEditClass() !== 'CustomFields')) + { + $oSearch = $oSearch->Intersect($oScopeSearch); + } // Retrieving results // - Preparing object set @@ -976,7 +994,7 @@ class ObjectController extends AbstractController 'sFormManagerData' => $sFormManagerData ) ); - + if ($oRequest->isXmlHttpRequest()) { $oResponse = $oApp['twig']->render('itop-portal-base/portal/src/views/bricks/object/modal.html.twig', $aData); diff --git a/datamodels/2.x/itop-portal-base/portal/src/forms/objectformmanager.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/forms/objectformmanager.class.inc.php index abbd87ca0..212cb71ed 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/forms/objectformmanager.class.inc.php +++ b/datamodels/2.x/itop-portal-base/portal/src/forms/objectformmanager.class.inc.php @@ -516,6 +516,38 @@ class ObjectFormManager extends FormManager $oField->SetInformationEndpoint($this->oApp['url_generator']->generate('p_object_get_informations_json')); } } + // - Field that require processing on their subfields + if (in_array(get_class($oField), array('Combodo\\iTop\\Form\\Field\\SubFormField'))) + { + $oSubForm = $oField->GetForm(); + if ($oAttDef->GetEditClass() === 'CustomFields') + { + // Retrieving only user data fields (not the metadata fields of the template) + if ($oSubForm->HasField('user_data')) + { + $oUserDataField = $oSubForm->GetField('user_data'); + $oUserDataForm = $oUserDataField->GetForm(); + foreach ($oUserDataForm->GetFields() as $oCustomField) + { + // - Field that require a search endpoint (OQL based dropdown list fields) + if (in_array(get_class($oCustomField), array('Combodo\\iTop\\Form\\Field\\SelectObjectField'))) + { + if ($this->oApp !== null) + { + + $sSearchEndpoint = $this->oApp['url_generator']->generate('p_object_search_generic', array( + 'sTargetAttCode' => $oAttDef->GetCode(), + 'sHostObjectClass' => get_class($this->oObject), + 'sHostObjectId' => ($this->oObject->IsNew()) ? null : $this->oObject->GetKey(), + 'ar_token' => $this->GetActionRulesToken(), + )); + $oCustomField->SetSearchEndpoint($sSearchEndpoint); + } + } + } + } + } + } } else { diff --git a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_search_regular.html.twig b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_search_regular.html.twig index c7f0198ca..a7dcbd2b0 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_search_regular.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/object/mode_search_regular.html.twig @@ -152,6 +152,8 @@ "url": "{{ app.url_generator.generate('p_object_search_from_attribute', {'sTargetAttCode': sTargetAttCode, 'sHostObjectClass': sHostObjectClass, 'sHostObjectId': sHostObjectId, 'ar_token': sActionRulesToken})|raw }}", "type": "POST", "data": function(d){ + d.sFormPath = '{{ aSource.sFormPath }}'; + d.sFieldId = '{{ aSource.sFieldId }}'; d.aObjectIdsToIgnore = {{ aSource.aObjectIdsToIgnore|json_encode()|raw }}; d.iPageNumber = Math.floor(d.start/d.length) + 1; d.iCountPerPage = d.length; diff --git a/sources/form/form.class.inc.php b/sources/form/form.class.inc.php index 4d9ff4738..3687449ec 100644 --- a/sources/form/form.class.inc.php +++ b/sources/form/form.class.inc.php @@ -243,7 +243,7 @@ class Form { if (!array_key_exists($sId, $this->aFields)) { - throw new Exception('Field with ID "' . $sId . '" was not found in the Form.'); + throw new Exception('Field with ID "' . $sId . '" was not found in the Form of ID "' . $this->sId . '".'); } return $this->aFields[$sId]; }