mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-20 17:18:51 +02:00
Rework of the edition of 1-N and N-N links: managed as a delta from the GUI down to the the lowest APIs.
- Fixes the management of obsolete linked data. - N.744 Fixes concurrent modifications (example: a user modifies a team, another user modifies a person related to that same team). Still NOT fixed with the customer portal. - N.849 Fixes links edition in the case some data are not allowed to the current user (organization silos) -TO BE TESTED - #1145 Fixes the creation of duplicate links in one step (Server to NW Device) - #1147 Fixes the update of duplicate links SVN:trunk[4766]
This commit is contained in:
@@ -405,11 +405,28 @@ EOF
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||
// Display mode
|
||||
if (!$oAttDef->IsLinkset()) continue; // Process only linkset attributes...
|
||||
|
||||
// $oSet = new DBObjectSet($this->Get($sAttCode)->GetFilter()); // Why do something so useless ?
|
||||
$oSet = $this->Get($sAttCode);
|
||||
$oSet->SetShowObsoleteData(utils::ShowObsoleteData());
|
||||
$iCount = $oSet->Count();
|
||||
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
|
||||
// Filter out links pointing to obsolete objects (if relevant)
|
||||
$oLinkSearch = $this->Get($sAttCode)->GetFilter();
|
||||
if ($oAttDef->IsIndirect())
|
||||
{
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||
if (!utils::ShowObsoleteData() && MetaModel::IsObsoletable($sTargetClass))
|
||||
{
|
||||
$oNotObsolete = new BinaryExpression(
|
||||
new FieldExpression('obsolescence_flag', $sTargetClass),
|
||||
'=',
|
||||
new ScalarExpression(0)
|
||||
);
|
||||
$oLinkSearch->AddConditionExpression($oNotObsolete);
|
||||
}
|
||||
}
|
||||
$oLinkSet = new DBObjectSet($oLinkSearch);
|
||||
|
||||
$iCount = $oLinkSet->Count();
|
||||
$sCount = '';
|
||||
if ($iCount != 0)
|
||||
{
|
||||
@@ -427,8 +444,7 @@ EOF
|
||||
// Adjust the flags according to user rights
|
||||
if ($oAttDef->IsIndirect())
|
||||
{
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||
// n:n links => must be allowed to modify the linking class AND read the target class in order to edit the linkedset
|
||||
if (!UserRights::IsActionAllowed($sLinkedClass, UR_ACTION_MODIFY) || !UserRights::IsActionAllowed($sTargetClass, UR_ACTION_READ))
|
||||
@@ -444,12 +460,12 @@ EOF
|
||||
else
|
||||
{
|
||||
// 1:n links => must be allowed to modify the linked class in order to edit the linkedset
|
||||
if (!UserRights::IsActionAllowed($oAttDef->GetLinkedClass(), UR_ACTION_MODIFY))
|
||||
if (!UserRights::IsActionAllowed($sLinkedClass, UR_ACTION_MODIFY))
|
||||
{
|
||||
$iFlags |= OPT_ATT_READONLY;
|
||||
}
|
||||
// 1:n links => must be allowed to read the linked class in order to display the linkedset
|
||||
if (!UserRights::IsActionAllowed($oAttDef->GetLinkedClass(), UR_ACTION_READ))
|
||||
if (!UserRights::IsActionAllowed($sLinkedClass, UR_ACTION_READ))
|
||||
{
|
||||
$iFlags |= OPT_ATT_HIDDEN;
|
||||
}
|
||||
@@ -463,10 +479,9 @@ EOF
|
||||
{
|
||||
$sInputId = $this->m_iFormId.'_'.$sAttCode;
|
||||
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
if ($oAttDef->IsIndirect())
|
||||
{
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||
}
|
||||
else
|
||||
@@ -475,9 +490,8 @@ EOF
|
||||
}
|
||||
$oPage->p(MetaModel::GetClassIcon($sTargetClass)." ".$oAttDef->GetDescription().'<span id="busy_'.$sInputId.'"></span>');
|
||||
|
||||
$oValue = $this->Get($sAttCode);
|
||||
$sDisplayValue = ''; // not used
|
||||
$sHTMLValue = "<span id=\"field_{$sInputId}\">".self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $oValue, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).'</span>';
|
||||
$sHTMLValue = "<span id=\"field_{$sInputId}\">".self::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, $oLinkSet, $sDisplayValue, $sInputId, '', $iFlags, $aArgs).'</span>';
|
||||
$this->AddToFieldsMap($sAttCode, $sInputId);
|
||||
$oPage->add($sHTMLValue);
|
||||
}
|
||||
@@ -487,7 +501,7 @@ EOF
|
||||
if (!$oAttDef->IsIndirect())
|
||||
{
|
||||
// 1:n links
|
||||
$sTargetClass = $oAttDef->GetLinkedClass();
|
||||
$sTargetClass = $sLinkedClass;
|
||||
|
||||
$aDefaults = array($oAttDef->GetExtKeyToMe() => $this->GetKey());
|
||||
$oAppContext = new ApplicationContext();
|
||||
@@ -510,10 +524,8 @@ EOF
|
||||
else
|
||||
{
|
||||
// n:n links
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||
$oLinkingAttDef = MetaModel::GetAttributeDef($sLinkedClass, $oAttDef->GetExtKeyToRemote());
|
||||
$sTargetClass = $oLinkingAttDef->GetTargetClass();
|
||||
$bMenu = ($this->Get($sAttCode)->Count() > 0); // The menu is enabled only if there are already some elements...
|
||||
$aParams = array(
|
||||
'link_attr' => $oAttDef->GetExtKeyToMe(),
|
||||
'object_id' => $this->GetKey(),
|
||||
@@ -525,7 +537,7 @@ EOF
|
||||
);
|
||||
}
|
||||
$oPage->p(MetaModel::GetClassIcon($sTargetClass)." ".$oAttDef->GetDescription());
|
||||
$oBlock = new DisplayBlock($this->Get($sAttCode)->GetFilter(), 'list', false);
|
||||
$oBlock = new DisplayBlock($oLinkSet->GetFilter(), 'list', false);
|
||||
$oBlock->Display($oPage, 'rel_'.$sAttCode, $aParams);
|
||||
}
|
||||
if (array_key_exists($sAttCode, $aRedundancySettings))
|
||||
@@ -2107,7 +2119,7 @@ EOF
|
||||
$oPage->add_dict_entry('UI:ValueMustBeSet');
|
||||
$oPage->add_dict_entry('UI:ValueMustBeChanged');
|
||||
$oPage->add_dict_entry('UI:ValueInvalidFormat');
|
||||
return "<div>{$sHTMLValue}</div>";
|
||||
return "<div class=\"attribute-edit\" data-attcode=\"$sAttCode\">{$sHTMLValue}</div>";
|
||||
}
|
||||
|
||||
public function DisplayModifyForm(WebPage $oPage, $aExtraParams = array())
|
||||
@@ -3026,50 +3038,7 @@ EOF
|
||||
foreach($aValues as $sAttCode => $value)
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
|
||||
if ($oAttDef->IsLinkSet() && $oAttDef->IsIndirect())
|
||||
{
|
||||
$aLinks = $value;
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
|
||||
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
||||
$oLinkedSet = DBObjectSet::FromScratch($sLinkedClass);
|
||||
if (is_array($aLinks))
|
||||
{
|
||||
foreach($aLinks as $id => $aData)
|
||||
{
|
||||
if (is_numeric($id))
|
||||
{
|
||||
if ($id < 0)
|
||||
{
|
||||
// New link to be created, the opposite of the id (-$id) is the ID of the remote object
|
||||
$oLink = MetaModel::NewObject($sLinkedClass);
|
||||
$oLink->Set($sExtKeyToRemote, -$id);
|
||||
$oLink->Set($sExtKeyToMe, $this->GetKey());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Existing link, potentially to be updated...
|
||||
$oLink = MetaModel::GetObject($sLinkedClass, $id);
|
||||
}
|
||||
// Now populate the attributes
|
||||
foreach($aData as $sName => $value)
|
||||
{
|
||||
if (MetaModel::IsValidAttCode($sLinkedClass, $sName))
|
||||
{
|
||||
$oLinkAttDef = MetaModel::GetAttributeDef($sLinkedClass, $sName);
|
||||
if ($oLinkAttDef->IsWritable())
|
||||
{
|
||||
$oLink->Set($sName, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
$oLinkedSet->AddObject($oLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->Set($sAttCode, $oLinkedSet);
|
||||
}
|
||||
elseif ($oAttDef->GetEditClass() == 'Document')
|
||||
if ($oAttDef->GetEditClass() == 'Document')
|
||||
{
|
||||
// There should be an uploaded file with the named attr_<attCode>
|
||||
$oDocument = $value['fcontents'];
|
||||
@@ -3123,30 +3092,10 @@ EOF
|
||||
{
|
||||
$this->Set($sAttCode, $value);
|
||||
}
|
||||
else if (($oAttDef->GetEditClass() == 'LinkedSet') && !$oAttDef->IsIndirect() &&
|
||||
(($oAttDef->GetEditMode() == LINKSET_EDITMODE_INPLACE) || ($oAttDef->GetEditMode() == LINKSET_EDITMODE_ADDREMOVE)))
|
||||
else if ($oAttDef->GetEditClass() == 'LinkedSet')
|
||||
{
|
||||
$oLinkset = $this->Get($sAttCode);
|
||||
$sLinkedClass = $oLinkset->GetClass();
|
||||
$aObjSet = array();
|
||||
$oLinkset->Rewind();
|
||||
$bModified = false;
|
||||
while($oLink = $oLinkset->Fetch())
|
||||
{
|
||||
if (in_array($oLink->GetKey(), $value['to_be_deleted']))
|
||||
{
|
||||
// The link is to be deleted, don't copy it in the array
|
||||
$bModified = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!array_key_exists('to_be_removed', $value) || !in_array($oLink->GetKey(), $value['to_be_removed']))
|
||||
{
|
||||
$aObjSet[] = $oLink;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oLinkSet = $this->Get($sAttCode);
|
||||
$sLinkedClass = $oAttDef->GetLinkedClass();
|
||||
if (array_key_exists('to_be_created', $value) && (count($value['to_be_created']) > 0))
|
||||
{
|
||||
// Now handle the links to be created
|
||||
@@ -3156,11 +3105,10 @@ EOF
|
||||
if ( ($sLinkedClass == $sSubClass) || (is_subclass_of($sSubClass, $sLinkedClass)) )
|
||||
{
|
||||
$aObjData = $aData['data'];
|
||||
|
||||
$oLink = new $sSubClass;
|
||||
|
||||
$oLink = MetaModel::NewObject($sSubClass);
|
||||
$oLink->UpdateObjectFromArray($aObjData);
|
||||
$aObjSet[] = $oLink;
|
||||
$bModified = true;
|
||||
$oLinkSet->AddItem($oLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3172,32 +3120,39 @@ EOF
|
||||
$oLink = MetaModel::GetObject($sLinkedClass, $iObjKey, false);
|
||||
if ($oLink)
|
||||
{
|
||||
$aObjSet[] = $oLink;
|
||||
$bModified = true;
|
||||
$oLinkSet->AddItem($oLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (array_key_exists('to_be_modified', $value) && (count($value['to_be_modified']) > 0))
|
||||
{
|
||||
// Now handle the links to be added by making the remote object point to self
|
||||
foreach($value['to_be_modified'] as $iObjKey => $aData)
|
||||
{
|
||||
$oLink = MetaModel::GetObject($sLinkedClass, $iObjKey, false);
|
||||
if ($oLink)
|
||||
{
|
||||
$aObjData = $aData['data'];
|
||||
$oLink->UpdateObjectFromArray($aObjData);
|
||||
$oLinkSet->ModifyItem($oLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (array_key_exists('to_be_removed', $value) && (count($value['to_be_removed']) > 0))
|
||||
{
|
||||
// Now handle the links to be removed by making the remote object point to nothing
|
||||
// Keep them in the set (modified), DBWriteLinks will handle them
|
||||
foreach($value['to_be_removed'] as $iObjKey)
|
||||
{
|
||||
$oLink = MetaModel::GetObject($sLinkedClass, $iObjKey, false);
|
||||
if ($oLink)
|
||||
{
|
||||
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
|
||||
$oLink->Set($sExtKeyToMe, null);
|
||||
$aObjSet[] = $oLink;
|
||||
$bModified = true;
|
||||
}
|
||||
$oLinkSet->RemoveItem($iObjKey);
|
||||
}
|
||||
}
|
||||
if ($bModified)
|
||||
if (array_key_exists('to_be_deleted', $value) && (count($value['to_be_deleted']) > 0))
|
||||
{
|
||||
$oNewSet = DBObjectSet::FromArray($oLinkset->GetClass(), $aObjSet);
|
||||
$this->Set($sAttCode, $oNewSet);
|
||||
}
|
||||
foreach($value['to_be_deleted'] as $iObjKey)
|
||||
{
|
||||
$oLinkSet->RemoveItem($iObjKey);
|
||||
}
|
||||
}
|
||||
$this->Set($sAttCode, $oLinkSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3254,15 +3209,14 @@ EOF
|
||||
{
|
||||
$value = $oAttDef->ReadValueFromPostedForm($this, $sFormPrefix);
|
||||
}
|
||||
else if (($oAttDef->GetEditClass() == 'LinkedSet') && !$oAttDef->IsIndirect() &&
|
||||
(($oAttDef->GetEditMode() == LINKSET_EDITMODE_INPLACE) || ($oAttDef->GetEditMode() == LINKSET_EDITMODE_ADDREMOVE)) )
|
||||
else if ($oAttDef->GetEditClass() == 'LinkedSet')
|
||||
{
|
||||
$aRawToBeCreated = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbc", '{}', 'raw_data'), true);
|
||||
$aToBeCreated = array();
|
||||
foreach($aRawToBeCreated as $aData)
|
||||
{
|
||||
$sSubFormPrefix = $aData['formPrefix'];
|
||||
$sObjClass = $aData['class'];
|
||||
$sObjClass = $oAttDef->GetLinkedClass();
|
||||
$aObjData = array();
|
||||
foreach($aData as $sKey => $value)
|
||||
{
|
||||
@@ -3273,11 +3227,30 @@ EOF
|
||||
}
|
||||
$aToBeCreated[] = array('class' => $sObjClass, 'data' => $aObjData);
|
||||
}
|
||||
|
||||
$value = array('to_be_created' => $aToBeCreated,
|
||||
'to_be_deleted' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbd", '[]', 'raw_data'), true),
|
||||
'to_be_added' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tba", '[]', 'raw_data'), true),
|
||||
'to_be_removed' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbr", '[]', 'raw_data'), true) );
|
||||
|
||||
$aRawToBeModified = json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbm", '{}', 'raw_data'), true);
|
||||
$aToBeModified = array();
|
||||
foreach($aRawToBeModified as $iObjKey => $aData)
|
||||
{
|
||||
$sSubFormPrefix = $aData['formPrefix'];
|
||||
$aObjData = array();
|
||||
foreach($aData as $sKey => $value)
|
||||
{
|
||||
if (preg_match("/^attr_$sSubFormPrefix(.*)$/", $sKey, $aMatches))
|
||||
{
|
||||
$aObjData[$aMatches[1]] = $value;
|
||||
}
|
||||
}
|
||||
$aToBeModified[$iObjKey] = array('data' => $aObjData);
|
||||
}
|
||||
|
||||
$value = array(
|
||||
'to_be_created' => $aToBeCreated,
|
||||
'to_be_modified' => $aToBeModified,
|
||||
'to_be_deleted' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbd", '[]', 'raw_data'), true),
|
||||
'to_be_added' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tba", '[]', 'raw_data'), true),
|
||||
'to_be_removed' => json_decode(utils::ReadPostedParam("attr_{$sFormPrefix}{$sAttCode}_tbr", '[]', 'raw_data'), true)
|
||||
);
|
||||
}
|
||||
else if ($oAttDef instanceof AttributeDateTime) // AttributeDate is derived from AttributeDateTime
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// Copyright (C) 2010-2015 Combodo SARL
|
||||
// Copyright (C) 2010-2017 Combodo SARL
|
||||
//
|
||||
// This file is part of iTop.
|
||||
//
|
||||
@@ -19,7 +19,7 @@
|
||||
/**
|
||||
* Class UILinksWidgetDirect
|
||||
*
|
||||
* @copyright Copyright (C) 2010-2015 Combodo SARL
|
||||
* @copyright Copyright (C) 2010-2017 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
@@ -71,7 +71,14 @@ class UILinksWidgetDirect
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param DBObjectSet $oValue
|
||||
* @param array $aArgs
|
||||
* @param $sFormPrefix
|
||||
* @param $oCurrentObj
|
||||
*/
|
||||
public function Display(WebPage $oPage, DBObjectSet $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj)
|
||||
{
|
||||
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||
@@ -115,7 +122,15 @@ class UILinksWidgetDirect
|
||||
$this->DisplayAsBlock($oPage, $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, true /* bDisplayMenu*/);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param DBObjectSet $oValue
|
||||
* @param array $aArgs
|
||||
* @param $sFormPrefix
|
||||
* @param $oCurrentObj
|
||||
* @param $bDisplayMenu
|
||||
*/
|
||||
protected function DisplayAsBlock(WebPage $oPage, DBObjectSet $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, $bDisplayMenu)
|
||||
{
|
||||
$oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
|
||||
@@ -151,7 +166,15 @@ class UILinksWidgetDirect
|
||||
$oBlock->Display($oPage, $this->sInputid, $aParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param WebPage $oPage
|
||||
* @param DBObjectSet $oValue
|
||||
* @param array $aArgs
|
||||
* @param $sFormPrefix
|
||||
* @param $oCurrentObj
|
||||
* @param array $aButtons
|
||||
*/
|
||||
protected function DisplayEditInPlace(WebPage $oPage, DBObjectSet $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, $aButtons = array('create', 'delete'))
|
||||
{
|
||||
$aAttribs = $this->GetTableConfig();
|
||||
|
||||
@@ -92,16 +92,18 @@ class UILinksWidget
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A one-row form for editing a link record
|
||||
* @param WebPage $oP Web page used for the ouput
|
||||
* @param DBObject $oLinkedObj The object to which all the elements of the linked set refer to
|
||||
* @param DBObject $oLinkedObj Remote object
|
||||
* @param mixed $linkObjOrId Either the object linked or a unique number for new link records to add
|
||||
* @param Hash $aArgs Extra context arguments
|
||||
* @param array|Hash $aArgs Extra context arguments
|
||||
* @param $oCurrentObj The object to which all the elements of the linked set refer to
|
||||
* @param $iUniqueId A unique identifier of new links
|
||||
* @return string The HTML fragment of the one-row form
|
||||
*/
|
||||
protected function GetFormRow(WebPage $oP, DBObject $oLinkedObj, $linkObjOrId = null, $aArgs = array(), $oCurrentObj )
|
||||
protected function GetFormRow(WebPage $oP, DBObject $oLinkedObj, $linkObjOrId, $aArgs, $oCurrentObj, $iUniqueId)
|
||||
{
|
||||
$sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}";
|
||||
$aRow = array();
|
||||
@@ -115,8 +117,7 @@ class UILinksWidget
|
||||
$aArgs['prefix'] = $sPrefix;
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$key}";
|
||||
$aArgs['this'] = $linkObjOrId;
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$key\">";
|
||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" name=\"attr_{$sPrefix}id{$sNameSuffix}\" value=\"$key\">";
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"$key\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$key\">";
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$linkObjOrId->GetKey().']';
|
||||
@@ -137,28 +138,25 @@ class UILinksWidget
|
||||
// New link existing only in memory
|
||||
$oNewLinkObj = $linkObjOrId;
|
||||
$iRemoteObjKey = $oNewLinkObj->Get($this->m_sExtKeyToRemote);
|
||||
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, $iRemoteObjKey);
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||
$linkObjOrId = -$iRemoteObjKey;
|
||||
}
|
||||
else
|
||||
{
|
||||
$iRemoteObjKey = -$linkObjOrId;
|
||||
$iRemoteObjKey = $linkObjOrId;
|
||||
$oNewLinkObj = MetaModel::NewObject($this->m_sLinkedClass);
|
||||
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, -$linkObjOrId);
|
||||
$oRemoteObj = MetaModel::GetObject($this->m_sRemoteClass, $iRemoteObjKey);
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToRemote, $oRemoteObj); // Setting the extkey with the object alsoo fills the related external fields
|
||||
$oNewLinkObj->Set($this->m_sExtKeyToMe, $oCurrentObj); // Setting the extkey with the object also fills the related external fields
|
||||
}
|
||||
$sPrefix .= "[$linkObjOrId][";
|
||||
$sPrefix .= "[-$iUniqueId][";
|
||||
$sNameSuffix = "]"; // To make a tabular form
|
||||
$aArgs['prefix'] = $sPrefix;
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}_".(-$linkObjOrId);
|
||||
$aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}_".$iUniqueId;
|
||||
$aArgs['this'] = $oNewLinkObj;
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"$linkObjOrId\">";
|
||||
$aRow['form::checkbox'] .= "<input type=\"hidden\" name=\"attr_{$sPrefix}id{$sNameSuffix}\" value=\"\">";
|
||||
$aRow['form::checkbox'] = "<input class=\"selection\" data-remote-id=\"$iRemoteObjKey\" data-link-id=\"\" data-unique-id=\"$iUniqueId\" type=\"checkbox\" onClick=\"oWidget".$this->m_iInputId.".OnSelectChange();\" value=\"-$iUniqueId\">";
|
||||
foreach($this->m_aEditableFields as $sFieldCode)
|
||||
{
|
||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$linkObjOrId.']';
|
||||
$sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.-$iUniqueId.']';
|
||||
$sSafeId = utils::GetSafeId($sFieldId);
|
||||
$sValue = $oNewLinkObj->Get($sFieldCode);
|
||||
$sDisplayValue = $oNewLinkObj->GetEditValue($sFieldCode);
|
||||
@@ -171,6 +169,7 @@ class UILinksWidget
|
||||
$oP->add_script(
|
||||
<<<EOF
|
||||
PrepareWidgets();
|
||||
oWidget{$this->m_iInputId}.OnLinkAdded($iUniqueId, $iRemoteObjKey);
|
||||
EOF
|
||||
);
|
||||
}
|
||||
@@ -278,21 +277,19 @@ EOF
|
||||
$sHtmlValue .= "<input type=\"hidden\" id=\"{$sFormPrefix}{$this->m_iInputId}\">\n";
|
||||
$oValue->Rewind();
|
||||
$aForm = array();
|
||||
$iAddedId = 1; // Unique id for new links
|
||||
while($oCurrentLink = $oValue->Fetch())
|
||||
{
|
||||
$aRow = array();
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $oCurrentLink->Get($this->m_sExtKeyToRemote));
|
||||
if ($oCurrentLink->IsNew())
|
||||
{
|
||||
$key = -$oLinkedObj->GetKey();
|
||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj);
|
||||
$key = -($iAddedId++);
|
||||
}
|
||||
else
|
||||
{
|
||||
$key = $oCurrentLink->GetKey();
|
||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj);
|
||||
}
|
||||
|
||||
$aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key);
|
||||
}
|
||||
$sHtmlValue .= $this->DisplayFormTable($oPage, $this->m_aTableConfig, $aForm);
|
||||
$sDuplicates = ($this->m_bDuplicatesAllowed) ? 'true' : 'false';
|
||||
@@ -300,7 +297,6 @@ EOF
|
||||
$oPage->add_ready_script(<<<EOF
|
||||
oWidget{$this->m_iInputId} = new LinksWidget('{$this->m_sAttCode}{$this->m_sNameSuffix}', '{$this->m_sClass}', '{$this->m_sAttCode}', '{$this->m_iInputId}', '{$this->m_sNameSuffix}', $sDuplicates, $sWizHelper, '{$this->m_sExtKeyToRemote}');
|
||||
oWidget{$this->m_iInputId}.Init();
|
||||
$('#{$this->m_iInputId}').bind('update_value', function() { $(this).val(oWidget{$this->m_iInputId}.GetUpdatedValue()); })
|
||||
EOF
|
||||
);
|
||||
$sHtmlValue .= "<span style=\"float:left;\"> <img src=\"../images/tv-item-last.gif\"> <input id=\"{$this->m_sAttCode}{$this->m_sNameSuffix}_btnRemove\" type=\"button\" value=\"".Dict::S('UI:RemoveLinkedObjectsOf_Class')."\" onClick=\"oWidget{$this->m_iInputId}.RemoveSelected();\" >";
|
||||
@@ -373,51 +369,25 @@ EOF
|
||||
}
|
||||
if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0)
|
||||
{
|
||||
// Positive IDs correspond to existing link records
|
||||
// negative IDs correspond to "remote" objects to be linked
|
||||
$aLinkIds = array();
|
||||
$aRemoteObjIds = array();
|
||||
foreach($aAlreadyLinkedIds as $iId)
|
||||
{
|
||||
if ($iId > 0)
|
||||
{
|
||||
$aLinkIds[] = $iId;
|
||||
}
|
||||
else
|
||||
{
|
||||
$aRemoteObjIds[] = -$iId;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($aLinkIds) >0)
|
||||
{
|
||||
// Search for the links to find to which "remote" object they are linked
|
||||
$oLinkFilter = new DBObjectSearch($this->m_sLinkedClass);
|
||||
$oLinkFilter->AddCondition('id', $aLinkIds, 'IN');
|
||||
$oLinkSet = new CMDBObjectSet($oLinkFilter);
|
||||
while($oLink = $oLinkSet->Fetch())
|
||||
{
|
||||
$aRemoteObjIds[] = $oLink->Get($this->m_sExtKeyToRemote);
|
||||
}
|
||||
}
|
||||
$oFilter->AddCondition('id', $aRemoteObjIds, 'NOTIN');
|
||||
$oFilter->AddCondition('id', $aAlreadyLinkedIds, 'NOTIN');
|
||||
}
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
$oBlock = new DisplayBlock($oFilter, 'list', false);
|
||||
$oBlock->Display($oP, "ResultsToAdd_{$this->m_sAttCode}", array('menu' => false, 'cssCount'=> '#count_'.$this->m_sAttCode.$this->m_sNameSuffix , 'selection_mode' => true, 'table_id' => 'add_'.$this->m_sAttCode)); // Don't display the 'Actions' menu on the results
|
||||
}
|
||||
|
||||
public function DoAddObjects(WebPage $oP, $oFullSetFilter, $oCurrentObj)
|
||||
public function DoAddObjects(WebPage $oP, $iMaxAddedId, $oFullSetFilter, $oCurrentObj)
|
||||
{
|
||||
$aLinkedObjectIds = utils::ReadMultipleSelection($oFullSetFilter);
|
||||
|
||||
$iAdditionId = $iMaxAddedId + 1;
|
||||
foreach($aLinkedObjectIds as $iObjectId)
|
||||
{
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId);
|
||||
$oLinkedObj = MetaModel::GetObject($this->m_sRemoteClass, $iObjectId, false);
|
||||
if (is_object($oLinkedObj))
|
||||
{
|
||||
$aRow = $this->GetFormRow($oP, $oLinkedObj, -$iObjectId, array(), $oCurrentObj ); // Not yet created link get negative Ids
|
||||
$oP->add($this->DisplayFormRow($oP, $this->m_aTableConfig, $aRow, -$iObjectId));
|
||||
$aRow = $this->GetFormRow($oP, $oLinkedObj, $iObjectId, array(), $oCurrentObj, $iAdditionId); // Not yet created link get negative Ids
|
||||
$oP->add($this->DisplayFormRow($oP, $this->m_aTableConfig, $aRow, -$iAdditionId));
|
||||
$iAdditionId++;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -468,4 +438,3 @@ EOF
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user