From 02c78d4044f8c983501d31b9e7b9b57a7e0b2757 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 12 Jun 2019 10:17:19 +0200 Subject: [PATCH 1/3] =?UTF-8?q?N=C2=B02278=20-=20Object-copier:=20Fix=20n:?= =?UTF-8?q?n=20link=20attributes=20set=20to=20default=20on=20copy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit 6564d84a2fc5e12bc0dd0f30d5a001a84fb4577e) --- application/ui.linkswidget.class.inc.php | 87 +++++++++++++----------- js/linkswidget.js | 4 ++ 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/application/ui.linkswidget.class.inc.php b/application/ui.linkswidget.class.inc.php index e03f884e5..068f967b1 100644 --- a/application/ui.linkswidget.class.inc.php +++ b/application/ui.linkswidget.class.inc.php @@ -133,14 +133,15 @@ class UILinksWidget $sPrefix = "$this->m_sAttCode{$this->m_sNameSuffix}"; $aRow = array(); $aFieldsMap = array(); + $iKey = 0; if(is_object($linkObjOrId) && (!$linkObjOrId->IsNew())) { - $key = $linkObjOrId->GetKey(); + $iKey = $linkObjOrId->GetKey(); $iRemoteObjKey = $linkObjOrId->Get($this->m_sExtKeyToRemote); - $sPrefix .= "[$key]["; + $sPrefix .= "[$iKey]["; $sNameSuffix = "]"; // To make a tabular form $aArgs['prefix'] = $sPrefix; - $aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$key}"; + $aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}{$iKey}"; $aArgs['this'] = $linkObjOrId; if($bReadOnly) @@ -154,7 +155,7 @@ class UILinksWidget } else { - $aRow['form::checkbox'] = "m_iInputId.".OnSelectChange();\" value=\"$key\">"; + $aRow['form::checkbox'] = "m_iInputId.".OnSelectChange();\" value=\"$iKey\">"; foreach($this->m_aEditableFields as $sFieldCode) { $sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.$linkObjOrId->GetKey().']'; @@ -195,7 +196,30 @@ class UILinksWidget $aArgs['wizHelper'] = "oWizardHelper{$this->m_iInputId}_".($iUniqueId < 0 ? -$iUniqueId : $iUniqueId); $aArgs['this'] = $oNewLinkObj; $sInputValue = $iUniqueId > 0 ? "-$iUniqueId" : "$iUniqueId"; - $aRow['form::checkbox'] = "m_iInputId.".OnSelectChange();\" value=\"$sInputValue\">"; + $aRow['form::checkbox'] = "m_iInputId.".OnSelectChange();\" value=\"$sInputValue\">"; + + if ($iUniqueId > 0) + { + // Rows created with ajax call need OnLinkAdded call. + // + $oP->add_ready_script( + <<m_iInputId}.OnLinkAdded($iUniqueId, $iRemoteObjKey); +EOF + ); + } + else + { + // Rows added before loading the form don't have to call OnLinkAdded. + // Listeners are already present and DOM is not recreated + $iPositiveUniqueId = -$iUniqueId; + $oP->add_ready_script(<<m_iInputId}.AddLink($iPositiveUniqueId, $iRemoteObjKey); +EOF + ); + } + foreach($this->m_aEditableFields as $sFieldCode) { $sFieldId = $this->m_iInputId.'_'.$sFieldCode.'['.-$iUniqueId.']'; @@ -207,20 +231,12 @@ class UILinksWidget cmdbAbstractObject::GetFormElementForField($oP, $this->m_sLinkedClass, $sFieldCode, $oAttDef, $sValue, $sDisplayValue, $sSafeId /* id */, $sNameSuffix, 0, $aArgs). ''; $aFieldsMap[$sFieldCode] = $sSafeId; + $oP->add_ready_script(<<m_iInputId}.OnValueChange($iKey, $iUniqueId, '$sFieldCode', '$sValue'); +EOF + ); } $sState = ''; - - // Rows created with ajax call need OnLinkAdded call. - // Rows added before loading the form cannot call OnLinkAdded. - if ($iUniqueId > 0) - { - $oP->add_ready_script( - <<m_iInputId}.OnLinkAdded($iUniqueId, $iRemoteObjKey); -EOF - ); - } } if(!$bReadOnly) @@ -337,8 +353,19 @@ EOF $sHtmlValue .= "m_iInputId}\">\n"; $oValue->Rewind(); $aForm = array(); - $iAddedId = 1; // Unique id for new links - $aAddedLinks = array(); + $iAddedId = -1; // Unique id for new links + + $sDuplicates = ($this->m_bDuplicatesAllowed) ? 'true' : 'false'; + // Don't automatically launch the search if the table is huge + $bDoSearch = !utils::IsHighCardinality($this->m_sRemoteClass); + $sJSDoSearch = $bDoSearch ? 'true' : 'false'; + $sWizHelper = 'oWizardHelper'.$sFormPrefix; + $oPage->add_ready_script(<<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}', $sJSDoSearch); + oWidget{$this->m_iInputId}.Init(); +EOF + ); + while($oCurrentLink = $oValue->Fetch()) { // We try to retrieve the remote object as usual @@ -357,9 +384,7 @@ EOF if ($oCurrentLink->IsNew()) { - $key = -($iAddedId++); - $iUniqueId = -$key; - $aAddedLinks[] = array('iAddedId' => $iUniqueId, 'iRemote' => $oCurrentLink->Get($this->m_sExtKeyToRemote)); + $key = $iAddedId--; } else { @@ -368,24 +393,6 @@ EOF $aForm[$key] = $this->GetFormRow($oPage, $oLinkedObj, $oCurrentLink, $aArgs, $oCurrentObj, $key, $bReadOnly); } $sHtmlValue .= $this->DisplayFormTable($oPage, $this->m_aTableConfig, $aForm); - $sDuplicates = ($this->m_bDuplicatesAllowed) ? 'true' : 'false'; - // Don't automatically launch the search if the table is huge - $bDoSearch = !utils::IsHighCardinality($this->m_sRemoteClass); - $sJSDoSearch = $bDoSearch ? 'true' : 'false'; - $sWizHelper = 'oWizardHelper'.$sFormPrefix; - $oPage->add_ready_script(<<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}', $sJSDoSearch); - oWidget{$this->m_iInputId}.Init(); -EOF -); - - foreach ($aAddedLinks as $aAddedLink) - { - $oPage->add_ready_script(<<m_iInputId}.AddLink({$aAddedLink['iAddedId']}, {$aAddedLink['iRemote']}); -EOF - ); - } $sHtmlValue .= "     m_sAttCode}{$this->m_sNameSuffix}_btnRemove\" type=\"button\" value=\"".Dict::S('UI:RemoveLinkedObjectsOf_Class')."\" onClick=\"oWidget{$this->m_iInputId}.RemoveSelected();\" >"; $sHtmlValue .= "   m_sAttCode}{$this->m_sNameSuffix}_btnAdd\" type=\"button\" value=\"".Dict::Format('UI:AddLinkedObjectsOf_Class', MetaModel::GetName($this->m_sRemoteClass))."\" onClick=\"oWidget{$this->m_iInputId}.AddObjects();\">m_sAttCode}{$this->m_sNameSuffix}_indicatorAdd\">\n"; diff --git a/js/linkswidget.js b/js/linkswidget.js index c29c9437e..f6fdcb9ab 100644 --- a/js/linkswidget.js +++ b/js/linkswidget.js @@ -452,6 +452,10 @@ function LinksWidget(id, sClass, sAttCode, iInputId, sSuffix, bDuplicates, oWizH } else { // Modifying a newly added link - the structure should already be up to date + if (iUniqueId < 0) + { + iUniqueId = -iUniqueId; + } me.aAdded[iUniqueId]['attr_' + sFormPrefix + sAttCode] = value; } }; From 2f9e050e2b527fc295509b13c0ac6dc8a62dccb6 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Thu, 20 Jun 2019 10:34:10 +0200 Subject: [PATCH 2/3] =?UTF-8?q?N=C2=B02323.4=20Fix=20regression=20introduc?= =?UTF-8?q?ed=20in=20previous=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current user picture was no longer displayed in the portal (cherry picked from commit 56b9eb6cf3c65a98f6772e4b849bfce4c1d4f858) --- core/ormdocument.class.inc.php | 2 ++ .../src/controllers/userprofilebrickcontroller.class.inc.php | 3 ++- .../portal/src/helpers/applicationhelper.class.inc.php | 5 ++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core/ormdocument.class.inc.php b/core/ormdocument.class.inc.php index 3ff796f8c..68d8d0368 100644 --- a/core/ormdocument.class.inc.php +++ b/core/ormdocument.class.inc.php @@ -126,6 +126,7 @@ class ormDocument */ public function GetDisplayURL($sClass, $Id, $sAttCode) { + // TODO: When refactoring this with the URLMaker system, mind to also change calls in the portal (look for the "p_object_document_display" route) return utils::GetAbsoluteUrlAppRoot() . "pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode"; } @@ -137,6 +138,7 @@ class ormDocument { // Compute a signature to reset the cache anytime the data changes (this is acceptable if used only with icon files) $sSignature = md5($this->GetData()); + // TODO: When refactoring this with the URLMaker system, mind to also change calls in the portal (look for the "p_object_document_display" route) return utils::GetAbsoluteUrlAppRoot() . "pages/ajax.document.php?operation=download_document&class=$sClass&id=$Id&field=$sAttCode&s=$sSignature&cache=86400"; } diff --git a/datamodels/2.x/itop-portal-base/portal/src/controllers/userprofilebrickcontroller.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/controllers/userprofilebrickcontroller.class.inc.php index d2d8ebdae..62e24a4dc 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/controllers/userprofilebrickcontroller.class.inc.php +++ b/datamodels/2.x/itop-portal-base/portal/src/controllers/userprofilebrickcontroller.class.inc.php @@ -284,7 +284,8 @@ class UserProfileBrickController extends BrickController $aFormData['error'] = $e->GetMessage(); } - $aFormData['picture_url'] = $oImage->GetDownloadURL(get_class($oCurContact), $oCurContact->GetKey(), $sPictureAttCode); + // TODO: This should be changed when refactoring the ormDocument GetDisplayUrl() and GetDownloadUrl() in iTop 2.8 + $aFormData['picture_url'] = $oApp['url_generator']->generate('p_object_document_display', array('sObjectClass' => get_class($oCurContact), 'sObjectId' => $oCurContact->GetKey(), 'sObjectField' => $sPictureAttCode, 'cache' => 86400, 't' => time())); $aFormData['validation'] = array( 'valid' => true, 'messages' => array() diff --git a/datamodels/2.x/itop-portal-base/portal/src/helpers/applicationhelper.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/helpers/applicationhelper.class.inc.php index 44e39a360..91f9ec59e 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/helpers/applicationhelper.class.inc.php +++ b/datamodels/2.x/itop-portal-base/portal/src/helpers/applicationhelper.class.inc.php @@ -632,7 +632,10 @@ class ApplicationHelper $oImage = $oContact->Get('picture'); if (is_object($oImage) && !$oImage->IsEmpty()) { - $sContactPhotoUrl = $oImage->GetDownloadURL(get_class($oContact), $oContact->GetKey(), 'picture'); + // Note: At this stage of runtime, the UrlGenerator context is not properly initialized (lacks the baseurl among other things). + // The Context is set later by the RouterListener during an event, so we manually put the base url with utils::GetAbsoluteUrlExecPage() + // TODO: This should be changed when refactoring the ormDocument GetDisplayUrl() and GetDownloadUrl() in iTop 2.8 + $sContactPhotoUrl = utils::GetAbsoluteUrlExecPage().$oApp['url_generator']->generate('p_object_document_display', array('sObjectClass' => get_class($oContact), 'sObjectId' => $oContact->GetKey(), 'sObjectField' => 'picture', 'cache' => 86400)); } else { From 93099ea3c76c199eb2510012ca6c7864c2cdba22 Mon Sep 17 00:00:00 2001 From: Molkobain Date: Fri, 21 Jun 2019 10:01:31 +0200 Subject: [PATCH 3/3] =?UTF-8?q?N=C2=B02323.5=20Fix=20regression=20introduc?= =?UTF-8?q?ed=20in=20previous=20commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Could not upload images in HTML field anymore --- pages/ajax.render.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pages/ajax.render.php b/pages/ajax.render.php index 7a91ee802..dcfa05e26 100644 --- a/pages/ajax.render.php +++ b/pages/ajax.render.php @@ -59,6 +59,9 @@ try case 'export_build': case 'export_cancel': case 'export_download': + case 'cke_img_upload': + case 'cke_upload_and_browse': + case 'cke_browse': $sRequestedPortalId = null; break;