N°3136 - Add creation and modification of n-n objects in object details (#378)

* Rebase onto develop

* Use exit condition instead of englobing condition

* Add informative modals that can be called from modal toolbox

* Refactor "apply_modify" and "apply_new" into own controller, handle ajax requests with a json response and handle these responses in linkset creation/edition

* Fix merge issues

* Remove inverted condition

* Move linkset create button to a better place, still needs to fix duplicate "New" button caused by a refactor

* Handle "Cancel" button in modals

* Do not display relations when editing an object in a modal

* More elegant way to add "New" button to relations lists

* Factorize vertical highlights in alerts and modal in a single mixin

* Replace button name with dict entry code

* Change route name to snake case

* More elegant way to add "Create in modal" button to relations lists

* Replace triple if with in_array

* Move listener to body

* Rename variable to match boolean rules

* Rename event

* Rename extra param

* Add phpdoc

* Revert changes

* Check indirect linkset rights before allowing creation in modal
This commit is contained in:
Stephen Abello
2023-01-18 13:35:48 +01:00
committed by GitHub
parent cc2881a7b0
commit e1ffa65d8b
21 changed files with 835 additions and 328 deletions

View File

@@ -6,8 +6,14 @@
namespace Combodo\iTop\Controller\Links;
use AjaxPage;
use cmdbAbstractObject;
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
use Combodo\iTop\Controller\AbstractController;
use DBObject;
use iTopWebPage;
use MetaModel;
use UserRights;
use utils;
/**
@@ -99,5 +105,97 @@ class LinkSetController extends AbstractController
return $oPage;
}
/**
* @return \iTopWebPage|\AjaxPage Create edit form in its webpage
* @throws \ApplicationException
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \SecurityException
*/
public function OperationCreateLinkedObject()
{
$bPrintable = utils::ReadParam('printable', '0') === '1';
$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');
// 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(); // TODO 3.1 array($sExtKeyToMe => OPT_ATT_READONLY);
$oObj = DBObject::MakeDefaultInstance($sRealClass);
if ($this->IsHandlingXmlHttpRequest()) {
$oPage = new AjaxPage('');
} else {
$oPage = new iTopWebPage('', $bPrintable);
$oPage->DisableBreadCrumb();
$oPage->SetContentLayout(PageContentFactory::MakeForObjectDetails($oObj, cmdbAbstractObject::ENUM_DISPLAY_MODE_CREATE));
}
$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 =
<<<JS
event.preventDefault();
if(bOnSubmitForm === true)
{
let oForm = $(this);
let sUrl = oForm.attr('action');
let sPosting = $.post( sUrl, oForm.serialize());
/* Alerts the results */
sPosting.done(function(data) {
if(data.success !== undefined && data.success === true) {
oForm.closest('[data-role="ibo-modal"]').dialog('close');
}
else {
CombodoModal.OpenInformativeModal(data.data.error_message, 'error');
}
});
}
JS
;
$aExtraParams = [
'noRelations' => true,
'fieldsFlags' => $aFieldFlags,
'js_handlers' => [
'form_on_submit' => $sFormOnSubmitJsCode,
'cancel_button_on_click' =>
<<<JS
function() {
$(this).closest('[data-role="ibo-modal"]').dialog('close');
};
JS
]
];
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObj, array(), $aExtraParams);
return $oPage;
}
return;
}
}