IsHandlingXmlHttpRequest()) { throw new CoreException('LinksetController can only be called in ajax.'); } $oPage = new JsonPage(); $sErrorMessage = null; $bOperationSuccess = false; // retrieve parameters $sLinkedObjectClass = utils::ReadParam('linked_object_class', '', false, utils::ENUM_SANITIZATION_FILTER_CLASS); $sLinkedObjectObjectKey = utils::ReadParam('linked_object_key', 0, false, utils::ENUM_SANITIZATION_FILTER_STRING); $sTransactionId = utils::ReadParam('transaction_id', null, false, utils::ENUM_SANITIZATION_FILTER_TRANSACTION_ID); // check transaction id if (utils::IsTransactionValid($sTransactionId, false)) { try { $oDeletionPlan = MetaModel::GetObject($sLinkedObjectClass, $sLinkedObjectObjectKey)->DBDelete(); $bOperationSuccess = (count($oDeletionPlan->GetIssues()) === 0); if (!$bOperationSuccess) { $sErrorMessage = json_encode($oDeletionPlan->GetIssues()); } } catch (Exception $e) { $sErrorMessage = $e->getMessage(); } } else { $sErrorMessage = 'invalid transaction id'; } $oPage->SetData([ 'success' => $bOperationSuccess, 'error_message' => $sErrorMessage, ]); return $oPage; } /** * OperationDetachLinkedObject. * * @return \JsonPage * @throws \CoreException */ public function OperationDetachLinkedObject(): JsonPage { if (!$this->IsHandlingXmlHttpRequest()) { throw new CoreException('LinksetController can only be called in ajax.'); } $oPage = new JsonPage(); $sErrorMessage = null; $bOperationSuccess = false; // retrieve parameters $sLinkedObjectClass = utils::ReadParam('linked_object_class', '', false, utils::ENUM_SANITIZATION_FILTER_CLASS); $sLinkedObjectKey = utils::ReadParam('linked_object_key', 0, false, utils::ENUM_SANITIZATION_FILTER_STRING); $sExternalKeyAttCode = utils::ReadParam('external_key_att_code', null, false, utils::ENUM_SANITIZATION_FILTER_STRING); $sTransactionId = utils::ReadParam('transaction_id', null, false, utils::ENUM_SANITIZATION_FILTER_TRANSACTION_ID); // check transaction id if (utils::IsTransactionValid($sTransactionId, false)) { try { $oLinkedObject = MetaModel::GetObject($sLinkedObjectClass, $sLinkedObjectKey); $oLinkedObject->Set($sExternalKeyAttCode, null); $oLinkedObject->DBWrite(); $bOperationSuccess = true; } catch (Exception $e) { $sErrorMessage = $e->getMessage(); } } else { $sErrorMessage = 'invalid transaction id'; } $oPage->SetData([ 'success' => $bOperationSuccess, 'error_message' => $sErrorMessage, ]); return $oPage; } /** * @return \AjaxPage Create edit form in its webpage * @throws \ApplicationException * @throws \ArchivedObjectException * @throws \CoreException * @throws \SecurityException */ public function OperationCreateLinkedObject(): AjaxPage { if (!$this->IsHandlingXmlHttpRequest()) { throw new CoreException('LinksetController can only be called in ajax.'); } $oRouter = Router::GetInstance(); $oPage = new AjaxPage(''); $sProposedRealClass = utils::ReadParam('class', '', false, 'class'); $sAttCode = utils::ReadParam('att_code', '', false, 'raw'); $sClass = utils::ReadParam('host_class', '', false, 'class'); $sId = utils::ReadParam('host_id', '', false, 'integer'); $sFormTitle = utils::ReadPostedParam('form_title', null, utils::ENUM_SANITIZATION_FILTER_STRING); // For security reasons: check that the "proposed" class is actually a subclass of the linked class // and that the current user is allowed to create objects of this class $sRealClass = ''; $aSubClasses = MetaModel::EnumChildClasses($sProposedRealClass, ENUM_CHILD_CLASSES_ALL); // Including the specified class itself $aPossibleClasses = array(); foreach ($aSubClasses as $sCandidateClass) { if (!MetaModel::IsAbstract($sCandidateClass) && (UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES)) { if ($sCandidateClass == $sProposedRealClass) { $sRealClass = $sProposedRealClass; } $aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass); } } // Only one of the subclasses can be instantiated... if (count($aPossibleClasses) == 1) { $aKeys = array_keys($aPossibleClasses); $sRealClass = $aKeys[0]; } if ($sRealClass != '') { $oLinksetDef = MetaModel::GetAttributeDef($sClass, $sAttCode); $sExtKeyToMe = $oLinksetDef->GetExtKeyToMe(); $aFieldFlags = array($sExtKeyToMe => OPT_ATT_READONLY); $oObj = DBObject::MakeDefaultInstance($sRealClass); $oSourceObj = MetaModel::GetObject($sClass, $sId); $oObj->Set($sExtKeyToMe, $sId); $aPrefillParam = array('source_obj' => $oSourceObj); $oObj->PrefillForm('creation_from_editinplace', $aPrefillParam); // We display this form in a modal, once we submit (in ajax) we probably want to only close the modal $sFormOnSubmitJsCode = << true, 'hide_transitions' => true, 'formPrefix' => $sAttCode, 'fieldsFlags' => $aFieldFlags, 'forceFieldsSubmission' => [ $sExtKeyToMe, ], 'form_title' => $sFormTitle, 'custom_button' => \Dict::S('UI:Button:Add'), 'js_handlers' => [ 'form_on_submit' => $sFormOnSubmitJsCode, 'cancel_button_on_click' => <<AddUiBlock(FormHelper::GetAlertForMandatoryAttributeBlobInputsInModal(FormHelper::ENUM_MANDATORY_BLOB_MODE_CREATE)); } cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aExtraParams); } else { // - We'll let the user select a class if multiple classes are available $oClassForm = FormUIBlockFactory::MakeStandard(); // - When the user submit, redo the same request but with a real class $sCurrentParameters = json_encode([ 'att_code' => $sAttCode, 'host_class' => $sClass, 'host_id' => $sId]); $sCurrentUrl = $oRouter->GenerateUrl('linkset.create_linked_object'); $oClassForm->SetOnSubmitJsCode( <<AddSubBlock(cmdbAbstractObject::DisplayBlockSelectClassToCreate($sProposedRealClass, MetaModel::GetName($sProposedRealClass), $aPossibleClasses)); $oPage->AddUiBlock($oClassForm); } return $oPage; } /** * OperationGetRemoteObject. * * @return JsonPage */ public function OperationGetRemoteObject(): JsonPage { $oPage = new JsonPage(); $bSuccess = true; $aObjectData = null; // Retrieve query params $sObjectClass = utils::ReadParam('linked_object_class', '', false, utils::ENUM_SANITIZATION_FILTER_STRING); $sObjectKey = utils::ReadParam('linked_object_key', '', false, utils::ENUM_SANITIZATION_FILTER_STRING); $sRemoteClass = utils::ReadParam('remote_class', null, false, utils::ENUM_SANITIZATION_FILTER_STRING); $sRemoteExtKey = utils::ReadParam('external_key_att_code', null, false, utils::ENUM_SANITIZATION_FILTER_STRING); // Retrieve object try { $oObject = MetaModel::GetObject($sObjectClass, $sObjectKey); $sLinkKey = $oObject->GetKey(); if (!utils::IsNullOrEmptyString($sRemoteExtKey)) { $oObject = MetaModel::GetObject($sRemoteClass, $oObject->Get($sRemoteExtKey)); } $aObjectData = ObjectRepository::ConvertObjectToArray($oObject, $sObjectClass); $aObjectData['link_keys'] = [$sObjectKey]; } catch (Exception $e) { $bSuccess = false; } return $oPage->SetData([ 'object' => $aObjectData, 'success' => $bSuccess, ]); } }