mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°6935 - Migrate "object.xxx" operations / routes to Symfony routes
This commit is contained in:
@@ -26,7 +26,6 @@ use Combodo\iTop\Application\UI\DisplayBlock\BlockCsv\BlockCsv;
|
||||
use Combodo\iTop\Application\UI\DisplayBlock\BlockList\BlockList;
|
||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
use Combodo\iTop\Service\Router\Router;
|
||||
|
||||
require_once(APPROOT.'/application/utils.inc.php');
|
||||
|
||||
@@ -1848,7 +1847,6 @@ class MenuBlock extends DisplayBlock
|
||||
*/
|
||||
public function GetRenderContent(WebPage $oPage, array $aExtraParams, string $sId)
|
||||
{
|
||||
$oRouter = Router::GetInstance();
|
||||
$oRenderBlock = new UIContentBlock();
|
||||
|
||||
if ($this->m_sStyle == 'popup') // popup is a synonym of 'list' for backward compatibility
|
||||
@@ -2068,7 +2066,8 @@ class MenuBlock extends DisplayBlock
|
||||
if ($bIsModifyAllowed) {
|
||||
$aRegularActions['UI:Menu:Modify'] = array(
|
||||
'label' => Dict::S('UI:Menu:Modify'),
|
||||
'url' => $oRouter->GenerateUrl('object.modify', ['class' => $sClass, 'id' => $id]) . "{$sContext}#",
|
||||
// Can't use URL Generator (`$this->oUrlGenerator->generate("b_object_summary", [$sObjClass, $sObjKey])`) yet as we have to find how to inject it here
|
||||
'url' => "{$sRootUrl}app.php/object/modify/{$sClass}/{$id}{$sContext}#",
|
||||
) + $aActionParams;
|
||||
}
|
||||
if ($bIsDeleteAllowed) {
|
||||
|
||||
@@ -11,7 +11,6 @@ use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenuItem\Popov
|
||||
use Combodo\iTop\Application\UI\Base\tUIContentAreas;
|
||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
||||
use Combodo\iTop\Service\Router\Router;
|
||||
use DBObject;
|
||||
use Dict;
|
||||
use MetaModel;
|
||||
@@ -100,7 +99,6 @@ class ObjectSummary extends ObjectDetails
|
||||
*/
|
||||
private function ComputeActions()
|
||||
{
|
||||
$oRouter = Router::GetInstance();
|
||||
$oDetailsButton = null;
|
||||
// We can pass a DBObject to the UIBlock, so we check for the DisplayModifyForm method
|
||||
if(method_exists($this->oObject, 'DisplayModifyForm') && UserRights::IsActionAllowed($this->sClassName, UR_ACTION_MODIFY)) {
|
||||
@@ -113,7 +111,8 @@ class ObjectSummary extends ObjectDetails
|
||||
'_blank'
|
||||
);
|
||||
$oModifyButton = ButtonUIBlockFactory::MakeLinkNeutral(
|
||||
$oRouter->GenerateUrl('object.modify', ['class' => $this->sClassName, 'id' => $this->sObjectId]),
|
||||
// Can't use URL Generator (`$this->oUrlGenerator->generate("b_object_summary", [$sObjClass, $sObjKey])`) yet as we have to find how to inject it here
|
||||
"{$sRootUrl}app.php/object/modify/{$this->sClassName}/{$this->sObjectId}",
|
||||
Dict::S('UI:Menu:Modify'),
|
||||
'fas fa-external-link-alt',
|
||||
'_blank',
|
||||
|
||||
@@ -30,7 +30,12 @@ use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use Combodo\iTop\Application\WebPage\JsonPage;
|
||||
use MetaModel;
|
||||
use SecurityException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Combodo\iTop\Service\SummaryCard\SummaryCardService;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use UserRights;
|
||||
use utils;
|
||||
|
||||
@@ -42,30 +47,47 @@ use utils;
|
||||
* @since 3.1.0
|
||||
* @package Combodo\iTop\Controller\Base\Layout
|
||||
*/
|
||||
#[Route("/object", name: "b_object_")]
|
||||
class ObjectController extends AbstractController
|
||||
{
|
||||
public const ROUTE_NAMESPACE = 'object';
|
||||
/** @deprecated 3.2.0 N°6935 Replaced by Symfony route name prefix on the controller */
|
||||
//public const ROUTE_NAMESPACE = 'object';
|
||||
|
||||
/**
|
||||
* @throws \CoreException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \MySQLException
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \ConfigException
|
||||
* @throws \ApplicationException
|
||||
* @throws \MissingQueryArgument
|
||||
* @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $oUrlGenerator
|
||||
* @since 3.2.0 N°6935
|
||||
*/
|
||||
public function OperationNew()
|
||||
public function __construct(
|
||||
protected UrlGeneratorInterface $oUrlGenerator
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Symfony\Component\HttpFoundation\Request $oRequest
|
||||
* @param string $sClass Class of the datamodel object to create
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
|
||||
* @throws ApplicationException
|
||||
*/
|
||||
#[Route('/new/{sClass}', name: 'new')]
|
||||
public function OperationNew(Request $oRequest, string $sClass): Response
|
||||
{
|
||||
// Retrieve parameters
|
||||
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$sStateCode = utils::ReadParam('state', '');
|
||||
$bCheckSubClass = utils::ReadParam('checkSubclass', true);
|
||||
$oAppContext = new ApplicationContext();
|
||||
$oRouter = Router::GetInstance();
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
// Check parameters
|
||||
if (false === MetaModel::IsValidClass($sClass)) {
|
||||
throw new HttpException(Response::HTTP_NOT_FOUND, Dict::S('UI:ObjectDoesNotExist'));
|
||||
}
|
||||
|
||||
$oAppContext = new ApplicationContext();
|
||||
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$oPage = new AjaxPage('');
|
||||
} else {
|
||||
$oPage = new iTopWebPage('', $bPrintable);
|
||||
@@ -73,7 +95,6 @@ class ObjectController extends AbstractController
|
||||
$this->AddRequiredForModificationJsFilesToPage($oPage);
|
||||
}
|
||||
|
||||
|
||||
if (empty($sClass))
|
||||
{
|
||||
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'class'));
|
||||
@@ -133,7 +154,7 @@ class ObjectController extends AbstractController
|
||||
// - Update flags with parameters set in URL
|
||||
FormHelper::UpdateFlagsFromContext($oObjToClone, $aFormExtraParams);
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aFormExtraParams['js_handlers'] = [];
|
||||
$aFormExtraParams['noRelations'] = true;
|
||||
$aFormExtraParams['hide_transitions'] = true;
|
||||
@@ -187,9 +208,9 @@ JS;
|
||||
|
||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObjToClone, array(), $aFormExtraParams);
|
||||
} else {
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$oClassForm = cmdbAbstractObject::DisplayFormBlockSelectClassToCreate($sClass, MetaModel::GetName($sClass), $oAppContext, $aPossibleClasses, ['state' => $sStateCode]);
|
||||
$sCurrentUrl = $oRouter->GenerateUrl('object.new');
|
||||
$sCurrentUrl = $this->oUrlGenerator->generate('b_object_new');
|
||||
$oClassForm->SetOnSubmitJsCode(
|
||||
<<<JS
|
||||
let me = this;
|
||||
@@ -208,25 +229,35 @@ JS
|
||||
cmdbAbstractObject::DisplaySelectClassToCreate($sClass, $oPage, $oAppContext, $aPossibleClasses,['state' => $sStateCode]);
|
||||
}
|
||||
}
|
||||
return $oPage;
|
||||
|
||||
return $oPage->GenerateResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iTopWebPage|AjaxPage Object edit form in its webpage
|
||||
* @param \Symfony\Component\HttpFoundation\Request $oRequest
|
||||
* @param string $sClass Class of the datamodel object to modify
|
||||
* @param string $sId ID of the object to modify
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*
|
||||
* @throws \ApplicationException
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \SecurityException
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function OperationModify()
|
||||
#[Route('/modify/{sClass}/{sId}', name: 'modify')]
|
||||
public function OperationModify(Request $oRequest, string $sClass, string $sId): Response
|
||||
{
|
||||
// Retrieve and check parameters
|
||||
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$sId = utils::ReadParam('id', '');
|
||||
$sFormTitle = utils::ReadPostedParam('form_title', null, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||
|
||||
// Check parameters
|
||||
if (false === MetaModel::IsValidClass($sClass)) {
|
||||
throw new HttpException(Response::HTTP_NOT_FOUND, Dict::S('UI:ObjectDoesNotExist'));
|
||||
}
|
||||
|
||||
if (utils::IsNullOrEmptyString($sClass) || utils::IsNullOrEmptyString($sId))
|
||||
{
|
||||
throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'id'));
|
||||
@@ -254,7 +285,7 @@ JS
|
||||
$aFormExtraParams['form_title'] = $sFormTitle;
|
||||
}
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$oPage = new AjaxPage('');
|
||||
$aFormExtraParams['js_handlers'] = [];
|
||||
$aFormExtraParams['noRelations'] = true;
|
||||
@@ -321,21 +352,25 @@ JS;
|
||||
// Note: Code duplicated to the case 'apply_modify' in UI.php when a data integrity issue has been found
|
||||
$oObj->DisplayModifyForm($oPage, $aFormExtraParams); // wizard_container: Display the title above the form
|
||||
|
||||
return $oPage;
|
||||
return $oPage->GenerateResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iTopWebPage|JsonPage Object edit form in its webpage
|
||||
* @param \Symfony\Component\HttpFoundation\Request $oRequest
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*
|
||||
* @throws \ApplicationException
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \SecurityException
|
||||
*/
|
||||
public function OperationApplyNew()
|
||||
#[Route('/apply_new', name: 'apply_new')]
|
||||
public function OperationApplyNew(Request $oRequest): Response
|
||||
{
|
||||
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
||||
$aResult = [];
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$oPage = new JsonPage();
|
||||
$oPage->SetOutputDataOnly(true);
|
||||
$aResult['success'] = false;
|
||||
@@ -367,7 +402,7 @@ JS;
|
||||
$sUser = UserRights::GetUser();
|
||||
IssueLog::Error(__CLASS__.'::'.__METHOD__." : invalid transaction_id ! data: user='$sUser', class='$sClass'");
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => Dict::S('UI:Error:ObjectAlreadyCreated')];
|
||||
} else {
|
||||
$oErrorAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:Error:ObjectAlreadyCreated'));
|
||||
@@ -464,7 +499,7 @@ JS;
|
||||
}
|
||||
} else {
|
||||
// Nothing more to do
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aResult['success'] = true;
|
||||
$aResult['data'] = ['object' => ObjectRepository::ConvertObjectToArray($oObj, $sClass)];
|
||||
} else {
|
||||
@@ -476,7 +511,7 @@ JS;
|
||||
// Found issues, explain and give the user a second chance
|
||||
//
|
||||
$aIssues = $e->getIssues();
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => $e->getHtmlMessage()];
|
||||
} else {
|
||||
$sClassLabel = MetaModel::GetName($sClass);
|
||||
@@ -494,15 +529,18 @@ JS;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$oPage->SetData($aResult);
|
||||
}
|
||||
|
||||
return $oPage;
|
||||
return $oPage->GenerateResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iTopWebPage|JsonPage
|
||||
* @param \Symfony\Component\HttpFoundation\Request $oRequest
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*
|
||||
* @throws \ApplicationException
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \ConfigException
|
||||
@@ -511,10 +549,12 @@ JS;
|
||||
* @throws \DictExceptionMissingString
|
||||
* @throws \MySQLException
|
||||
*/
|
||||
public function OperationApplyModify(){
|
||||
public function OperationApplyModify(Request $oRequest): Response
|
||||
{
|
||||
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
||||
$aResult = [];
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$oPage = new JsonPage();
|
||||
$oPage->SetOutputDataOnly(true);
|
||||
$aResult['success'] = false;
|
||||
@@ -546,7 +586,7 @@ JS;
|
||||
{
|
||||
$bDisplayDetails = false;
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => Dict::S('UI:ObjectDoesNotExist')];
|
||||
} else {
|
||||
$oPage->set_title(Dict::S('UI:ErrorPageTitle'));
|
||||
@@ -572,7 +612,7 @@ JS;
|
||||
$sUser = UserRights::GetUser();
|
||||
IssueLog::Error(__CLASS__.'::'.__METHOD__." : invalid transaction_id ! data: user='$sUser', class='$sClass'");
|
||||
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => Dict::S('UI:Error:ObjectAlreadyUpdated')];
|
||||
} else {
|
||||
$oPage->set_title(Dict::Format('UI:ModificationPageTitle_Object_Class', $oObj->GetRawName(), $sClassLabel)); // Set title will take care of the encoding
|
||||
@@ -598,7 +638,7 @@ JS;
|
||||
|
||||
if (!$oObj->IsModified() && empty($aErrors))
|
||||
{
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => Dict::Format('UI:Class_Object_NotUpdated', MetaModel::GetName(get_class($oObj)), $oObj->GetName())];
|
||||
} else {
|
||||
$oPage->set_title(Dict::Format('UI:ModificationPageTitle_Object_Class', $oObj->GetRawName(), $sClassLabel)); // Set title will take care of the encoding
|
||||
@@ -646,7 +686,7 @@ JS;
|
||||
|
||||
$sMessage = Dict::Format('UI:Class_Object_Updated', MetaModel::GetName(get_class($oObj)), $oObj->GetName());
|
||||
$sSeverity = 'ok';
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aResult['success'] = true;
|
||||
}
|
||||
}
|
||||
@@ -656,7 +696,7 @@ JS;
|
||||
//
|
||||
$bDisplayDetails = false;
|
||||
$aIssues = $e->getIssues();
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => $e->getHtmlMessage()];
|
||||
} else {
|
||||
$oPage->AddHeaderMessage($e->getHtmlMessage(), 'message_error');
|
||||
@@ -667,7 +707,7 @@ JS;
|
||||
}
|
||||
catch (DeleteException $e)
|
||||
{
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$aResult['data'] = ['error_message' => Dict::Format('UI:Class_Object_NotUpdated', MetaModel::GetName(get_class($oObj)), $oObj->GetName())];
|
||||
} else {
|
||||
// Say two things:
|
||||
@@ -706,7 +746,7 @@ JS;
|
||||
// Nothing more to do
|
||||
$sMessage = isset($sMessage) ? $sMessage : '';
|
||||
$sSeverity = isset($sSeverity) ? $sSeverity : null;
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
;
|
||||
} else {
|
||||
ReloadAndDisplay($oPage, $oObj, 'update', $sMessage, $sSeverity);
|
||||
@@ -724,27 +764,38 @@ JS;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
if ($oRequest->isXmlHttpRequest()) {
|
||||
$oPage->SetData($aResult);
|
||||
}
|
||||
return $oPage;
|
||||
return $oPage->GenerateResponse();
|
||||
}
|
||||
|
||||
public function OperationSummary() {
|
||||
/**
|
||||
* @param \Symfony\Component\HttpFoundation\Request $oRequest
|
||||
* @param string $sClass Class of the datamodel object to view
|
||||
* @param string $sId ID of the datamodel object to view (note that friendlyname can also be used but is less efficient)
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
#[Route('/summary/{sClass}/{sId}', name: 'summary')]
|
||||
public function OperationSummary(Request $oRequest, string $sClass, string $sId): Response
|
||||
{
|
||||
$oPage = new AjaxPage('');
|
||||
|
||||
$sClass = utils::ReadParam('obj_class', '', false, utils::ENUM_SANITIZATION_FILTER_CLASS);
|
||||
$sObjectKey = utils::ReadParam('obj_key', 0, false);
|
||||
// Check parameters
|
||||
if (false === MetaModel::IsValidClass($sClass)) {
|
||||
throw new HttpException(Response::HTTP_NOT_FOUND, Dict::S('UI:ObjectDoesNotExist'));
|
||||
}
|
||||
|
||||
// - Check if we are allowed to see/make summary for this class
|
||||
if(SummaryCardService::IsAllowedForClass($sClass)){
|
||||
if (is_numeric($sObjectKey))
|
||||
if (is_numeric($sId))
|
||||
{
|
||||
$oObj = MetaModel::GetObject($sClass, $sObjectKey, false /* MustBeFound */);
|
||||
$oObj = MetaModel::GetObject($sClass, $sId, false /* MustBeFound */);
|
||||
}
|
||||
else
|
||||
{
|
||||
$oObj = MetaModel::GetObjectByName($sClass, $sObjectKey, false /* MustBeFound */);
|
||||
$oObj = MetaModel::GetObjectByName($sClass, $sId, false /* MustBeFound */);
|
||||
}
|
||||
|
||||
if($oObj !== null) {
|
||||
@@ -758,7 +809,7 @@ JS;
|
||||
->SetIsClosable(false)
|
||||
);
|
||||
}
|
||||
return $oPage;
|
||||
return $oPage->GenerateResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,9 +8,10 @@ namespace Combodo\iTop\Service\SummaryCard;
|
||||
|
||||
use appUserPreferences;
|
||||
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
||||
use Combodo\iTop\Service\Router\Router;
|
||||
use MetaModel;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use UserRights;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Class SummaryCardService
|
||||
@@ -19,10 +20,22 @@ use UserRights;
|
||||
*
|
||||
* @since 3.1.0
|
||||
*/
|
||||
class SummaryCardService {
|
||||
class SummaryCardService
|
||||
{
|
||||
/**
|
||||
* @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $oUrlGenerator
|
||||
*
|
||||
* @since 3.2.0 Add constructor and dependency injection of $oUrlGenerator
|
||||
*/
|
||||
public function __construct(
|
||||
protected UrlGeneratorInterface $oUrlGenerator
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $sObjClass
|
||||
* @param string $sObjClass
|
||||
* @param $sObjKey
|
||||
*
|
||||
* @return string
|
||||
@@ -30,8 +43,8 @@ class SummaryCardService {
|
||||
*/
|
||||
public static function GetHyperlinkMarkup(string $sObjClass, $sObjKey): string
|
||||
{
|
||||
$oRouter = Router::GetInstance();
|
||||
$sRoute = $oRouter->GenerateUrl("object.summary", ["obj_class" => $sObjClass, "obj_key" => $sObjKey]);
|
||||
// Can't use URL Generator (`$this->oUrlGenerator->generate("b_object_summary", [$sObjClass, $sObjKey])`) yet as we have to find how to inject it here
|
||||
$sRoute = utils::GetAbsoluteUrlAppRoot() . "app.php/object/summary/$sObjClass/$sObjKey";
|
||||
return
|
||||
<<<HTML
|
||||
data-tooltip-content="$sRoute"
|
||||
|
||||
Reference in New Issue
Block a user