mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 02:58:43 +02:00
Compare commits
9 Commits
feature/ph
...
feature/69
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94fb23d366 | ||
|
|
4e4b6c1ec2 | ||
|
|
451bab6957 | ||
|
|
85003e89eb | ||
|
|
5fb5f093e7 | ||
|
|
4c48b65e6b | ||
|
|
43d3a3bc67 | ||
|
|
1fee4372eb | ||
|
|
a4434afa0d |
@@ -79,6 +79,10 @@ gitGraph
|
|||||||
commit id: "2023-08-10" tag: "2.7.9"
|
commit id: "2023-08-10" tag: "2.7.9"
|
||||||
checkout support/3.1
|
checkout support/3.1
|
||||||
commit id: "2023-12-20" tag: "3.1.1"
|
commit id: "2023-12-20" tag: "3.1.1"
|
||||||
|
checkout support/2.7
|
||||||
|
commit id: "2024-01-17a" tag: "2.7.10"
|
||||||
|
checkout support/3.0
|
||||||
|
commit id: "2024-01-17b" tag: "3.0.4"
|
||||||
```
|
```
|
||||||
|
|
||||||
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).
|
To learn more, check the [iTop community versions history on the official wiki](https://www.itophub.io/wiki/page?id=latest:release:start).
|
||||||
|
|||||||
@@ -563,8 +563,8 @@ JS
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$bEditMode) {
|
if (!$bEditMode) {
|
||||||
$oPage->add_linked_script('../js/dashlet.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/dashlet.js');
|
||||||
$oPage->add_linked_script('../js/dashboard.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/dashboard.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $oDashboard;
|
return $oDashboard;
|
||||||
|
|||||||
@@ -326,6 +326,7 @@ class DataTable
|
|||||||
$sPagesLinks = implode('', $aPagesToDisplay);
|
$sPagesLinks = implode('', $aPagesToDisplay);
|
||||||
$sPagesList = '['.implode(',', array_keys($aPagesToDisplay)).']';
|
$sPagesList = '['.implode(',', array_keys($aPagesToDisplay)).']';
|
||||||
|
|
||||||
|
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||||
$sSelectionMode = ($iNbPages == 1) ? '' : 'positive';
|
$sSelectionMode = ($iNbPages == 1) ? '' : 'positive';
|
||||||
$sHtml =
|
$sHtml =
|
||||||
<<<EOF
|
<<<EOF
|
||||||
@@ -333,11 +334,11 @@ class DataTable
|
|||||||
<div $sPagerStyle>
|
<div $sPagerStyle>
|
||||||
<table id="pager{$this->iListId}" class="pager"><tr>
|
<table id="pager{$this->iListId}" class="pager"><tr>
|
||||||
<td>$sPages</td>
|
<td>$sPages</td>
|
||||||
<td><img src="../images/first.png" class="first"/></td>
|
<td><img src="{$sAppRootUrl}images/first.png" class="first"/>AAAA</td>
|
||||||
<td><img src="../images/prev.png" class="prev"/></td>
|
<td><img src="{$sAppRootUrl}images/prev.png" class="prev"/></td>
|
||||||
<td><span id="index">$sPagesLinks</span></td>
|
<td><span id="index">$sPagesLinks</span></td>
|
||||||
<td><img src="../images/next.png" class="next"/></td>
|
<td><img src="{$sAppRootUrl}images/next.png" class="next"/></td>
|
||||||
<td><img src="../images/last.png" class="last"/></td>
|
<td><img src="{$sAppRootUrl}images/last.png" class="last"/></td>
|
||||||
<td>$sPageSizeCombo</td>
|
<td>$sPageSizeCombo</td>
|
||||||
<td><span id="loading"> </span><input type="hidden" name="selectionMode" value="$sSelectionMode"></input>
|
<td><span id="loading"> </span><input type="hidden" name="selectionMode" value="$sSelectionMode"></input>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ use Combodo\iTop\Application\UI\DisplayBlock\BlockCsv\BlockCsv;
|
|||||||
use Combodo\iTop\Application\UI\DisplayBlock\BlockList\BlockList;
|
use Combodo\iTop\Application\UI\DisplayBlock\BlockList\BlockList;
|
||||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||||
use Combodo\iTop\Application\WebPage\WebPage;
|
use Combodo\iTop\Application\WebPage\WebPage;
|
||||||
use Combodo\iTop\Service\Router\Router;
|
|
||||||
|
|
||||||
require_once(APPROOT.'/application/utils.inc.php');
|
require_once(APPROOT.'/application/utils.inc.php');
|
||||||
|
|
||||||
@@ -570,7 +569,7 @@ class DisplayBlock
|
|||||||
} else {
|
} else {
|
||||||
// render it as an Ajax (asynchronous) call
|
// render it as an Ajax (asynchronous) call
|
||||||
$oHtml->AddCSSClass("loading");
|
$oHtml->AddCSSClass("loading");
|
||||||
$oHtml->AddHtml("<p><img src=\"../images/indicator_arrows.gif\"> ".Dict::S('UI:Loading').'</p>');
|
$oHtml->AddHtml("<p><img src=\"".utils::GetAbsoluteUrlAppRoot()."images/indicator_arrows.gif\"> ".Dict::S('UI:Loading').'</p>');
|
||||||
$oPage->add_script('
|
$oPage->add_script('
|
||||||
$.post("ajax.render.php?style='.$this->m_sStyle.'",
|
$.post("ajax.render.php?style='.$this->m_sStyle.'",
|
||||||
{ operation: "ajax", filter: "'.$sFilter.'", extra_params: "'.$sExtraParams.'" },
|
{ operation: "ajax", filter: "'.$sFilter.'", extra_params: "'.$sExtraParams.'" },
|
||||||
@@ -1848,7 +1847,6 @@ class MenuBlock extends DisplayBlock
|
|||||||
*/
|
*/
|
||||||
public function GetRenderContent(WebPage $oPage, array $aExtraParams, string $sId)
|
public function GetRenderContent(WebPage $oPage, array $aExtraParams, string $sId)
|
||||||
{
|
{
|
||||||
$oRouter = Router::GetInstance();
|
|
||||||
$oRenderBlock = new UIContentBlock();
|
$oRenderBlock = new UIContentBlock();
|
||||||
|
|
||||||
if ($this->m_sStyle == 'popup') // popup is a synonym of 'list' for backward compatibility
|
if ($this->m_sStyle == 'popup') // popup is a synonym of 'list' for backward compatibility
|
||||||
@@ -2068,7 +2066,8 @@ class MenuBlock extends DisplayBlock
|
|||||||
if ($bIsModifyAllowed) {
|
if ($bIsModifyAllowed) {
|
||||||
$aRegularActions['UI:Menu:Modify'] = array(
|
$aRegularActions['UI:Menu:Modify'] = array(
|
||||||
'label' => Dict::S('UI:Menu:Modify'),
|
'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;
|
) + $aActionParams;
|
||||||
}
|
}
|
||||||
if ($bIsDeleteAllowed) {
|
if ($bIsDeleteAllowed) {
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ class ExcelExporter
|
|||||||
{
|
{
|
||||||
if ($this->sOutputFilePath == null)
|
if ($this->sOutputFilePath == null)
|
||||||
{
|
{
|
||||||
return APPROOT.'data/bulk_export/'.$this->sToken.'.xlsx';
|
return utils::GetDataPath().'bulk_export/'.$this->sToken.'.xlsx';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -313,14 +313,14 @@ class ExcelExporter
|
|||||||
|
|
||||||
public static function GetExcelFileFromToken($sToken)
|
public static function GetExcelFileFromToken($sToken)
|
||||||
{
|
{
|
||||||
return @file_get_contents(APPROOT.'data/bulk_export/'.$sToken.'.xlsx');
|
return @file_get_contents(utils::GetDataPath().'bulk_export/'.$sToken.'.xlsx');
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function CleanupFromToken($sToken)
|
public static function CleanupFromToken($sToken)
|
||||||
{
|
{
|
||||||
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.status');
|
@unlink(utils::GetDataPath().'bulk_export/'.$sToken.'.status');
|
||||||
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.data');
|
@unlink(utils::GetDataPath().'bulk_export/'.$sToken.'.data');
|
||||||
@unlink(APPROOT.'data/bulk_export/'.$sToken.'.xlsx');
|
@unlink(utils::GetDataPath().'bulk_export/'.$sToken.'.xlsx');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Cleanup()
|
public function Cleanup()
|
||||||
@@ -334,7 +334,7 @@ class ExcelExporter
|
|||||||
*/
|
*/
|
||||||
public static function CleanupOldFiles()
|
public static function CleanupOldFiles()
|
||||||
{
|
{
|
||||||
$aFiles = glob(APPROOT.'data/bulk_export/*.*');
|
$aFiles = glob(utils::GetDataPath().'bulk_export/*.*');
|
||||||
$iDelay = MetaModel::GetConfig()->Get('xlsx_exporter_cleanup_old_files_delay');
|
$iDelay = MetaModel::GetConfig()->Get('xlsx_exporter_cleanup_old_files_delay');
|
||||||
|
|
||||||
if($iDelay > 0)
|
if($iDelay > 0)
|
||||||
@@ -416,14 +416,14 @@ class ExcelExporter
|
|||||||
|
|
||||||
protected function CheckDataDir()
|
protected function CheckDataDir()
|
||||||
{
|
{
|
||||||
if(!is_dir(APPROOT."data/bulk_export"))
|
if(!is_dir(utils::GetDataPath()."bulk_export"))
|
||||||
{
|
{
|
||||||
@mkdir(APPROOT."data/bulk_export", 0777, true /* recursive */);
|
@mkdir(utils::GetDataPath()."bulk_export", 0777, true /* recursive */);
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
}
|
}
|
||||||
if (!is_writable(APPROOT."data/bulk_export"))
|
if (!is_writable(utils::GetDataPath()."bulk_export"))
|
||||||
{
|
{
|
||||||
throw new Exception('Data directory "'.APPROOT.'data/bulk_export" could not be written.');
|
throw new Exception('Data directory "'.utils::GetDataPath().'bulk_export" could not be written.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,12 +433,12 @@ class ExcelExporter
|
|||||||
{
|
{
|
||||||
$sToken = $this->sToken;
|
$sToken = $this->sToken;
|
||||||
}
|
}
|
||||||
return APPROOT."data/bulk_export/$sToken.status";
|
return utils::GetDataPath()."bulk_export/$sToken.status";
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetDataFile()
|
protected function GetDataFile()
|
||||||
{
|
{
|
||||||
return APPROOT.'data/bulk_export/'.$this->sToken.'.data';
|
return utils::GetDataPath().'bulk_export/'.$this->sToken.'.data';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function GetNewToken()
|
protected function GetNewToken()
|
||||||
|
|||||||
@@ -232,12 +232,13 @@ class DisplayTemplate
|
|||||||
static public function UnitTest()
|
static public function UnitTest()
|
||||||
{
|
{
|
||||||
require_once(APPROOT.'/application/startup.inc.php');
|
require_once(APPROOT.'/application/startup.inc.php');
|
||||||
|
|
||||||
|
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||||
$sTemplate = '<div class="page_header">
|
$sTemplate = '<div class="page_header">
|
||||||
<div class="actions_details"><a href="#"><span>Actions</span></a></div>
|
<div class="actions_details"><a href="#"><span>Actions</span></a></div>
|
||||||
<h1>$class$: <span class="hilite">$name$</span></h1>
|
<h1>$class$: <span class="hilite">$name$</span></h1>
|
||||||
</div>
|
</div>
|
||||||
<img src="../../images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
|
<img src="'.$sAppRootUrl.'images/connect_to_network.png" style="margin-top:-10px; margin-right:10px; float:right">
|
||||||
<itoptabs>
|
<itoptabs>
|
||||||
<itoptab name="Interfaces">
|
<itoptab name="Interfaces">
|
||||||
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT Interface AS i WHERE i.device_id = $id$</itopblock>
|
<itopblock blockclass="DisplayBlock" type="list" encoding="text/oql">SELECT Interface AS i WHERE i.device_id = $id$</itopblock>
|
||||||
@@ -350,7 +351,8 @@ class ObjectDetailsTemplate extends DisplayTemplate
|
|||||||
if ($iFlags & OPT_ATT_SLAVE)
|
if ($iFlags & OPT_ATT_SLAVE)
|
||||||
{
|
{
|
||||||
$iSynchroFlags = $this->m_oObj->GetSynchroReplicaFlags($sAttCode, $aReasons);
|
$iSynchroFlags = $this->m_oObj->GetSynchroReplicaFlags($sAttCode, $aReasons);
|
||||||
$sSynchroIcon = " <img id=\"synchro_$iInputId\" src=\"../images/transp-lock.png\" style=\"vertical-align:middle\"/>";
|
$sAppRooturl = utils::GetAbsoluteUrlAppRoot();
|
||||||
|
$sSynchroIcon = " <img id=\"synchro_$iInputId\" src=\"{$sAppRooturl}images/transp-lock.png\" style=\"vertical-align:middle\"/>";
|
||||||
$sTip = '';
|
$sTip = '';
|
||||||
foreach($aReasons as $aRow)
|
foreach($aReasons as $aRow)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ class privUITransactionFile
|
|||||||
*/
|
*/
|
||||||
public static function GetNewTransactionId()
|
public static function GetNewTransactionId()
|
||||||
{
|
{
|
||||||
if (!is_dir(APPROOT.'data/transactions'))
|
if (!is_dir(utils::GetDataPath().'transactions'))
|
||||||
{
|
{
|
||||||
if (!is_writable(APPROOT.'data'))
|
if (!is_writable(APPROOT.'data'))
|
||||||
{
|
{
|
||||||
@@ -236,22 +236,22 @@ class privUITransactionFile
|
|||||||
}
|
}
|
||||||
// condition avoids race condition N°2345
|
// condition avoids race condition N°2345
|
||||||
// See https://github.com/kalessil/phpinspectionsea/blob/master/docs/probable-bugs.md#mkdir-race-condition
|
// See https://github.com/kalessil/phpinspectionsea/blob/master/docs/probable-bugs.md#mkdir-race-condition
|
||||||
if (!mkdir($concurrentDirectory = APPROOT.'data/transactions') && !is_dir($concurrentDirectory))
|
if (!mkdir($concurrentDirectory = utils::GetDataPath().'transactions') && !is_dir($concurrentDirectory))
|
||||||
{
|
{
|
||||||
throw new Exception('Failed to create the directory "'.APPROOT.'data/transactions". Ajust the rights on the parent directory or let an administrator create the transactions directory and give the web sever enough rights to write into it.');
|
throw new Exception('Failed to create the directory "'.utils::GetDataPath().'transactions". Ajust the rights on the parent directory or let an administrator create the transactions directory and give the web sever enough rights to write into it.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_writable(APPROOT.'data/transactions'))
|
if (!is_writable(utils::GetDataPath().'transactions'))
|
||||||
{
|
{
|
||||||
throw new Exception('The directory "'.APPROOT.'data/transactions" must be writable to the application.');
|
throw new Exception('The directory "'.utils::GetDataPath().'transactions" must be writable to the application.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$iCurrentUserId = static::GetCurrentUserId();
|
$iCurrentUserId = static::GetCurrentUserId();
|
||||||
|
|
||||||
self::CleanupOldTransactions();
|
self::CleanupOldTransactions();
|
||||||
|
|
||||||
$sTransactionIdFullPath = tempnam(APPROOT.'data/transactions', static::GetUserPrefix());
|
$sTransactionIdFullPath = tempnam(utils::GetDataPath().'transactions', static::GetUserPrefix());
|
||||||
file_put_contents($sTransactionIdFullPath, $iCurrentUserId, LOCK_EX);
|
file_put_contents($sTransactionIdFullPath, $iCurrentUserId, LOCK_EX);
|
||||||
|
|
||||||
$sTransactionIdFileName = basename($sTransactionIdFullPath);
|
$sTransactionIdFileName = basename($sTransactionIdFullPath);
|
||||||
@@ -274,8 +274,8 @@ class privUITransactionFile
|
|||||||
*/
|
*/
|
||||||
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
public static function IsTransactionValid($id, $bRemoveTransaction = true)
|
||||||
{
|
{
|
||||||
// Constraint the transaction file within APPROOT.'data/transactions'
|
// Constraint the transaction file within utils::GetDataPath().'transactions'
|
||||||
$sTransactionDir = realpath(APPROOT.'data/transactions');
|
$sTransactionDir = realpath(utils::GetDataPath().'transactions');
|
||||||
$sFilepath = utils::RealPath($sTransactionDir.'/'.$id, $sTransactionDir);
|
$sFilepath = utils::RealPath($sTransactionDir.'/'.$id, $sTransactionDir);
|
||||||
if (($sFilepath === false) || (strlen($sTransactionDir) == strlen($sFilepath)))
|
if (($sFilepath === false) || (strlen($sTransactionDir) == strlen($sFilepath)))
|
||||||
{
|
{
|
||||||
@@ -348,7 +348,7 @@ class privUITransactionFile
|
|||||||
|
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
$iLimit = time() - 24*3600;
|
$iLimit = time() - 24*3600;
|
||||||
$sPattern = $sTransactionDir ? "$sTransactionDir/*" : APPROOT.'data/transactions/*';
|
$sPattern = $sTransactionDir ? "$sTransactionDir/*" : utils::GetDataPath().'transactions/*';
|
||||||
$aTransactions = glob($sPattern);
|
$aTransactions = glob($sPattern);
|
||||||
foreach($aTransactions as $sFileName)
|
foreach($aTransactions as $sFileName)
|
||||||
{
|
{
|
||||||
@@ -368,7 +368,7 @@ class privUITransactionFile
|
|||||||
{
|
{
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
$aResult = array();
|
$aResult = array();
|
||||||
$aTransactions = glob(APPROOT.'data/transactions/'.self::GetUserPrefix().'*');
|
$aTransactions = glob(utils::GetDataPath().'transactions/'.self::GetUserPrefix().'*');
|
||||||
foreach($aTransactions as $sFileName)
|
foreach($aTransactions as $sFileName)
|
||||||
{
|
{
|
||||||
$aResult[] = date('Y-m-d H:i:s', filemtime($sFileName)).' - '.basename($sFileName);
|
$aResult[] = date('Y-m-d H:i:s', filemtime($sFileName)).' - '.basename($sFileName);
|
||||||
|
|||||||
@@ -161,8 +161,8 @@ class UIExtKeyWidget
|
|||||||
public function DisplaySelect(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), &$sInputType = '')
|
public function DisplaySelect(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, DBObjectset $oAllowedValues, $value, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), &$sInputType = '')
|
||||||
{
|
{
|
||||||
$sTitle = addslashes($sTitle);
|
$sTitle = addslashes($sTitle);
|
||||||
$oPage->add_linked_script('../js/extkeywidget.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/extkeywidget.js');
|
||||||
$oPage->add_linked_script('../js/forms-json-utils.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/forms-json-utils.js');
|
||||||
|
|
||||||
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_MODIFY) && $bAllowTargetCreation);
|
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_MODIFY) && $bAllowTargetCreation);
|
||||||
$bExtensions = true;
|
$bExtensions = true;
|
||||||
@@ -368,7 +368,7 @@ JS
|
|||||||
*/
|
*/
|
||||||
public function DisplayRadio(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, DBObjectset $oAllowedValues, $value, $sFieldName, $sDisplayStyle)
|
public function DisplayRadio(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, DBObjectset $oAllowedValues, $value, $sFieldName, $sDisplayStyle)
|
||||||
{
|
{
|
||||||
$oPage->add_linked_script('../js/forms-json-utils.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/forms-json-utils.js');
|
||||||
|
|
||||||
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
|
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
|
||||||
$bExtensions = true;
|
$bExtensions = true;
|
||||||
@@ -477,8 +477,8 @@ JS
|
|||||||
$this->bSearchMode = $bSearchMode;
|
$this->bSearchMode = $bSearchMode;
|
||||||
}
|
}
|
||||||
$sTitle = addslashes($sTitle);
|
$sTitle = addslashes($sTitle);
|
||||||
$oPage->add_linked_script('../js/extkeywidget.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/extkeywidget.js');
|
||||||
$oPage->add_linked_script('../js/forms-json-utils.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/forms-json-utils.js');
|
||||||
|
|
||||||
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
|
$bCreate = (!$this->bSearchMode) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
|
||||||
$bExtensions = true;
|
$bExtensions = true;
|
||||||
|
|||||||
@@ -1446,7 +1446,7 @@ EOF
|
|||||||
<<<EOF
|
<<<EOF
|
||||||
function OnTruncatedHistoryToggle(bShowAll)
|
function OnTruncatedHistoryToggle(bShowAll)
|
||||||
{
|
{
|
||||||
$('#csv_history_reload').html('<img src="../images/indicator.gif"/>');
|
$('#csv_history_reload').html('<img src="' + GetAbsoluteUrlAppRoot() + 'images/indicator.gif"/>');
|
||||||
$.get(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?{$sAppContext}', {operation: 'displayCSVHistory', showall: bShowAll}, function(data)
|
$.get(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?{$sAppContext}', {operation: 'displayCSVHistory', showall: bShowAll}, function(data)
|
||||||
{
|
{
|
||||||
$('#$sAjaxDivId').html(data);
|
$('#$sAjaxDivId').html(data);
|
||||||
|
|||||||
@@ -474,14 +474,14 @@ abstract class BulkExport
|
|||||||
*/
|
*/
|
||||||
protected function MakeTmpFile($sExtension)
|
protected function MakeTmpFile($sExtension)
|
||||||
{
|
{
|
||||||
if(!is_dir(APPROOT."data/bulk_export"))
|
if(!is_dir(utils::GetDataPath()."bulk_export"))
|
||||||
{
|
{
|
||||||
@mkdir(APPROOT."data/bulk_export", 0777, true /* recursive */);
|
@mkdir(utils::GetDataPath()."bulk_export", 0777, true /* recursive */);
|
||||||
clearstatcache();
|
clearstatcache();
|
||||||
}
|
}
|
||||||
if (!is_writable(APPROOT."data/bulk_export"))
|
if (!is_writable(utils::GetDataPath()."bulk_export"))
|
||||||
{
|
{
|
||||||
throw new Exception('Data directory "'.APPROOT.'data/bulk_export" could not be written.');
|
throw new Exception('Data directory "'.utils::GetDataPath().'bulk_export" could not be written.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$iNum = rand();
|
$iNum = rand();
|
||||||
@@ -489,7 +489,7 @@ abstract class BulkExport
|
|||||||
{
|
{
|
||||||
$iNum++;
|
$iNum++;
|
||||||
$sToken = sprintf("%08x", $iNum);
|
$sToken = sprintf("%08x", $iNum);
|
||||||
$sFileName = APPROOT."data/bulk_export/$sToken.".$sExtension;
|
$sFileName = utils::GetDataPath()."bulk_export/$sToken.".$sExtension;
|
||||||
$hFile = @fopen($sFileName, 'x');
|
$hFile = @fopen($sFileName, 'x');
|
||||||
}
|
}
|
||||||
while($hFile === false);
|
while($hFile === false);
|
||||||
|
|||||||
@@ -1552,13 +1552,13 @@ abstract class DBSearch
|
|||||||
}
|
}
|
||||||
|
|
||||||
$sLogFile = 'queries.latest';
|
$sLogFile = 'queries.latest';
|
||||||
file_put_contents(APPROOT.'data/'.$sLogFile.'.html', $sHtml);
|
file_put_contents(utils::GetDataPath().$sLogFile.'.html', $sHtml);
|
||||||
|
|
||||||
$sLog = "<?php\n\$aQueriesLog = ".var_export(self::$m_aQueriesLog, true).";";
|
$sLog = "<?php\n\$aQueriesLog = ".var_export(self::$m_aQueriesLog, true).";";
|
||||||
file_put_contents(APPROOT.'data/'.$sLogFile.'.log', $sLog);
|
file_put_contents(utils::GetDataPath().$sLogFile.'.log', $sLog);
|
||||||
|
|
||||||
// Cumulate the queries
|
// Cumulate the queries
|
||||||
$sAllQueries = APPROOT.'data/queries.log';
|
$sAllQueries = utils::GetDataPath().'queries.log';
|
||||||
if (file_exists($sAllQueries))
|
if (file_exists($sAllQueries))
|
||||||
{
|
{
|
||||||
// Merge the new queries into the existing log
|
// Merge the new queries into the existing log
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ class ormStopWatch
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$aProperties['Elapsed'] = 'running <img src="../images/indicator.gif">';
|
$aProperties['Elapsed'] = 'running <img src="' . utils::GetAbsoluteUrlAppRoot() . 'images/indicator.gif">';
|
||||||
}
|
}
|
||||||
|
|
||||||
$aProperties['Started'] = $oAttDef->SecondsToDate($this->iStarted);
|
$aProperties['Started'] = $oAttDef->SecondsToDate($this->iStarted);
|
||||||
|
|||||||
@@ -500,17 +500,17 @@ EOF
|
|||||||
if (file_exists($sDotExecutable))
|
if (file_exists($sDotExecutable))
|
||||||
{
|
{
|
||||||
// create the file with Graphviz
|
// create the file with Graphviz
|
||||||
if (!is_dir(APPROOT."data"))
|
if (!is_dir(utils::GetDataPath()))
|
||||||
{
|
{
|
||||||
@mkdir(APPROOT."data");
|
@mkdir(utils::GetDataPath());
|
||||||
}
|
}
|
||||||
if (!is_dir(APPROOT."data/tmp"))
|
if (!is_dir(utils::GetDataPath()."tmp"))
|
||||||
{
|
{
|
||||||
@mkdir(APPROOT."data/tmp");
|
@mkdir(utils::GetDataPath()."tmp");
|
||||||
}
|
}
|
||||||
$sImageFilePath = tempnam(APPROOT."data/tmp", 'png-');
|
$sImageFilePath = tempnam(utils::GetDataPath()."tmp", 'png-');
|
||||||
$sDotDescription = $this->GetDotDescription();
|
$sDotDescription = $this->GetDotDescription();
|
||||||
$sDotFilePath = tempnam(APPROOT."data/tmp", 'dot-');
|
$sDotFilePath = tempnam(utils::GetDataPath()."tmp", 'dot-');
|
||||||
|
|
||||||
$rFile = @fopen($sDotFilePath, "w");
|
$rFile = @fopen($sDotFilePath, "w");
|
||||||
@fwrite($rFile, $sDotDescription);
|
@fwrite($rFile, $sDotDescription);
|
||||||
@@ -556,17 +556,17 @@ EOF
|
|||||||
if (file_exists($sDotExecutable))
|
if (file_exists($sDotExecutable))
|
||||||
{
|
{
|
||||||
// create the file with Graphviz
|
// create the file with Graphviz
|
||||||
if (!is_dir(APPROOT."data"))
|
if (!is_dir(utils::GetDataPath()))
|
||||||
{
|
{
|
||||||
@mkdir(APPROOT."data");
|
@mkdir(utils::GetDataPath());
|
||||||
}
|
}
|
||||||
if (!is_dir(APPROOT."data/tmp"))
|
if (!is_dir(utils::GetDataPath()."tmp"))
|
||||||
{
|
{
|
||||||
@mkdir(APPROOT."data/tmp");
|
@mkdir(utils::GetDataPath()."tmp");
|
||||||
}
|
}
|
||||||
$sXdotFilePath = tempnam(APPROOT."data/tmp", 'xdot-');
|
$sXdotFilePath = tempnam(utils::GetDataPath()."tmp", 'xdot-');
|
||||||
$sDotDescription = $this->GetDotDescription(true); // true => don't put (localized) labels in the file, since it makes it harder to parse
|
$sDotDescription = $this->GetDotDescription(true); // true => don't put (localized) labels in the file, since it makes it harder to parse
|
||||||
$sDotFilePath = tempnam(APPROOT."data/tmp", 'dot-');
|
$sDotFilePath = tempnam(utils::GetDataPath()."tmp", 'dot-');
|
||||||
|
|
||||||
$rFile = @fopen($sDotFilePath, "w");
|
$rFile = @fopen($sDotFilePath, "w");
|
||||||
@fwrite($rFile, $sDotDescription);
|
@fwrite($rFile, $sDotDescription);
|
||||||
|
|||||||
@@ -185,6 +185,7 @@ abstract class AbstractAttachmentsRenderer
|
|||||||
{
|
{
|
||||||
$sClass = $this->sObjClass;
|
$sClass = $this->sObjClass;
|
||||||
$sId = $this->iObjKey;
|
$sId = $this->iObjKey;
|
||||||
|
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||||
$iMaxUploadInBytes = AttachmentPlugIn::GetMaxUploadSize();
|
$iMaxUploadInBytes = AttachmentPlugIn::GetMaxUploadSize();
|
||||||
$sMaxUploadLabel = AttachmentPlugIn::GetMaxUpload();
|
$sMaxUploadLabel = AttachmentPlugIn::GetMaxUpload();
|
||||||
$sFileTooBigLabel = Dict::Format('Attachments:Error:FileTooLarge', $sMaxUploadLabel);
|
$sFileTooBigLabel = Dict::Format('Attachments:Error:FileTooLarge', $sMaxUploadLabel);
|
||||||
@@ -195,7 +196,7 @@ abstract class AbstractAttachmentsRenderer
|
|||||||
$oAddButton = FileSelectUIBlockFactory::MakeStandard('file', 'file');
|
$oAddButton = FileSelectUIBlockFactory::MakeStandard('file', 'file');
|
||||||
$oAddButton->SetShowFilename(false);
|
$oAddButton->SetShowFilename(false);
|
||||||
$this->oPage->AddUiBlock($oAddButton);
|
$this->oPage->AddUiBlock($oAddButton);
|
||||||
$this->oPage->add('<span style="display:none;" id="attachment_loading"><img src="../images/indicator.gif"></span> '.$sMaxUploadLabel);
|
$this->oPage->add('<span style="display:none;" id="attachment_loading"><img src="' . $sAppRootUrl . 'images/indicator.gif"></span> ' . $sMaxUploadLabel);
|
||||||
$this->oPage->add('</div>');
|
$this->oPage->add('</div>');
|
||||||
$this->oPage->add('<div class="ibo-attachment--upload-file--drop-zone-hint ibo-svg-illustration--container">');
|
$this->oPage->add('<div class="ibo-attachment--upload-file--drop-zone-hint ibo-svg-illustration--container">');
|
||||||
$this->oPage->add(file_get_contents(APPROOT.'images/illustrations/undraw_upload.svg'));
|
$this->oPage->add(file_get_contents(APPROOT.'images/illustrations/undraw_upload.svg'));
|
||||||
@@ -342,7 +343,7 @@ abstract class AbstractAttachmentsRenderer
|
|||||||
$('.attachment a[href="'+sSrc+'"]').parent().addClass('image-in-use').find('img').wrap('<div class="image-in-use-wrapper" style="position:relative;display:inline-block;"></div>');
|
$('.attachment a[href="'+sSrc+'"]').parent().addClass('image-in-use').find('img').wrap('<div class="image-in-use-wrapper" style="position:relative;display:inline-block;"></div>');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
$('.image-in-use-wrapper').append('<div style="position:absolute;top:0;left:0;"><img src="../images/transp-lock.png"></div>');
|
$('.image-in-use-wrapper').append('<div style="position:absolute;top:0;left:0;"><img src="' + GetAbsoluteUrlModulesRoot() + 'images/transp-lock.png"></div>');
|
||||||
}, 200 );
|
}, 200 );
|
||||||
JS
|
JS
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ try
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
set_time_limit(0);
|
set_time_limit(0);
|
||||||
$oBB = new BackupExec(APPROOT.'data/backups/manual/', 0 /*iRetentionCount*/);
|
$oBB = new BackupExec(utils::GetDataPath().'backups/manual/', 0 /*iRetentionCount*/);
|
||||||
$sRes = $oBB->Process(time() + 36000); // 10 hours to complete should be sufficient!
|
$sRes = $oBB->Process(time() + 36000); // 10 hours to complete should be sufficient!
|
||||||
}
|
}
|
||||||
catch (Exception $e)
|
catch (Exception $e)
|
||||||
@@ -185,7 +185,7 @@ try
|
|||||||
$oDBRS = new DBRestore($oItopConfig);
|
$oDBRS = new DBRestore($oItopConfig);
|
||||||
$oDBRS->SetMySQLBinDir($sMySQLBinDir);
|
$oDBRS->SetMySQLBinDir($sMySQLBinDir);
|
||||||
|
|
||||||
$sBackupDir = APPROOT.'data/backups/';
|
$sBackupDir = utils::GetDataPath().'backups/';
|
||||||
$sBackupFile = $sBackupDir.$sFile;
|
$sBackupFile = $sBackupDir.$sFile;
|
||||||
$sRes = $oDBRS->RestoreFromCompressedBackup($sBackupFile, $sEnvironment);
|
$sRes = $oDBRS->RestoreFromCompressedBackup($sBackupFile, $sEnvironment);
|
||||||
|
|
||||||
@@ -210,7 +210,7 @@ try
|
|||||||
}
|
}
|
||||||
$sFile = utils::ReadParam('file', '', false, 'raw_data');
|
$sFile = utils::ReadParam('file', '', false, 'raw_data');
|
||||||
$oBackup = new DBBackupScheduled();
|
$oBackup = new DBBackupScheduled();
|
||||||
$sBackupDir = APPROOT.'data/backups/';
|
$sBackupDir = utils::GetDataPath().'backups/';
|
||||||
$sBackupFilePath = utils::RealPath($sBackupDir.$sFile, $sBackupDir);
|
$sBackupFilePath = utils::RealPath($sBackupDir.$sFile, $sBackupDir);
|
||||||
if ($sBackupFilePath === false)
|
if ($sBackupFilePath === false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ class DBRestore extends DBBackup
|
|||||||
|
|
||||||
// Load the database
|
// Load the database
|
||||||
//
|
//
|
||||||
$sDataDir = APPROOT.'data/tmp-backup-'.rand(10000, getrandmax());
|
$sDataDir = utils::GetDataPath().'tmp-backup-'.rand(10000, getrandmax());
|
||||||
|
|
||||||
SetupUtils::builddir($sDataDir); // Here is the directory
|
SetupUtils::builddir($sDataDir); // Here is the directory
|
||||||
$oArchive->extractTo($sDataDir);
|
$oArchive->extractTo($sDataDir);
|
||||||
@@ -164,7 +164,7 @@ class DBRestore extends DBBackup
|
|||||||
|
|
||||||
// Update the code
|
// Update the code
|
||||||
//
|
//
|
||||||
$sDeltaFile = APPROOT.'data/'.$sEnvironment.'.delta.xml';
|
$sDeltaFile = utils::GetDataPath().$sEnvironment.'.delta.xml';
|
||||||
|
|
||||||
if (is_file($sDataDir.'/delta.xml')) {
|
if (is_file($sDataDir.'/delta.xml')) {
|
||||||
// Extract and rename delta.xml => <env>.delta.xml;
|
// Extract and rename delta.xml => <env>.delta.xml;
|
||||||
@@ -172,15 +172,15 @@ class DBRestore extends DBBackup
|
|||||||
} else {
|
} else {
|
||||||
@unlink($sDeltaFile);
|
@unlink($sDeltaFile);
|
||||||
}
|
}
|
||||||
if (is_dir(APPROOT.'data/production-modules/')) {
|
if (is_dir(utils::GetDataPath().'production-modules/')) {
|
||||||
try {
|
try {
|
||||||
SetupUtils::rrmdir(APPROOT.'data/production-modules/');
|
SetupUtils::rrmdir(utils::GetDataPath().'production-modules/');
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
throw new BackupException("Can't remove production-modules dir", 0, $e);
|
throw new BackupException("Can't remove production-modules dir", 0, $e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (is_dir($sDataDir.'/production-modules')) {
|
if (is_dir($sDataDir.'/production-modules')) {
|
||||||
rename($sDataDir.'/production-modules', APPROOT.'data/production-modules/');
|
rename($sDataDir.'/production-modules', utils::GetDataPath().'production-modules/');
|
||||||
}
|
}
|
||||||
|
|
||||||
$sConfigFile = APPROOT.'conf/'.$sEnvironment.'/config-itop.php';
|
$sConfigFile = APPROOT.'conf/'.$sEnvironment.'/config-itop.php';
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ class BackupExec extends AbstractWeeklyScheduledProcess
|
|||||||
{
|
{
|
||||||
if (is_null($sBackupDir))
|
if (is_null($sBackupDir))
|
||||||
{
|
{
|
||||||
$this->sBackupDir = APPROOT.'data/backups/auto/';
|
$this->sBackupDir = utils::GetDataPath().'backups/auto/';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ try {
|
|||||||
// Destination directory
|
// Destination directory
|
||||||
//
|
//
|
||||||
// Make sure the target directory exists and is writeable
|
// Make sure the target directory exists and is writeable
|
||||||
$sBackupDir = realpath(APPROOT.'data/backups/');
|
$sBackupDir = realpath(utils::GetDataPath().'backups/');
|
||||||
SetupUtils::builddir($sBackupDir);
|
SetupUtils::builddir($sBackupDir);
|
||||||
if (!is_dir($sBackupDir)) {
|
if (!is_dir($sBackupDir)) {
|
||||||
$oBlockForChecks->AddSubBlock(
|
$oBlockForChecks->AddSubBlock(
|
||||||
|
|||||||
@@ -486,7 +486,7 @@ final class CoreUpdater
|
|||||||
*/
|
*/
|
||||||
private static function GetItopArchiveName()
|
private static function GetItopArchiveName()
|
||||||
{
|
{
|
||||||
$sItopArchiveName = APPROOT.'data/backups/itop';
|
$sItopArchiveName = utils::GetDataPath().'backups/itop';
|
||||||
return $sItopArchiveName;
|
return $sItopArchiveName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,7 +504,7 @@ final class CoreUpdater
|
|||||||
*/
|
*/
|
||||||
private static function GetBackupName()
|
private static function GetBackupName()
|
||||||
{
|
{
|
||||||
$sBackupName = APPROOT.'data/backups/manual/backup-core-update';
|
$sBackupName = utils::GetDataPath().'backups/manual/backup-core-update';
|
||||||
return $sBackupName;
|
return $sBackupName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ try
|
|||||||
require_once (APPROOT.'/application/loginwebpage.class.inc.php');
|
require_once (APPROOT.'/application/loginwebpage.class.inc.php');
|
||||||
LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin)
|
LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin)
|
||||||
|
|
||||||
$sDBBackupPath = APPROOT.'data/backups/manual';
|
$sDBBackupPath = utils::GetDataPath().'backups/manual';
|
||||||
$aChecks = SetupUtils::CheckBackupPrerequisites($sDBBackupPath);
|
$aChecks = SetupUtils::CheckBackupPrerequisites($sDBBackupPath);
|
||||||
$bFailed = false;
|
$bFailed = false;
|
||||||
foreach ($aChecks as $oCheckResult)
|
foreach ($aChecks as $oCheckResult)
|
||||||
@@ -258,7 +258,7 @@ try
|
|||||||
case 'compile':
|
case 'compile':
|
||||||
SetupLog::Info('Deployment starts...');
|
SetupLog::Info('Deployment starts...');
|
||||||
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
|
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
|
||||||
if (!file_exists(APPROOT.'data/hub/compile_authent') || $sAuthent !== file_get_contents(APPROOT.'data/hub/compile_authent'))
|
if (!file_exists(utils::GetDataPath().'hub/compile_authent') || $sAuthent !== file_get_contents(utils::GetDataPath().'hub/compile_authent'))
|
||||||
{
|
{
|
||||||
throw new SecurityException(Dict::S('iTopHub:FailAuthent'));
|
throw new SecurityException(Dict::S('iTopHub:FailAuthent'));
|
||||||
}
|
}
|
||||||
@@ -301,11 +301,11 @@ try
|
|||||||
{
|
{
|
||||||
SetupLog::Info('Move to production starts...');
|
SetupLog::Info('Move to production starts...');
|
||||||
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
|
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
|
||||||
if (!file_exists(APPROOT.'data/hub/compile_authent') || $sAuthent !== file_get_contents(APPROOT.'data/hub/compile_authent'))
|
if (!file_exists(utils::GetDataPath().'hub/compile_authent') || $sAuthent !== file_get_contents(utils::GetDataPath().'hub/compile_authent'))
|
||||||
{
|
{
|
||||||
throw new SecurityException(Dict::S('iTopHub:FailAuthent'));
|
throw new SecurityException(Dict::S('iTopHub:FailAuthent'));
|
||||||
}
|
}
|
||||||
unlink(APPROOT.'data/hub/compile_authent');
|
unlink(utils::GetDataPath().'hub/compile_authent');
|
||||||
// Load the "production" config file to clone & update it
|
// Load the "production" config file to clone & update it
|
||||||
$oConfig = new Config(APPCONF.'production/'.ITOP_CONFIG_FILE);
|
$oConfig = new Config(APPCONF.'production/'.ITOP_CONFIG_FILE);
|
||||||
SetupUtils::EnterReadOnlyMode($oConfig);
|
SetupUtils::EnterReadOnlyMode($oConfig);
|
||||||
@@ -370,9 +370,9 @@ try
|
|||||||
}
|
}
|
||||||
catch (Exception $e)
|
catch (Exception $e)
|
||||||
{
|
{
|
||||||
if(file_exists(APPROOT.'data/hub/compile_authent'))
|
if(file_exists(utils::GetDataPath().'hub/compile_authent'))
|
||||||
{
|
{
|
||||||
unlink(APPROOT.'data/hub/compile_authent');
|
unlink(utils::GetDataPath().'hub/compile_authent');
|
||||||
}
|
}
|
||||||
// Note: at this point, the dictionnary is not necessarily loaded
|
// Note: at this point, the dictionnary is not necessarily loaded
|
||||||
SetupLog::Error(get_class($e).': '.Dict::S('iTopHub:ConfigurationSafelyReverted')."\n".$e->getMessage());
|
SetupLog::Error(get_class($e).': '.Dict::S('iTopHub:ConfigurationSafelyReverted')."\n".$e->getMessage());
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ class HubNewsroomProvider extends NewsroomProviderBase
|
|||||||
$sBaseUrl = $this->oConfig->GetModuleSetting('itop-hub-connector', 'url').MetaModel::GetModuleSetting('itop-hub-connector', $sRouteCode);
|
$sBaseUrl = $this->oConfig->GetModuleSetting('itop-hub-connector', 'url').MetaModel::GetModuleSetting('itop-hub-connector', $sRouteCode);
|
||||||
|
|
||||||
$sParameters = 'uuid[bdd]='.urlencode((string) trim(DBProperty::GetProperty('database_uuid', ''), '{}'));
|
$sParameters = 'uuid[bdd]='.urlencode((string) trim(DBProperty::GetProperty('database_uuid', ''), '{}'));
|
||||||
$sParameters .= '&uuid[file]='.urlencode((string) trim(@file_get_contents(APPROOT."data/instance.txt"), "{} \n"));
|
$sParameters .= '&uuid[file]='.urlencode((string) trim(@file_get_contents(utils::GetDataPath()."instance.txt"), "{} \n"));
|
||||||
$sParameters .= '&uuid[user]='.urlencode(UserRights::GetUserId());
|
$sParameters .= '&uuid[user]='.urlencode(UserRights::GetUserId());
|
||||||
|
|
||||||
return $sBaseUrl.'?'.$sParameters;
|
return $sBaseUrl.'?'.$sParameters;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ function DisplayStatus(WebPage $oPage)
|
|||||||
|
|
||||||
$oPage->add('<div class="module-selection-body">');
|
$oPage->add('<div class="module-selection-body">');
|
||||||
// Now scan the extensions and display a report of the extensions brought by the hub
|
// Now scan the extensions and display a report of the extensions brought by the hub
|
||||||
$sPath = APPROOT.'data/downloaded-extensions/';
|
$sPath = utils::GetDataPath().'downloaded-extensions/';
|
||||||
$aExtraDirs = array();
|
$aExtraDirs = array();
|
||||||
if (is_dir($sPath)) {
|
if (is_dir($sPath)) {
|
||||||
$aExtraDirs[] = $sPath; // Also read the extra downloaded-modules directory
|
$aExtraDirs[] = $sPath; // Also read the extra downloaded-modules directory
|
||||||
@@ -84,7 +84,7 @@ function DoLanding(WebPage $oPage)
|
|||||||
throw new Exception("Inconsistent version '$sVersion', expecting ".ITOP_VERSION."'");
|
throw new Exception("Inconsistent version '$sVersion', expecting ".ITOP_VERSION."'");
|
||||||
}
|
}
|
||||||
|
|
||||||
$sFileUUID = (string)trim(@file_get_contents(APPROOT."data/instance.txt"), "{} \n");
|
$sFileUUID = (string)trim(@file_get_contents(utils::GetDataPath()."instance.txt"), "{} \n");
|
||||||
if ($sInstanceUUID != $sFileUUID) {
|
if ($sInstanceUUID != $sFileUUID) {
|
||||||
throw new Exception("Inconsistent file UUID '$sInstanceUUID', expecting ".$sFileUUID."'");
|
throw new Exception("Inconsistent file UUID '$sInstanceUUID', expecting ".$sFileUUID."'");
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ function DoLanding(WebPage $oPage)
|
|||||||
// Uncompression of extensions in data/downloaded-extensions
|
// Uncompression of extensions in data/downloaded-extensions
|
||||||
// only newly downloaded extensions reside in this folder
|
// only newly downloaded extensions reside in this folder
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$sPath = APPROOT.'data/downloaded-extensions/';
|
$sPath = utils::GetDataPath().'downloaded-extensions/';
|
||||||
if (!is_dir($sPath)) {
|
if (!is_dir($sPath)) {
|
||||||
if (!mkdir($sPath)) {
|
if (!mkdir($sPath)) {
|
||||||
throw new Exception("ERROR: Unable to create the directory '$sPath'. Cannot download any extension. Check the access rights on '".dirname('data/downloaded-extensions/')."'");
|
throw new Exception("ERROR: Unable to create the directory '$sPath'. Cannot download any extension. Check the access rights on '".dirname('data/downloaded-extensions/')."'");
|
||||||
@@ -112,7 +112,7 @@ function DoLanding(WebPage $oPage)
|
|||||||
|
|
||||||
$sZipArchiveFile = $sPath."/extension-{$i}.zip";
|
$sZipArchiveFile = $sPath."/extension-{$i}.zip";
|
||||||
file_put_contents($sZipArchiveFile, $sArchive);
|
file_put_contents($sZipArchiveFile, $sArchive);
|
||||||
// Expand the content of extension-x.zip into APPROOT.'data/downloaded-extensions/'
|
// Expand the content of extension-x.zip into utils::GetDataPath().'downloaded-extensions/'
|
||||||
// where the installation will load the extension automatically
|
// where the installation will load the extension automatically
|
||||||
$oZip = new ZipArchive();
|
$oZip = new ZipArchive();
|
||||||
if (!$oZip->open($sZipArchiveFile)) {
|
if (!$oZip->open($sZipArchiveFile)) {
|
||||||
@@ -136,7 +136,7 @@ function DoLanding(WebPage $oPage)
|
|||||||
function DoInstall(WebPage $oPage)
|
function DoInstall(WebPage $oPage)
|
||||||
{
|
{
|
||||||
$sUID = hash('sha256', rand());
|
$sUID = hash('sha256', rand());
|
||||||
file_put_contents(APPROOT.'data/hub/compile_authent', $sUID);
|
file_put_contents(utils::GetDataPath().'hub/compile_authent', $sUID);
|
||||||
|
|
||||||
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/css/hub.css');
|
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/css/hub.css');
|
||||||
$oPage->add('<table class="module-selection-banner"><tr>');
|
$oPage->add('<table class="module-selection-banner"><tr>');
|
||||||
@@ -151,7 +151,7 @@ function DoInstall(WebPage $oPage)
|
|||||||
|
|
||||||
// Now scan the extensions and display a report of the extensions brought by the hub
|
// Now scan the extensions and display a report of the extensions brought by the hub
|
||||||
// Now scan the extensions and display a report of the extensions brought by the hub
|
// Now scan the extensions and display a report of the extensions brought by the hub
|
||||||
$sPath = APPROOT.'data/downloaded-extensions/';
|
$sPath = utils::GetDataPath().'downloaded-extensions/';
|
||||||
$aExtraDirs = array();
|
$aExtraDirs = array();
|
||||||
if (is_dir($sPath)) {
|
if (is_dir($sPath)) {
|
||||||
$aExtraDirs[] = $sPath; // Also read the extra downloaded-modules directory
|
$aExtraDirs[] = $sPath; // Also read the extra downloaded-modules directory
|
||||||
@@ -283,8 +283,8 @@ CSS
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'install':
|
case 'install':
|
||||||
if (!file_exists(APPROOT.'data/hub')) {
|
if (!file_exists(utils::GetDataPath().'hub')) {
|
||||||
mkdir(APPROOT.'data/hub');
|
mkdir(utils::GetDataPath().'hub');
|
||||||
}
|
}
|
||||||
DoInstall($oPage);
|
DoInstall($oPage);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ function MakeDataToPost($sTargetRoute)
|
|||||||
'itop_hub_target_route' => $sTargetRoute,
|
'itop_hub_target_route' => $sTargetRoute,
|
||||||
'itop_stack' => array(
|
'itop_stack' => array(
|
||||||
"uuidBdd" => (string)trim(DBProperty::GetProperty('database_uuid', ''), '{}'), // TODO check if empty and... regenerate a new UUID ??
|
"uuidBdd" => (string)trim(DBProperty::GetProperty('database_uuid', ''), '{}'), // TODO check if empty and... regenerate a new UUID ??
|
||||||
"uuidFile" => (string)trim(@file_get_contents(APPROOT."data/instance.txt"), "{} \n"), // TODO check if empty and... regenerate a new UUID ??
|
"uuidFile" => (string)trim(@file_get_contents(utils::GetDataPath()."instance.txt"), "{} \n"), // TODO check if empty and... regenerate a new UUID ??
|
||||||
'instance_friendly_name' => (string)$_SERVER['SERVER_NAME'],
|
'instance_friendly_name' => (string)$_SERVER['SERVER_NAME'],
|
||||||
'instance_host' => (string)utils::GetAbsoluteUrlAppRoot(),
|
'instance_host' => (string)utils::GetAbsoluteUrlAppRoot(),
|
||||||
'application_name' => (string)ITOP_APPLICATION,
|
'application_name' => (string)ITOP_APPLICATION,
|
||||||
|
|||||||
@@ -389,7 +389,6 @@ return array(
|
|||||||
'Combodo\\iTop\\Application\\WebPage\\iTopWebPage' => $baseDir . '/sources/Application/WebPage/iTopWebPage.php',
|
'Combodo\\iTop\\Application\\WebPage\\iTopWebPage' => $baseDir . '/sources/Application/WebPage/iTopWebPage.php',
|
||||||
'Combodo\\iTop\\Application\\WebPage\\iTopWizardWebPage' => $baseDir . '/sources/Application/WebPage/iTopWizardWebPage.php',
|
'Combodo\\iTop\\Application\\WebPage\\iTopWizardWebPage' => $baseDir . '/sources/Application/WebPage/iTopWizardWebPage.php',
|
||||||
'Combodo\\iTop\\Composer\\iTopComposer' => $baseDir . '/sources/Composer/iTopComposer.php',
|
'Combodo\\iTop\\Composer\\iTopComposer' => $baseDir . '/sources/Composer/iTopComposer.php',
|
||||||
'Combodo\\iTop\\Controller\\AbstractAppController' => $baseDir . '/sources/Controller/AbstractAppController.php',
|
|
||||||
'Combodo\\iTop\\Controller\\AbstractController' => $baseDir . '/sources/Controller/AbstractController.php',
|
'Combodo\\iTop\\Controller\\AbstractController' => $baseDir . '/sources/Controller/AbstractController.php',
|
||||||
'Combodo\\iTop\\Controller\\AjaxRenderController' => $baseDir . '/sources/Controller/AjaxRenderController.php',
|
'Combodo\\iTop\\Controller\\AjaxRenderController' => $baseDir . '/sources/Controller/AjaxRenderController.php',
|
||||||
'Combodo\\iTop\\Controller\\Base\\Layout\\ActivityPanelController' => $baseDir . '/sources/Controller/Base/Layout/ActivityPanelController.php',
|
'Combodo\\iTop\\Controller\\Base\\Layout\\ActivityPanelController' => $baseDir . '/sources/Controller/Base/Layout/ActivityPanelController.php',
|
||||||
|
|||||||
@@ -764,7 +764,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
|||||||
'Combodo\\iTop\\Application\\WebPage\\iTopWebPage' => __DIR__ . '/../..' . '/sources/Application/WebPage/iTopWebPage.php',
|
'Combodo\\iTop\\Application\\WebPage\\iTopWebPage' => __DIR__ . '/../..' . '/sources/Application/WebPage/iTopWebPage.php',
|
||||||
'Combodo\\iTop\\Application\\WebPage\\iTopWizardWebPage' => __DIR__ . '/../..' . '/sources/Application/WebPage/iTopWizardWebPage.php',
|
'Combodo\\iTop\\Application\\WebPage\\iTopWizardWebPage' => __DIR__ . '/../..' . '/sources/Application/WebPage/iTopWizardWebPage.php',
|
||||||
'Combodo\\iTop\\Composer\\iTopComposer' => __DIR__ . '/../..' . '/sources/Composer/iTopComposer.php',
|
'Combodo\\iTop\\Composer\\iTopComposer' => __DIR__ . '/../..' . '/sources/Composer/iTopComposer.php',
|
||||||
'Combodo\\iTop\\Controller\\AbstractAppController' => __DIR__ . '/../..' . '/sources/Controller/AbstractAppController.php',
|
|
||||||
'Combodo\\iTop\\Controller\\AbstractController' => __DIR__ . '/../..' . '/sources/Controller/AbstractController.php',
|
'Combodo\\iTop\\Controller\\AbstractController' => __DIR__ . '/../..' . '/sources/Controller/AbstractController.php',
|
||||||
'Combodo\\iTop\\Controller\\AjaxRenderController' => __DIR__ . '/../..' . '/sources/Controller/AjaxRenderController.php',
|
'Combodo\\iTop\\Controller\\AjaxRenderController' => __DIR__ . '/../..' . '/sources/Controller/AjaxRenderController.php',
|
||||||
'Combodo\\iTop\\Controller\\Base\\Layout\\ActivityPanelController' => __DIR__ . '/../..' . '/sources/Controller/Base/Layout/ActivityPanelController.php',
|
'Combodo\\iTop\\Controller\\Base\\Layout\\ActivityPanelController' => __DIR__ . '/../..' . '/sources/Controller/Base/Layout/ActivityPanelController.php',
|
||||||
|
|||||||
168
pages/UI.php
168
pages/UI.php
@@ -6,14 +6,12 @@
|
|||||||
|
|
||||||
use Combodo\iTop\Application\Helper\Session;
|
use Combodo\iTop\Application\Helper\Session;
|
||||||
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Alert\AlertUIBlockFactory;
|
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Form\Form;
|
use Combodo\iTop\Application\UI\Base\Component\Form\Form;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\GlobalSearch\GlobalSearchHelper;
|
use Combodo\iTop\Application\UI\Base\Component\GlobalSearch\GlobalSearchHelper;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Title\Title;
|
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
|
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
|
||||||
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
|
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
|
||||||
@@ -23,7 +21,9 @@ use Combodo\iTop\Application\WebPage\ErrorPage;
|
|||||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||||
use Combodo\iTop\Application\WebPage\WebPage;
|
use Combodo\iTop\Application\WebPage\WebPage;
|
||||||
use Combodo\iTop\Controller\Base\Layout\ObjectController;
|
use Combodo\iTop\Controller\Base\Layout\ObjectController;
|
||||||
|
use Combodo\iTop\Kernel;
|
||||||
use Combodo\iTop\Service\Router\Router;
|
use Combodo\iTop\Service\Router\Router;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a popup welcome message, once per session at maximum
|
* Displays a popup welcome message, once per session at maximum
|
||||||
@@ -319,6 +319,7 @@ try
|
|||||||
$oKPI->ComputeAndReport('User login');
|
$oKPI->ComputeAndReport('User login');
|
||||||
|
|
||||||
// First check if we can redirect the route to a dedicated controller
|
// First check if we can redirect the route to a dedicated controller
|
||||||
|
// IMPORTANT: Even though iTop router is deprecated, we must ensure old URLs keep working (for a while) as they can be used in received notifications, bookmarks, extensions, ...
|
||||||
$sRoute = utils::ReadParam('route', '', false, utils::ENUM_SANITIZATION_FILTER_ROUTE);
|
$sRoute = utils::ReadParam('route', '', false, utils::ENUM_SANITIZATION_FILTER_ROUTE);
|
||||||
$oRouter = Router::GetInstance();
|
$oRouter = Router::GetInstance();
|
||||||
if ($oRouter->CanDispatchRoute($sRoute)) {
|
if ($oRouter->CanDispatchRoute($sRoute)) {
|
||||||
@@ -341,7 +342,131 @@ try
|
|||||||
$oP = new iTopWebPage(Dict::S('UI:WelcomeToITop'), $bPrintable);
|
$oP = new iTopWebPage(Dict::S('UI:WelcomeToITop'), $bPrintable);
|
||||||
$oP->SetMessage($sLoginMessage);
|
$oP->SetMessage($sLoginMessage);
|
||||||
|
|
||||||
// All the following actions use advanced forms that require more javascript to be loaded
|
//-----------------------------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Mind that the following backward compatibility pattern is also present in the `pages/ajax.render.php` endpoint
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Kept for backward compatibility with iTop 3.1.x notification URLs, don't remove
|
||||||
|
// Non-dispatchable "routes" (iTop 3.1) are mapped to their old corresponding "operation" (iTop 3.0 and older), in order to be later redirected to the proper new URLs (iTop 3.2 and newer)
|
||||||
|
switch ($sRoute) {
|
||||||
|
case 'object.new':
|
||||||
|
case 'object.apply_new':
|
||||||
|
case 'object.modify':
|
||||||
|
case 'object.apply_modify':
|
||||||
|
$operation = str_ireplace("object.", "", $sRoute);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (utils::IsNotNullOrEmptyString($sRoute)) {
|
||||||
|
DeprecatedCallsLog::Debug("Calling UI.php with a deprecated \"route\" parameter that was migrated to Symfony router, redirecting to fallback \"operation\" parameter. If URI comes from a custom code, migrate it. If URI comes from an old notification, mind that it may not work in future versions.", LogChannels::ROUTER, [
|
||||||
|
"request_uri" => $_SERVER["REQUEST_URI"],
|
||||||
|
"route" => $sRoute,
|
||||||
|
"fallback_operation" => $operation,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kept for backward compatibility with iTop 3.0 and older notification URLs, don't remove
|
||||||
|
// These operations have been migrated to Symfony router, we need to redirect to the proper new URLs
|
||||||
|
switch ($operation) {
|
||||||
|
/** @deprecated 3.1.0 Use the "b_object_new" Symfony route instead */
|
||||||
|
case 'new':
|
||||||
|
/** @deprecated 3.1.0 Use the "b_object_apply_new" Symfony route instead */
|
||||||
|
case 'apply_new':
|
||||||
|
/** @deprecated 3.1.0 Use the "b_object_modify" Symfony route instead */
|
||||||
|
case 'modify':
|
||||||
|
/** @deprecated 3.1.0 Use the "b_object_apply_new" Symfony route instead */
|
||||||
|
case 'apply_modify':
|
||||||
|
// Start a Symfony kernel and redirect to the corresponding route / controller
|
||||||
|
$oKernel = new Kernel("prod", false);
|
||||||
|
$oRequest = Request::createFromGlobals();
|
||||||
|
|
||||||
|
/** @var string $sRouteName Route name to redirect to */
|
||||||
|
$sRouteName = '';
|
||||||
|
/** @var string[] $aPath Parts of the Symfony route path (eg. for "/object/{sCLass}/{sId}", ["sClass" => "UserRequest", "sId" => "123"]) */
|
||||||
|
$aPath = [];
|
||||||
|
/** @var string[] $aQuery Query parameters of the request -parameters after the "?" of the URI- (eg. for "/object/UserRequest/123?a=1&b=2", ["a" => 1, "b" => 2]) */
|
||||||
|
$aQuery = $oRequest->query->all();
|
||||||
|
|
||||||
|
// Find controller corresponding to the old "operation"
|
||||||
|
switch ($operation) {
|
||||||
|
case 'new':
|
||||||
|
$sRouteName = 'b_object_new';
|
||||||
|
$aPath['_controller'] = ObjectController::class . "::OperationNew";
|
||||||
|
$aPath['sClass'] = utils::ReadParam('class', null, false, utils::ENUM_SANITIZATION_FILTER_CLASS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'apply_new':
|
||||||
|
$sRouteName = 'b_object_apply_new';
|
||||||
|
$aPath['_controller'] = ObjectController::class . "::OperationApplyNew";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'modify':
|
||||||
|
$sRouteName = 'b_object_modify';
|
||||||
|
$aPath['_controller'] = ObjectController::class . "::OperationModify";
|
||||||
|
$aPath['sClass'] = utils::ReadParam('class', '', false, utils::ENUM_SANITIZATION_FILTER_CLASS);
|
||||||
|
$aPath['sId'] = utils::ReadParam('id', '');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'apply_modify':
|
||||||
|
$sRouteName = 'b_object_apply_modify';
|
||||||
|
$aPath['_controller'] = ObjectController::class . "::OperationApplyModify";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Redirect
|
||||||
|
///** @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface $oUrlGenerator */
|
||||||
|
//$oResponse = $oKernel->handle($oRequest);
|
||||||
|
//$oUrlGenerator = $oKernel->getContainer()->get('router');
|
||||||
|
|
||||||
|
// - Solution 1: Simplement redirection
|
||||||
|
// Pros:
|
||||||
|
// - Redirects to the new URL
|
||||||
|
// - Keeps query parameters
|
||||||
|
// - Uses the real Symfony kernel as it will be a complete new process
|
||||||
|
// Cons:
|
||||||
|
// - Loose posted parameters if any (but could be ok as we essentially do this for notifications / bookmarks); extensions will be migrated
|
||||||
|
// - Makes an HTTP redirection, could be an issue in some infras? I don't think so, we already do it in several places
|
||||||
|
/*$sRedirectUrl = $oUrlGenerator->generate($sRouteName, $aPath + $aQuery);
|
||||||
|
// Generated URL is based on the script the Kernel is instantiated in, so we have to correct it to point to the new unique endpoint
|
||||||
|
$sRedirectUrl = str_ireplace("pages/UI.php", "app.php", $sRedirectUrl);
|
||||||
|
header("location: $sRedirectUrl");
|
||||||
|
die();*/
|
||||||
|
|
||||||
|
// - Solution 2: Symfony redirection
|
||||||
|
// Pros:
|
||||||
|
// - Redirects to the new URL
|
||||||
|
// - Keeps query parameters
|
||||||
|
// - Uses the real Symfony kernel as it will be a complete new process
|
||||||
|
// - Keeps redirection working even though there are deprecated messages printed before headers are send (unlike with solution 1)
|
||||||
|
// Cons:
|
||||||
|
// - Loose posted parameters if any (but could be ok as we essentially do this for notifications / bookmarks); extensions will be migrated
|
||||||
|
// - Makes an HTTP redirection, could be an issue in some infras? I don't think so, we already do it in several places
|
||||||
|
/*$sRedirectUrl = $oUrlGenerator->generate($sRouteName, $aPath + $aQuery);
|
||||||
|
// Generated URL is based on the script the Kernel is instantiated in, so we have to correct it to point to the new unique endpoint
|
||||||
|
$sRedirectUrl = str_ireplace("pages/UI.php", "app.php", $sRedirectUrl);
|
||||||
|
$oResponse = new RedirectResponse($sRedirectUrl);
|
||||||
|
$oResponse->send();
|
||||||
|
$oKernel->terminate($oRequest, $oResponse);
|
||||||
|
die();*/
|
||||||
|
|
||||||
|
|
||||||
|
// - Solution 3: Internal redirection
|
||||||
|
// Pros:
|
||||||
|
// - Keeps query parameters
|
||||||
|
// - Keeps posted parameters (essential for submission URLs)
|
||||||
|
// Cons:
|
||||||
|
// - Still displays the old URL
|
||||||
|
// - Uses a not so well-formed Symfony kernel?
|
||||||
|
$oSubRequest = $oRequest->duplicate($aQuery, null, $aPath);
|
||||||
|
$oResponse = $oKernel->handle($oSubRequest, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST);
|
||||||
|
$oResponse->send();
|
||||||
|
$oKernel->terminate($oSubRequest, $oResponse);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
// All the following operations use advanced forms that require more javascript to be loaded
|
||||||
switch($operation)
|
switch($operation)
|
||||||
{
|
{
|
||||||
case 'new': // Form to create a new object
|
case 'new': // Form to create a new object
|
||||||
@@ -350,7 +475,7 @@ try
|
|||||||
case 'stimulus': // Form displayed when applying a stimulus (state change)
|
case 'stimulus': // Form displayed when applying a stimulus (state change)
|
||||||
case 'apply_stimulus': // Form displayed when applying a stimulus (state change)
|
case 'apply_stimulus': // Form displayed when applying a stimulus (state change)
|
||||||
foreach (ObjectController::EnumRequiredForModificationJsFilesRelPaths() as $sJsFileRelPath) {
|
foreach (ObjectController::EnumRequiredForModificationJsFilesRelPaths() as $sJsFileRelPath) {
|
||||||
$oP->add_linked_script("../$sJsFileRelPath");
|
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "$sJsFileRelPath");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -651,7 +776,7 @@ try
|
|||||||
$oP->SetBreadCrumbEntry($sPageId, $sLabel, $sDescription, '', 'fas fa-search', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
$oP->SetBreadCrumbEntry($sPageId, $sLabel, $sDescription, '', 'fas fa-search', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES);
|
||||||
$oP->add("<div style=\"padding: 10px;\">\n");
|
$oP->add("<div style=\"padding: 10px;\">\n");
|
||||||
$oP->add("<div class=\"header_message\" id=\"full_text_progress\" style=\"position: fixed; background-color: #cccccc; opacity: 0.7; padding: 1.5em;\">\n");
|
$oP->add("<div class=\"header_message\" id=\"full_text_progress\" style=\"position: fixed; background-color: #cccccc; opacity: 0.7; padding: 1.5em;\">\n");
|
||||||
$oP->add('<img id="full_text_indicator" src="../images/indicator.gif"> <span style="padding: 1.5em;">'.Dict::Format('UI:Search:Ongoing', utils::EscapeHtml($sFullText)).'</span>');
|
$oP->add('<img id="full_text_indicator" src="' . utils::GetAbsoluteUrlAppRoot() . 'images/indicator.gif"> <span style="padding: 1.5em;">'.Dict::Format('UI:Search:Ongoing', utils::EscapeHtml($sFullText)).'</span>');
|
||||||
$oP->add("</div>\n");
|
$oP->add("</div>\n");
|
||||||
$oP->add("<div id=\"full_text_results\">\n");
|
$oP->add("<div id=\"full_text_results\">\n");
|
||||||
$oP->add("<div id=\"full_text_progress_placeholder\" style=\"padding: 1.5em;\"> </div>\n");
|
$oP->add("<div id=\"full_text_progress_placeholder\" style=\"padding: 1.5em;\"> </div>\n");
|
||||||
@@ -678,15 +803,6 @@ try
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/** @deprecated 3.1.0 Use the "object.modify" route instead */
|
|
||||||
// Kept for backward compatibility with notification URLs, don't remove
|
|
||||||
case 'modify': // Legacy operation
|
|
||||||
$oController = new ObjectController();
|
|
||||||
$oP = $oController->OperationModify();
|
|
||||||
break;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
case 'select_for_modify_all': // Select the list of objects to be modified (bulk modify)
|
case 'select_for_modify_all': // Select the list of objects to be modified (bulk modify)
|
||||||
UI::OperationSelectForModifyAll($oP);
|
UI::OperationSelectForModifyAll($oP);
|
||||||
break;
|
break;
|
||||||
@@ -703,22 +819,6 @@ try
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/** @deprecated 3.1.0 Use the "object.new" route instead */
|
|
||||||
// Kept for backward compatibility
|
|
||||||
case 'new': // Form to create a new object
|
|
||||||
$oController = new ObjectController();
|
|
||||||
$oP = $oController->OperationNew();
|
|
||||||
break;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
case 'apply_modify': // Applying the modifications to an existing object
|
|
||||||
$oController = new ObjectController();
|
|
||||||
$oP = $oController->OperationApplyModify();
|
|
||||||
break;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
case 'select_for_deletion': // Select multiple objects for deletion
|
case 'select_for_deletion': // Select multiple objects for deletion
|
||||||
$oP->DisableBreadCrumb();
|
$oP->DisableBreadCrumb();
|
||||||
@@ -813,14 +913,6 @@ try
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
case 'apply_new': // Creation of a new object
|
|
||||||
|
|
||||||
$oController = new ObjectController();
|
|
||||||
$oP = $oController->OperationApplyNew();
|
|
||||||
break;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
case 'select_bulk_stimulus': // Form displayed when applying a stimulus to many objects
|
case 'select_bulk_stimulus': // Form displayed when applying a stimulus to many objects
|
||||||
$oP->DisableBreadCrumb();
|
$oP->DisableBreadCrumb();
|
||||||
$sFilter = utils::ReadParam('filter', '', false, 'raw_data');
|
$sFilter = utils::ReadParam('filter', '', false, 'raw_data');
|
||||||
|
|||||||
@@ -33,11 +33,11 @@ ApplicationMenu::CheckMenuIdEnabled('UniversalSearchMenu');
|
|||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
|
|
||||||
$oP = new iTopWebPage(Dict::S('UI:UniversalSearchTitle'));
|
$oP = new iTopWebPage(Dict::S('UI:UniversalSearchTitle'));
|
||||||
$oP->add_linked_script("../js/forms-json-utils.js");
|
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/forms-json-utils.js");
|
||||||
$oP->add_linked_script("../js/wizardhelper.js");
|
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/wizardhelper.js");
|
||||||
$oP->add_linked_script("../js/wizard.utils.js");
|
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/wizard.utils.js");
|
||||||
$oP->add_linked_script("../js/extkeywidget.js");
|
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/extkeywidget.js");
|
||||||
$oP->add_linked_script("../js/jquery.blockUI.js");
|
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/jquery.blockUI.js");
|
||||||
|
|
||||||
// From now on the context is limited to the the selected organization ??
|
// From now on the context is limited to the the selected organization ??
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,10 @@ use Combodo\iTop\Controller\Base\Layout\ObjectController;
|
|||||||
use Combodo\iTop\Controller\PreferencesController;
|
use Combodo\iTop\Controller\PreferencesController;
|
||||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||||
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
||||||
|
use Combodo\iTop\Kernel;
|
||||||
use Combodo\iTop\Service\Router\Router;
|
use Combodo\iTop\Service\Router\Router;
|
||||||
use Combodo\iTop\Service\TemporaryObjects\TemporaryObjectManager;
|
use Combodo\iTop\Service\TemporaryObjects\TemporaryObjectManager;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
require_once('../approot.inc.php');
|
require_once('../approot.inc.php');
|
||||||
|
|
||||||
@@ -44,7 +46,6 @@ try
|
|||||||
$oKPI = new ExecutionKPI();
|
$oKPI = new ExecutionKPI();
|
||||||
|
|
||||||
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
|
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
|
||||||
$sRoute = utils::ReadParam('route', '', false, utils::ENUM_SANITIZATION_FILTER_ROUTE);
|
|
||||||
$operation = utils::ReadParam('operation', '', false, utils::ENUM_SANITIZATION_FILTER_OPERATION);
|
$operation = utils::ReadParam('operation', '', false, utils::ENUM_SANITIZATION_FILTER_OPERATION);
|
||||||
|
|
||||||
// Only allow export functions to portal users
|
// Only allow export functions to portal users
|
||||||
@@ -78,6 +79,7 @@ try
|
|||||||
}
|
}
|
||||||
|
|
||||||
// First check if we can redirect the route to a dedicated controller
|
// First check if we can redirect the route to a dedicated controller
|
||||||
|
// IMPORTANT: Even though iTop router is deprecated, we must ensure old URLs keep working (for a while) as they can be used in received notifications, bookmarks, extensions, ...
|
||||||
$sRoute = utils::ReadParam('route', '', false, utils::ENUM_SANITIZATION_FILTER_ROUTE);
|
$sRoute = utils::ReadParam('route', '', false, utils::ENUM_SANITIZATION_FILTER_ROUTE);
|
||||||
$oRouter = Router::GetInstance();
|
$oRouter = Router::GetInstance();
|
||||||
if ($oRouter->CanDispatchRoute($sRoute)) {
|
if ($oRouter->CanDispatchRoute($sRoute)) {
|
||||||
@@ -97,12 +99,82 @@ try
|
|||||||
// Default for most operations, but can be switch to a JsonPage, DownloadPage or else if the operation requires it
|
// Default for most operations, but can be switch to a JsonPage, DownloadPage or else if the operation requires it
|
||||||
$oPage = new AjaxPage("");
|
$oPage = new AjaxPage("");
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Mind that the following backward compatibility pattern is also present in the `pages/UI.php` endpoint
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Kept for backward compatibility with iTop 3.1.x notification URLs, don't remove
|
||||||
|
// Non-dispatchable "routes" (iTop 3.1) are mapped to their old corresponding "operation" (iTop 3.0 and older), in order to be later redirected to the proper new URLs (iTop 3.2 and newer)
|
||||||
|
switch ($sRoute) {
|
||||||
|
case 'object.new':
|
||||||
|
case 'object.modify':
|
||||||
|
$operation = str_ireplace("object.", "", $sRoute);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (utils::IsNotNullOrEmptyString($sRoute)) {
|
||||||
|
DeprecatedCallsLog::Debug("Calling UI.php with a deprecated \"route\" parameter that was migrated to Symfony router, redirecting to fallback \"operation\" parameter. If URI comes from a custom code, migrate it. If URI comes from an old notification, mind that it may not work in future versions.", LogChannels::ROUTER, [
|
||||||
|
"request_uri" => $_SERVER["REQUEST_URI"],
|
||||||
|
"route" => $sRoute,
|
||||||
|
"fallback_operation" => $operation,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kept for backward compatibility with iTop 3.0 and older notification URLs, don't remove
|
||||||
|
// These operations have been migrated to Symfony router, we need to redirect to the proper new URLs
|
||||||
|
switch ($operation) {
|
||||||
|
/** @deprecated 3.1.0 Use the "b_object_new" Symfony route instead */
|
||||||
|
case 'new':
|
||||||
|
/** @deprecated 3.1.0 Use the "b_object_modify" Symfony route instead */
|
||||||
|
case 'modify':
|
||||||
|
// Start a Symfony kernel and redirect to the corresponding route / controller
|
||||||
|
$oKernel = new Kernel("prod", false);
|
||||||
|
$oRequest = Request::createFromGlobals();
|
||||||
|
|
||||||
|
/** @var string $sRouteName Route name to redirect to */
|
||||||
|
$sRouteName = '';
|
||||||
|
/** @var string[] $aPath Parts of the Symfony route path (eg. for "/object/{sCLass}/{sId}", ["sClass" => "UserRequest", "sId" => "123"]) */
|
||||||
|
$aPath = [];
|
||||||
|
/** @var string[] $aQuery Query parameters of the request -parameters after the "?" of the URI- (eg. for "/object/UserRequest/123?a=1&b=2", ["a" => 1, "b" => 2]) */
|
||||||
|
$aQuery = $oRequest->query->all();
|
||||||
|
|
||||||
|
// Find controller corresponding to the old "operation"
|
||||||
|
switch ($operation) {
|
||||||
|
case 'new':
|
||||||
|
$sRouteName = 'b_object_new';
|
||||||
|
$aPath['_controller'] = ObjectController::class . "::OperationNew";
|
||||||
|
$aPath['sClass'] = utils::ReadParam('class', null, false, utils::ENUM_SANITIZATION_FILTER_CLASS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'modify':
|
||||||
|
$sRouteName = 'b_object_modify';
|
||||||
|
$aPath['_controller'] = ObjectController::class . "::OperationModify";
|
||||||
|
$aPath['sClass'] = utils::ReadParam('class', '', false, utils::ENUM_SANITIZATION_FILTER_CLASS);
|
||||||
|
$aPath['sId'] = utils::ReadParam('id', '');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal Symfony redirection
|
||||||
|
// Pros:
|
||||||
|
// - Keeps query parameters
|
||||||
|
// - Keeps posted parameters (essential for submission URLs)
|
||||||
|
// Cons:
|
||||||
|
// - Still displays the old URL
|
||||||
|
// - Uses a not so well-formed Symfony kernel?
|
||||||
|
$oSubRequest = $oRequest->duplicate($aQuery, null, $aPath);
|
||||||
|
$oResponse = $oKernel->handle($oSubRequest, \Symfony\Component\HttpKernel\HttpKernelInterface::SUB_REQUEST);
|
||||||
|
$oResponse->send();
|
||||||
|
$oKernel->terminate($oSubRequest, $oResponse);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
$sFilter = utils::ReadParam('filter', '', false, 'raw_data');
|
$sFilter = utils::ReadParam('filter', '', false, 'raw_data');
|
||||||
$sEncoding = utils::ReadParam('encoding', 'serialize');
|
$sEncoding = utils::ReadParam('encoding', 'serialize');
|
||||||
$sClass = utils::ReadParam('class', 'MissingAjaxParam', false, 'class');
|
$sClass = utils::ReadParam('class', 'MissingAjaxParam', false, 'class');
|
||||||
$sStyle = utils::ReadParam('style', 'list');
|
$sStyle = utils::ReadParam('style', 'list');
|
||||||
|
|
||||||
|
|
||||||
$oAjaxRenderController = new AjaxRenderController();
|
$oAjaxRenderController = new AjaxRenderController();
|
||||||
|
|
||||||
switch ($operation) {
|
switch ($operation) {
|
||||||
@@ -1375,7 +1447,7 @@ JS
|
|||||||
<<<EOF
|
<<<EOF
|
||||||
$('.search-class-$sClassName button').prop('disabled', true);
|
$('.search-class-$sClassName button').prop('disabled', true);
|
||||||
|
|
||||||
$('.search-class-$sClassName h2').append(' <img id="indicator" src="../images/indicator.gif">');
|
$('.search-class-$sClassName h2').append(' <img id="indicator" src="' + GetAbsoluteUrlAppRoot() + 'images/indicator.gif">');
|
||||||
var oParams = {operation: 'full_text_search_enlarge', class: '$sClassName', text: '$sFullTextJS'};
|
var oParams = {operation: 'full_text_search_enlarge', class: '$sClassName', text: '$sFullTextJS'};
|
||||||
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(data) {
|
$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(data) {
|
||||||
$('.search-class-$sClassName').html(data);
|
$('.search-class-$sClassName').html(data);
|
||||||
@@ -1532,6 +1604,7 @@ EOF
|
|||||||
case 'xlsx_export_dialog':
|
case 'xlsx_export_dialog':
|
||||||
DeprecatedCallsLog::NotifyDeprecatedPhpEndpoint('Use "export_*" operations instead of "'.$operation.'"');
|
DeprecatedCallsLog::NotifyDeprecatedPhpEndpoint('Use "export_*" operations instead of "'.$operation.'"');
|
||||||
$sFilter = utils::ReadParam('filter', '', false, 'raw_data');
|
$sFilter = utils::ReadParam('filter', '', false, 'raw_data');
|
||||||
|
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||||
$oPage->SetContentType('text/html');
|
$oPage->SetContentType('text/html');
|
||||||
$oPage->add(
|
$oPage->add(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
@@ -1561,11 +1634,11 @@ EOF
|
|||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
background: url(../images/minus.gif) 0 2px no-repeat;
|
background: url({$sAppRootUrl}images/minus.gif) 0 2px no-repeat;
|
||||||
}
|
}
|
||||||
.statistics > div.closed {
|
.statistics > div.closed {
|
||||||
padding-left: 16px;
|
padding-left: 16px;
|
||||||
background: url(../images/plus.gif) 0 2px no-repeat;
|
background: url({$sAppRootUrl}images/plus.gif) 0 2px no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.statistics .closed .stats-data {
|
.statistics .closed .stats-data {
|
||||||
@@ -1594,7 +1667,7 @@ EOF
|
|||||||
);
|
);
|
||||||
$sJSLabels = json_encode($aLabels);
|
$sJSLabels = json_encode($aLabels);
|
||||||
$sFilter = addslashes($sFilter);
|
$sFilter = addslashes($sFilter);
|
||||||
$sJSPageUrl = addslashes(utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php');
|
$sJSPageUrl = addslashes($sAppRootUrl.'pages/ajax.render.php');
|
||||||
$oPage->add_ready_script("$('#XlsxExportDlg').xlsxexporter({filter: '$sFilter', labels: $sJSLabels, ajax_page_url: '$sJSPageUrl'});");
|
$oPage->add_ready_script("$('#XlsxExportDlg').xlsxexporter({filter: '$sFilter', labels: $sJSLabels, ajax_page_url: '$sJSPageUrl'});");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -2208,7 +2281,8 @@ EOF
|
|||||||
$oPage = new NiceWebPage(Dict::S('UI:BrowseInlineImages'));
|
$oPage = new NiceWebPage(Dict::S('UI:BrowseInlineImages'));
|
||||||
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/magnific-popup.css');
|
$oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/magnific-popup.css');
|
||||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.magnific-popup.min.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.magnific-popup.min.js');
|
||||||
$sImgUrl = utils::GetAbsoluteUrlAppRoot().INLINEIMAGE_DOWNLOAD_URL;
|
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||||
|
$sImgUrl = $sAppRootUrl.INLINEIMAGE_DOWNLOAD_URL;
|
||||||
|
|
||||||
/** @noinspection SuspiciousAssignmentsInspection cke_upload_and_browse and cke_browse are chained */
|
/** @noinspection SuspiciousAssignmentsInspection cke_upload_and_browse and cke_browse are chained */
|
||||||
$sTempId = utils::ReadParam('temp_id', '', false, 'transaction_id');
|
$sTempId = utils::ReadParam('temp_id', '', false, 'transaction_id');
|
||||||
@@ -2236,7 +2310,7 @@ EOF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$sPostUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php?CKEditorFuncNum='.$sCKEditorFuncNum;
|
$sPostUrl = $sAppRootUrl.'pages/ajax.render.php?CKEditorFuncNum='.$sCKEditorFuncNum;
|
||||||
|
|
||||||
$oPage->add_style(
|
$oPage->add_style(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
@@ -2304,7 +2378,7 @@ EOF
|
|||||||
$oPage->add_ready_script(
|
$oPage->add_ready_script(
|
||||||
<<<EOF
|
<<<EOF
|
||||||
$('#upload_button').on('change', function() {
|
$('#upload_button').on('change', function() {
|
||||||
$('#upload_status').html('<img src="../images/indicator.gif">');
|
$('#upload_status').html('<img src="{$sAppRootUrl}images/indicator.gif">');
|
||||||
$('#upload_form').submit();
|
$('#upload_form').submit();
|
||||||
$(this).prop('disabled', true);
|
$(this).prop('disabled', true);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ try
|
|||||||
$oAllCategoriesDashlet
|
$oAllCategoriesDashlet
|
||||||
->AddCSSClasses(['ibo-dashlet--is-inline', 'ibo-dashlet-badge'])
|
->AddCSSClasses(['ibo-dashlet--is-inline', 'ibo-dashlet-badge'])
|
||||||
->AddSubBlock(DashletFactory::MakeForDashletBadge(
|
->AddSubBlock(DashletFactory::MakeForDashletBadge(
|
||||||
'../images/icons/icons8-audit.svg',
|
utils::GetAbsoluteUrlAppRoot().'images/icons/icons8-audit.svg',
|
||||||
utils::GetAbsoluteUrlAppRoot()."pages/audit.php?operation=audit",
|
utils::GetAbsoluteUrlAppRoot()."pages/audit.php?operation=audit",
|
||||||
$iCategoryCount,
|
$iCategoryCount,
|
||||||
Dict::S('UI:Audit:Interactive:Selection:BadgeAll')
|
Dict::S('UI:Audit:Interactive:Selection:BadgeAll')
|
||||||
@@ -304,7 +304,7 @@ try
|
|||||||
/** @var AuditDomain $oAuditDomain */
|
/** @var AuditDomain $oAuditDomain */
|
||||||
while($oAuditDomain = $oDomainSet->Fetch()) {
|
while($oAuditDomain = $oDomainSet->Fetch()) {
|
||||||
$sDomainUrl = utils::GetAbsoluteUrlAppRoot()."pages/audit.php?operation=audit&domain=".$oAuditDomain->GetKey();
|
$sDomainUrl = utils::GetAbsoluteUrlAppRoot()."pages/audit.php?operation=audit&domain=".$oAuditDomain->GetKey();
|
||||||
$sIconUrl = '../images/icons/icons8-puzzle.svg';
|
$sIconUrl = utils::GetAbsoluteUrlAppRoot().'images/icons/icons8-puzzle.svg';
|
||||||
/** @var \ormDocument $oImage */
|
/** @var \ormDocument $oImage */
|
||||||
$oImage = $oAuditDomain->Get('icon');
|
$oImage = $oAuditDomain->Get('icon');
|
||||||
if (!$oImage->IsEmpty()) {
|
if (!$oImage->IsEmpty()) {
|
||||||
@@ -357,9 +357,9 @@ try
|
|||||||
$oP->AddUiBlock(TitleUIBlockFactory::MakeForPage($sTitle));
|
$oP->AddUiBlock(TitleUIBlockFactory::MakeForPage($sTitle));
|
||||||
$oP->AddUiBlock(new Text($sSubTitle));
|
$oP->AddUiBlock(new Text($sSubTitle));
|
||||||
|
|
||||||
$oTotalBlock = DashletFactory::MakeForDashletBadge('../images/icons/icons8-audit.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsAudited'));
|
$oTotalBlock = DashletFactory::MakeForDashletBadge(utils::GetAbsoluteUrlAppRoot().'images/icons/icons8-audit.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsAudited'));
|
||||||
$oErrorBlock = DashletFactory::MakeForDashletBadge('../images/icons/icons8-delete.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsInError'));
|
$oErrorBlock = DashletFactory::MakeForDashletBadge(utils::GetAbsoluteUrlAppRoot().'images/icons/icons8-delete.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsInError'));
|
||||||
$oWorkingBlock = DashletFactory::MakeForDashletBadge('../images/icons/icons8-checkmark.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsValidated'));
|
$oWorkingBlock = DashletFactory::MakeForDashletBadge(utils::GetAbsoluteUrlAppRoot().'images/icons/icons8-checkmark.svg', '#', 0, Dict::S('UI:Audit:Dashboard:ObjectsValidated'));
|
||||||
|
|
||||||
$aCSSClasses = ['ibo-dashlet--is-inline', 'ibo-dashlet-badge'];
|
$aCSSClasses = ['ibo-dashlet--is-inline', 'ibo-dashlet-badge'];
|
||||||
|
|
||||||
@@ -436,7 +436,7 @@ try
|
|||||||
foreach ($aErrors as $aErrorRow) {
|
foreach ($aErrors as $aErrorRow) {
|
||||||
$aObjectsWithErrors[$aErrorRow['id']] = true;
|
$aObjectsWithErrors[$aErrorRow['id']] = true;
|
||||||
}
|
}
|
||||||
$aRow['nb_errors'] = ($iErrorsCount == 0) ? '0' : "<a href=\"?operation=errors&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">$iErrorsCount</a> <a href=\"?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\"><img src=\"../images/icons/icons8-export-csv.svg\" class=\"ibo-audit--audit-line--csv-download\"></a>";
|
$aRow['nb_errors'] = ($iErrorsCount == 0) ? '0' : "<a href=\"?operation=errors&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\">$iErrorsCount</a> <a href=\"?operation=csv&category=".$oAuditCategory->GetKey()."&rule=".$oAuditRule->GetKey()."&".$oAppContext->GetForLink()."\"><img src=\"" . utils::GetAbsoluteUrlAppRoot() . "images/icons/icons8-export-csv.svg\" class=\"ibo-audit--audit-line--csv-download\"></a>";
|
||||||
$aRow['percent_ok'] = sprintf('%.2f', 100.0 * (($iCount - $iErrorsCount) / $iCount));
|
$aRow['percent_ok'] = sprintf('%.2f', 100.0 * (($iCount - $iErrorsCount) / $iCount));
|
||||||
$aRow['class'] = $oAuditCategory->GetReportColor($iCount, $iErrorsCount);
|
$aRow['class'] = $oAuditCategory->GetReportColor($iCount, $iErrorsCount);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -400,6 +400,7 @@ try {
|
|||||||
$iUnchanged = 0;
|
$iUnchanged = 0;
|
||||||
|
|
||||||
$aTableData = [];
|
$aTableData = [];
|
||||||
|
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||||
|
|
||||||
foreach ($aRes as $iLine => $aResRow) {
|
foreach ($aRes as $iLine => $aResRow) {
|
||||||
$aTableRow = [];
|
$aTableRow = [];
|
||||||
@@ -414,7 +415,7 @@ try {
|
|||||||
$sFinalClass = $aResRow['finalclass'];
|
$sFinalClass = $aResRow['finalclass'];
|
||||||
$oObj = MetaModel::GetObject($sFinalClass, $aResRow['id']->GetPureValue());
|
$oObj = MetaModel::GetObject($sFinalClass, $aResRow['id']->GetPureValue());
|
||||||
$sUrl = $oObj->GetHyperlink();
|
$sUrl = $oObj->GetHyperlink();
|
||||||
$sStatus = '<img src="../images/unchanged.png" title="'.Dict::S('UI:CSVReport-Icon-Unchanged').'">';
|
$sStatus = '<img src="' . $sAppRootUrl . 'images/unchanged.png" title="'.Dict::S('UI:CSVReport-Icon-Unchanged').'">';
|
||||||
$sCSSRowClass = 'ibo-csv-import--row-unchanged';
|
$sCSSRowClass = 'ibo-csv-import--row-unchanged';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -423,7 +424,7 @@ try {
|
|||||||
$sFinalClass = $aResRow['finalclass'];
|
$sFinalClass = $aResRow['finalclass'];
|
||||||
$oObj = MetaModel::GetObject($sFinalClass, $aResRow['id']->GetPureValue());
|
$oObj = MetaModel::GetObject($sFinalClass, $aResRow['id']->GetPureValue());
|
||||||
$sUrl = $oObj->GetHyperlink();
|
$sUrl = $oObj->GetHyperlink();
|
||||||
$sStatus = '<img src="../images/modified.png" title="'.Dict::S('UI:CSVReport-Icon-Modified').'">';
|
$sStatus = '<img src="' . $sAppRootUrl . 'images/modified.png" title="'.Dict::S('UI:CSVReport-Icon-Modified').'">';
|
||||||
$sCSSRowClass = 'ibo-csv-import--row-modified';
|
$sCSSRowClass = 'ibo-csv-import--row-modified';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -432,7 +433,7 @@ try {
|
|||||||
$sFinalClass = $aResRow['finalclass'];
|
$sFinalClass = $aResRow['finalclass'];
|
||||||
$oObj = MetaModel::GetObject($sFinalClass, $aResRow['id']->GetPureValue());
|
$oObj = MetaModel::GetObject($sFinalClass, $aResRow['id']->GetPureValue());
|
||||||
$sUrl = $oObj->GetHyperlink();
|
$sUrl = $oObj->GetHyperlink();
|
||||||
$sStatus = '<img src="../images/delete.png" title="'.Dict::S('UI:CSVReport-Icon-Missing').'">';
|
$sStatus = '<img src="' . $sAppRootUrl . 'images/delete.png" title="'.Dict::S('UI:CSVReport-Icon-Missing').'">';
|
||||||
$sCSSRowClass = 'ibo-csv-import--row-modified';
|
$sCSSRowClass = 'ibo-csv-import--row-modified';
|
||||||
if ($bSimulate) {
|
if ($bSimulate) {
|
||||||
$sMessage = Dict::S('UI:CSVReport-Object-MissingToUpdate');
|
$sMessage = Dict::S('UI:CSVReport-Object-MissingToUpdate');
|
||||||
@@ -443,7 +444,7 @@ try {
|
|||||||
|
|
||||||
case 'RowStatus_NewObj':
|
case 'RowStatus_NewObj':
|
||||||
$iCreated++;
|
$iCreated++;
|
||||||
$sStatus = '<img src="../images/added.png" title="'.Dict::S('UI:CSVReport-Icon-Created').'">';
|
$sStatus = '<img src="' . $sAppRootUrl . 'images/added.png" title="'.Dict::S('UI:CSVReport-Icon-Created').'">';
|
||||||
$sCSSRowClass = 'ibo-csv-import--row-added';
|
$sCSSRowClass = 'ibo-csv-import--row-added';
|
||||||
if ($bSimulate) {
|
if ($bSimulate) {
|
||||||
$sMessage = Dict::S('UI:CSVReport-Object-ToCreate');
|
$sMessage = Dict::S('UI:CSVReport-Object-ToCreate');
|
||||||
@@ -585,21 +586,21 @@ HTML;
|
|||||||
$oMulticolumn->AddCSSClass('ml-1');
|
$oMulticolumn->AddCSSClass('ml-1');
|
||||||
$oForm->AddSubBlock($oMulticolumn);
|
$oForm->AddSubBlock($oMulticolumn);
|
||||||
|
|
||||||
$oCheckBoxUnchanged = InputUIBlockFactory::MakeForInputWithLabel('<img src="../images/unchanged.png"> '.sprintf($aDisplayFilters['unchanged'], $iUnchanged), '', "1", "show_unchanged", "checkbox");
|
$oCheckBoxUnchanged = InputUIBlockFactory::MakeForInputWithLabel('<img src="' . $sAppRootUrl . 'images/unchanged.png"> '.sprintf($aDisplayFilters['unchanged'], $iUnchanged), '', "1", "show_unchanged", "checkbox");
|
||||||
$oCheckBoxUnchanged->GetInput()->SetIsChecked(true);
|
$oCheckBoxUnchanged->GetInput()->SetIsChecked(true);
|
||||||
$oCheckBoxUnchanged->SetBeforeInput(false);
|
$oCheckBoxUnchanged->SetBeforeInput(false);
|
||||||
$oCheckBoxUnchanged->GetInput()->AddCSSClass('ibo-input-checkbox');
|
$oCheckBoxUnchanged->GetInput()->AddCSSClass('ibo-input-checkbox');
|
||||||
$oMulticolumn->AddColumn(ColumnUIBlockFactory::MakeForBlock($oCheckBoxUnchanged));
|
$oMulticolumn->AddColumn(ColumnUIBlockFactory::MakeForBlock($oCheckBoxUnchanged));
|
||||||
$oPage->add_ready_script("$('#show_unchanged').on('click', function(){ToggleRows('ibo-csv-import--row-unchanged')})");
|
$oPage->add_ready_script("$('#show_unchanged').on('click', function(){ToggleRows('ibo-csv-import--row-unchanged')})");
|
||||||
|
|
||||||
$oCheckBoxUnchanged = InputUIBlockFactory::MakeForInputWithLabel('<img src="../images/modified.png"> '.sprintf($aDisplayFilters['modified'], $iModified), '', "1", "show_modified", "checkbox");
|
$oCheckBoxUnchanged = InputUIBlockFactory::MakeForInputWithLabel('<img src="' . $sAppRootUrl . 'images/modified.png"> '.sprintf($aDisplayFilters['modified'], $iModified), '', "1", "show_modified", "checkbox");
|
||||||
$oCheckBoxUnchanged->GetInput()->SetIsChecked(true);
|
$oCheckBoxUnchanged->GetInput()->SetIsChecked(true);
|
||||||
$oCheckBoxUnchanged->SetBeforeInput(false);
|
$oCheckBoxUnchanged->SetBeforeInput(false);
|
||||||
$oCheckBoxUnchanged->GetInput()->AddCSSClass('ibo-input-checkbox');
|
$oCheckBoxUnchanged->GetInput()->AddCSSClass('ibo-input-checkbox');
|
||||||
$oMulticolumn->AddColumn(ColumnUIBlockFactory::MakeForBlock($oCheckBoxUnchanged));
|
$oMulticolumn->AddColumn(ColumnUIBlockFactory::MakeForBlock($oCheckBoxUnchanged));
|
||||||
$oPage->add_ready_script("$('#show_modified').on('click', function(){ToggleRows('ibo-csv-import--row-modified')})");
|
$oPage->add_ready_script("$('#show_modified').on('click', function(){ToggleRows('ibo-csv-import--row-modified')})");
|
||||||
|
|
||||||
$oCheckBoxUnchanged = InputUIBlockFactory::MakeForInputWithLabel('<img src="../images/added.png"> '.sprintf($aDisplayFilters['added'], $iCreated), '', "1", "show_created", "checkbox");
|
$oCheckBoxUnchanged = InputUIBlockFactory::MakeForInputWithLabel('<img src="' . $sAppRootUrl . 'images/added.png"> '.sprintf($aDisplayFilters['added'], $iCreated), '', "1", "show_created", "checkbox");
|
||||||
$oCheckBoxUnchanged->GetInput()->SetIsChecked(true);
|
$oCheckBoxUnchanged->GetInput()->SetIsChecked(true);
|
||||||
$oCheckBoxUnchanged->SetBeforeInput(false);
|
$oCheckBoxUnchanged->SetBeforeInput(false);
|
||||||
$oCheckBoxUnchanged->GetInput()->AddCSSClass('ibo-input-checkbox');
|
$oCheckBoxUnchanged->GetInput()->AddCSSClass('ibo-input-checkbox');
|
||||||
|
|||||||
@@ -81,8 +81,8 @@ if (is_link($sPageEnvFullPath)) {
|
|||||||
$aPossibleBasePaths = [
|
$aPossibleBasePaths = [
|
||||||
APPROOT.$sSourceDir,
|
APPROOT.$sSourceDir,
|
||||||
APPROOT.'extensions',
|
APPROOT.'extensions',
|
||||||
APPROOT.'data/'.$sEnvironment.'-modules',
|
utils::GetDataPath().$sEnvironment.'-modules',
|
||||||
APPROOT.'data/downloaded-extensions', // Hub connector
|
utils::GetDataPath().'downloaded-extensions', // Hub connector
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
$aPossibleBasePaths = [$sEnvFullPath];
|
$aPossibleBasePaths = [$sEnvFullPath];
|
||||||
|
|||||||
@@ -111,17 +111,17 @@ $sDotExecutable = MetaModel::GetConfig()->Get('graphviz_path');
|
|||||||
if (file_exists($sDotExecutable))
|
if (file_exists($sDotExecutable))
|
||||||
{
|
{
|
||||||
// create the file with Graphviz
|
// create the file with Graphviz
|
||||||
$sImageFilePath = APPROOT."data/lifecycle/".$sClass.".svg";
|
$sImageFilePath = utils::GetDataPath()."lifecycle/".$sClass.".svg";
|
||||||
if (!is_dir(APPROOT."data"))
|
if (!is_dir(utils::GetDataPath()))
|
||||||
{
|
{
|
||||||
@mkdir(APPROOT."data");
|
@mkdir(utils::GetDataPath());
|
||||||
}
|
}
|
||||||
if (!is_dir(APPROOT."data/lifecycle"))
|
if (!is_dir(utils::GetDataPath()."lifecycle"))
|
||||||
{
|
{
|
||||||
@mkdir(APPROOT."data/lifecycle");
|
@mkdir(utils::GetDataPath()."lifecycle");
|
||||||
}
|
}
|
||||||
$sDotDescription = GraphvizLifecycle($sClass);
|
$sDotDescription = GraphvizLifecycle($sClass);
|
||||||
$sDotFilePath = APPROOT."data/lifecycle/{$sClass}.dot";
|
$sDotFilePath = utils::GetDataPath()."lifecycle/{$sClass}.dot";
|
||||||
|
|
||||||
$rFile = @fopen($sDotFilePath, "w");
|
$rFile = @fopen($sDotFilePath, "w");
|
||||||
@fwrite($rFile, $sDotDescription);
|
@fwrite($rFile, $sDotDescription);
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ function ValidateOtherSettings()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$('#v_default_page_size').html('<img src="../images/validation_error.png"/>');
|
$('#v_default_page_size').html('<img src="' + GetAbsoluteUrlAppRoot() + 'images/validation_error.png"/>');
|
||||||
$('#ibo-misc-settings-submit').prop('disabled', true);
|
$('#ibo-misc-settings-submit').prop('disabled', true);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -417,7 +417,7 @@ JS
|
|||||||
|
|
||||||
$oUserPicturePlaceHolderBlock = new Panel(Dict::S('UI:Preferences:ChooseAPlaceholder'), array(), 'grey', 'ibo-user-picture-placeholder');
|
$oUserPicturePlaceHolderBlock = new Panel(Dict::S('UI:Preferences:ChooseAPlaceholder'), array(), 'grey', 'ibo-user-picture-placeholder');
|
||||||
|
|
||||||
$sUserPicturesFolder = '../images/user-pictures/';
|
$sUserPicturesFolder = utils::GetAbsoluteUrlAppRoot() . 'images/user-pictures/';
|
||||||
$sUserDefaultPicture = appUserPreferences::GetPref('user_picture_placeholder', 'default-placeholder.png');
|
$sUserDefaultPicture = appUserPreferences::GetPref('user_picture_placeholder', 'default-placeholder.png');
|
||||||
$sUserPicturePlaceHolderHtml = '';
|
$sUserPicturePlaceHolderHtml = '';
|
||||||
$sUserPicturePlaceHolderHtml .= '<p>'.Dict::S('UI:Preferences:ChooseAPlaceholder+').'</p> <div class="ibo-preferences--user-preferences--picture-placeholder">';
|
$sUserPicturePlaceHolderHtml .= '<p>'.Dict::S('UI:Preferences:ChooseAPlaceholder+').'</p> <div class="ibo-preferences--user-preferences--picture-placeholder">';
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ try
|
|||||||
// Main program
|
// Main program
|
||||||
//
|
//
|
||||||
$oP = new iTopWebPage(Dict::S('Menu:TagAdminMenu+'));
|
$oP = new iTopWebPage(Dict::S('Menu:TagAdminMenu+'));
|
||||||
$oP->add_linked_script("../js/forms-json-utils.js");
|
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/forms-json-utils.js");
|
||||||
$oP->add_linked_script("../js/wizardhelper.js");
|
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/wizardhelper.js");
|
||||||
$oP->add_linked_script("../js/wizard.utils.js");
|
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/wizard.utils.js");
|
||||||
$oP->add_linked_script("../js/extkeywidget.js");
|
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/extkeywidget.js");
|
||||||
$oP->add_linked_script("../js/jquery.blockUI.js");
|
$oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/jquery.blockUI.js");
|
||||||
|
|
||||||
$sBaseClass = 'TagSetFieldData';
|
$sBaseClass = 'TagSetFieldData';
|
||||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||||
|
|||||||
@@ -626,14 +626,14 @@ class ApplicationInstaller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Dump the "reference" model, just before loading any actual delta
|
// Dump the "reference" model, just before loading any actual delta
|
||||||
$oFactory->SaveToFile(APPROOT.'data/datamodel-'.$sEnvironment.'.xml');
|
$oFactory->SaveToFile(utils::GetDataPath().'datamodel-'.$sEnvironment.'.xml');
|
||||||
|
|
||||||
$sDeltaFile = APPROOT.'data/'.$sEnvironment.'.delta.xml';
|
$sDeltaFile = utils::GetDataPath().$sEnvironment.'.delta.xml';
|
||||||
if (file_exists($sDeltaFile))
|
if (file_exists($sDeltaFile))
|
||||||
{
|
{
|
||||||
$oDelta = new MFDeltaModule($sDeltaFile);
|
$oDelta = new MFDeltaModule($sDeltaFile);
|
||||||
$oFactory->LoadModule($oDelta);
|
$oFactory->LoadModule($oDelta);
|
||||||
$oFactory->SaveToFile(APPROOT.'data/datamodel-'.$sEnvironment.'-with-delta.xml');
|
$oFactory->SaveToFile(utils::GetDataPath().'datamodel-'.$sEnvironment.'-with-delta.xml');
|
||||||
}
|
}
|
||||||
|
|
||||||
$oMFCompiler = new MFCompiler($oFactory, $sEnvironment);
|
$oMFCompiler = new MFCompiler($oFactory, $sEnvironment);
|
||||||
@@ -658,8 +658,8 @@ class ApplicationInstaller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set an "Instance UUID" identifying this machine based on a file located in the data directory
|
// Set an "Instance UUID" identifying this machine based on a file located in the data directory
|
||||||
$sInstanceUUIDFile = APPROOT.'data/instance.txt';
|
$sInstanceUUIDFile = utils::GetDataPath().'instance.txt';
|
||||||
SetupUtils::builddir(APPROOT.'data');
|
SetupUtils::builddir(utils::GetDataPath());
|
||||||
if (!file_exists($sInstanceUUIDFile))
|
if (!file_exists($sInstanceUUIDFile))
|
||||||
{
|
{
|
||||||
$sIntanceUUID = utils::CreateUUID('filesystem');
|
$sIntanceUUID = utils::CreateUUID('filesystem');
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ class DBBackup
|
|||||||
|
|
||||||
$oArchive = new ITopArchiveTar($sTargetFile.'.tar.gz');
|
$oArchive = new ITopArchiveTar($sTargetFile.'.tar.gz');
|
||||||
|
|
||||||
$sTmpFolder = APPROOT.'data/tmp-backup-'.rand(10000, getrandmax());
|
$sTmpFolder = utils::GetDataPath().'tmp-backup-'.rand(10000, getrandmax());
|
||||||
$aFiles = $this->PrepareFilesToBackup($sSourceConfigFile, $sTmpFolder);
|
$aFiles = $this->PrepareFilesToBackup($sSourceConfigFile, $sTmpFolder);
|
||||||
|
|
||||||
$sFilesList = var_export($aFiles, true);
|
$sFilesList = var_export($aFiles, true);
|
||||||
@@ -248,7 +248,7 @@ class DBBackup
|
|||||||
$aRet[] = $sFile;
|
$aRet[] = $sFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sDeltaFile = APPROOT.'data/'.utils::GetCurrentEnvironment().'.delta.xml';
|
$sDeltaFile = utils::GetDataPath().utils::GetCurrentEnvironment().'.delta.xml';
|
||||||
if (file_exists($sDeltaFile))
|
if (file_exists($sDeltaFile))
|
||||||
{
|
{
|
||||||
$sFile = $sTmpFolder.'/delta.xml';
|
$sFile = $sTmpFolder.'/delta.xml';
|
||||||
@@ -256,7 +256,7 @@ class DBBackup
|
|||||||
copy($sDeltaFile, $sFile);
|
copy($sDeltaFile, $sFile);
|
||||||
$aRet[] = $sFile;
|
$aRet[] = $sFile;
|
||||||
}
|
}
|
||||||
$sExtraDir = APPROOT.'data/'.utils::GetCurrentEnvironment().'-modules/';
|
$sExtraDir = utils::GetDataPath().utils::GetCurrentEnvironment().'-modules/';
|
||||||
if (is_dir($sExtraDir))
|
if (is_dir($sExtraDir))
|
||||||
{
|
{
|
||||||
$sModules = utils::GetCurrentEnvironment().'-modules';
|
$sModules = utils::GetCurrentEnvironment().'-modules';
|
||||||
|
|||||||
@@ -380,7 +380,7 @@ class RunTimeEnvironment
|
|||||||
{
|
{
|
||||||
$aDirsToCompile[] = APPROOT.'extensions';
|
$aDirsToCompile[] = APPROOT.'extensions';
|
||||||
}
|
}
|
||||||
$sExtraDir = APPROOT.'data/'.$this->sTargetEnv.'-modules/';
|
$sExtraDir = utils::GetDataPath().$this->sTargetEnv.'-modules/';
|
||||||
if (is_dir($sExtraDir))
|
if (is_dir($sExtraDir))
|
||||||
{
|
{
|
||||||
$aDirsToCompile[] = $sExtraDir;
|
$aDirsToCompile[] = $sExtraDir;
|
||||||
@@ -475,7 +475,7 @@ class RunTimeEnvironment
|
|||||||
}
|
}
|
||||||
while($bModuleAdded);
|
while($bModuleAdded);
|
||||||
|
|
||||||
$sDeltaFile = APPROOT.'data/'.$this->sTargetEnv.'.delta.xml';
|
$sDeltaFile = utils::GetDataPath().$this->sTargetEnv.'.delta.xml';
|
||||||
if (file_exists($sDeltaFile))
|
if (file_exists($sDeltaFile))
|
||||||
{
|
{
|
||||||
$oDelta = new MFDeltaModule($sDeltaFile);
|
$oDelta = new MFDeltaModule($sDeltaFile);
|
||||||
@@ -512,7 +512,7 @@ class RunTimeEnvironment
|
|||||||
{
|
{
|
||||||
// Just before loading the delta, let's save an image of the datamodel
|
// Just before loading the delta, let's save an image of the datamodel
|
||||||
// in case there is no delta the operation will be done after the end of the loop
|
// in case there is no delta the operation will be done after the end of the loop
|
||||||
$oFactory->SaveToFile(APPROOT.'data/datamodel-'.$this->sTargetEnv.'.xml');
|
$oFactory->SaveToFile(utils::GetDataPath().'datamodel-'.$this->sTargetEnv.'.xml');
|
||||||
}
|
}
|
||||||
$oFactory->LoadModule($oModule);
|
$oFactory->LoadModule($oModule);
|
||||||
}
|
}
|
||||||
@@ -520,10 +520,10 @@ class RunTimeEnvironment
|
|||||||
|
|
||||||
if ($oModule instanceof MFDeltaModule) {
|
if ($oModule instanceof MFDeltaModule) {
|
||||||
// A delta was loaded, let's save a second copy of the datamodel
|
// A delta was loaded, let's save a second copy of the datamodel
|
||||||
$oFactory->SaveToFile(APPROOT.'data/datamodel-'.$this->sTargetEnv.'-with-delta.xml');
|
$oFactory->SaveToFile(utils::GetDataPath().'datamodel-'.$this->sTargetEnv.'-with-delta.xml');
|
||||||
} else {
|
} else {
|
||||||
// No delta was loaded, let's save the datamodel now
|
// No delta was loaded, let's save the datamodel now
|
||||||
$oFactory->SaveToFile(APPROOT.'data/datamodel-'.$this->sTargetEnv.'.xml');
|
$oFactory->SaveToFile(utils::GetDataPath().'datamodel-'.$this->sTargetEnv.'.xml');
|
||||||
}
|
}
|
||||||
|
|
||||||
$sTargetDir = APPROOT.'env-'.$this->sTargetEnv;
|
$sTargetDir = APPROOT.'env-'.$this->sTargetEnv;
|
||||||
@@ -532,7 +532,7 @@ class RunTimeEnvironment
|
|||||||
$oMFCompiler = new MFCompiler($oFactory, $this->sFinalEnv);
|
$oMFCompiler = new MFCompiler($oFactory, $this->sFinalEnv);
|
||||||
$oMFCompiler->Compile($sTargetDir, null, $bUseSymLinks, $bSkipTempDir);
|
$oMFCompiler->Compile($sTargetDir, null, $bUseSymLinks, $bSkipTempDir);
|
||||||
|
|
||||||
$sCacheDir = APPROOT.'data/cache-'.$this->sTargetEnv;
|
$sCacheDir = utils::GetDataPath().'cache-'.$this->sTargetEnv;
|
||||||
SetupUtils::builddir($sCacheDir);
|
SetupUtils::builddir($sCacheDir);
|
||||||
SetupUtils::tidydir($sCacheDir);
|
SetupUtils::tidydir($sCacheDir);
|
||||||
|
|
||||||
@@ -942,38 +942,38 @@ class RunTimeEnvironment
|
|||||||
{
|
{
|
||||||
if ($this->sFinalEnv != $this->sTargetEnv)
|
if ($this->sFinalEnv != $this->sTargetEnv)
|
||||||
{
|
{
|
||||||
if (file_exists(APPROOT.'data/'.$this->sTargetEnv.'.delta.xml'))
|
if (file_exists(utils::GetDataPath().$this->sTargetEnv.'.delta.xml'))
|
||||||
{
|
{
|
||||||
if (file_exists(APPROOT.'data/'.$this->sFinalEnv.'.delta.xml'))
|
if (file_exists(utils::GetDataPath().$this->sFinalEnv.'.delta.xml'))
|
||||||
{
|
{
|
||||||
// Make a "previous" file
|
// Make a "previous" file
|
||||||
copy(
|
copy(
|
||||||
APPROOT.'data/'.$this->sFinalEnv.'.delta.xml',
|
utils::GetDataPath().$this->sFinalEnv.'.delta.xml',
|
||||||
APPROOT.'data/'.$this->sFinalEnv.'.delta.prev.xml'
|
utils::GetDataPath().$this->sFinalEnv.'.delta.prev.xml'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$this->CommitFile(
|
$this->CommitFile(
|
||||||
APPROOT.'data/'.$this->sTargetEnv.'.delta.xml',
|
utils::GetDataPath().$this->sTargetEnv.'.delta.xml',
|
||||||
APPROOT.'data/'.$this->sFinalEnv.'.delta.xml'
|
utils::GetDataPath().$this->sFinalEnv.'.delta.xml'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$this->CommitFile(
|
$this->CommitFile(
|
||||||
APPROOT.'data/datamodel-'.$this->sTargetEnv.'.xml',
|
utils::GetDataPath().'datamodel-'.$this->sTargetEnv.'.xml',
|
||||||
APPROOT.'data/datamodel-'.$this->sFinalEnv.'.xml'
|
utils::GetDataPath().'datamodel-'.$this->sFinalEnv.'.xml'
|
||||||
);
|
);
|
||||||
$this->CommitFile(
|
$this->CommitFile(
|
||||||
APPROOT.'data/datamodel-'.$this->sTargetEnv.'-with-delta.xml',
|
utils::GetDataPath().'datamodel-'.$this->sTargetEnv.'-with-delta.xml',
|
||||||
APPROOT.'data/datamodel-'.$this->sFinalEnv.'-with-delta.xml',
|
utils::GetDataPath().'datamodel-'.$this->sFinalEnv.'-with-delta.xml',
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
$this->CommitDir(
|
$this->CommitDir(
|
||||||
APPROOT.'data/'.$this->sTargetEnv.'-modules/',
|
utils::GetDataPath().$this->sTargetEnv.'-modules/',
|
||||||
APPROOT.'data/'.$this->sFinalEnv.'-modules/',
|
utils::GetDataPath().$this->sFinalEnv.'-modules/',
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
$this->CommitDir(
|
$this->CommitDir(
|
||||||
APPROOT.'data/cache-'.$this->sTargetEnv,
|
utils::GetDataPath().'cache-'.$this->sTargetEnv,
|
||||||
APPROOT.'data/cache-'.$this->sFinalEnv,
|
utils::GetDataPath().'cache-'.$this->sFinalEnv,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
$this->CommitDir(
|
$this->CommitDir(
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ class SetupPage extends NiceWebPage
|
|||||||
public function __construct($sTitle)
|
public function __construct($sTitle)
|
||||||
{
|
{
|
||||||
parent::__construct($sTitle);
|
parent::__construct($sTitle);
|
||||||
$this->add_linked_script("../js/jquery.blockUI.js");
|
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/jquery.blockUI.js");
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'node_modules/@popperjs/core/dist/umd/popper.js');
|
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'node_modules/@popperjs/core/dist/umd/popper.js');
|
||||||
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'node_modules/tippy.js/dist/tippy-bundle.umd.js');
|
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'node_modules/tippy.js/dist/tippy-bundle.umd.js');
|
||||||
$this->add_linked_script("../setup/setup.js");
|
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "setup/setup.js");
|
||||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
|
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
|
||||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-combodo/font-combodo.css');
|
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-combodo/font-combodo.css');
|
||||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'node_modules/tippy.js/dist/tippy.css');
|
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'node_modules/tippy.js/dist/tippy.css');
|
||||||
|
|||||||
@@ -1581,7 +1581,7 @@ JS
|
|||||||
if (is_dir($oWizard->GetParameter('copy_extensions_from'))) {
|
if (is_dir($oWizard->GetParameter('copy_extensions_from'))) {
|
||||||
$aDirsToScan[] = $oWizard->GetParameter('copy_extensions_from');
|
$aDirsToScan[] = $oWizard->GetParameter('copy_extensions_from');
|
||||||
}
|
}
|
||||||
$sExtraDir = APPROOT.'data/production-modules/';
|
$sExtraDir = utils::GetDataPath().'production-modules/';
|
||||||
if (is_dir($sExtraDir))
|
if (is_dir($sExtraDir))
|
||||||
{
|
{
|
||||||
$aDirsToScan[] = $sExtraDir;
|
$aDirsToScan[] = $sExtraDir;
|
||||||
@@ -1935,7 +1935,7 @@ JS
|
|||||||
if (empty($sEnv)) {
|
if (empty($sEnv)) {
|
||||||
$aLicenceFiles = array_merge($aLicenceFiles, glob(APPROOT.'datamodels/*/*/license.*.xml'));
|
$aLicenceFiles = array_merge($aLicenceFiles, glob(APPROOT.'datamodels/*/*/license.*.xml'));
|
||||||
$aLicenceFiles = array_merge($aLicenceFiles, glob(APPROOT.'extensions/{*,*/*}/license.*.xml', GLOB_BRACE));
|
$aLicenceFiles = array_merge($aLicenceFiles, glob(APPROOT.'extensions/{*,*/*}/license.*.xml', GLOB_BRACE));
|
||||||
$aLicenceFiles = array_merge($aLicenceFiles, glob(APPROOT.'data/*-modules/{*,*/*}/license.*.xml', GLOB_BRACE));
|
$aLicenceFiles = array_merge($aLicenceFiles, glob(utils::GetDataPath().'*-modules/{*,*/*}/license.*.xml', GLOB_BRACE));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2067,11 +2067,11 @@ JS
|
|||||||
if (!is_dir(APPROOT.'data')) {
|
if (!is_dir(APPROOT.'data')) {
|
||||||
mkdir(APPROOT.'data');
|
mkdir(APPROOT.'data');
|
||||||
}
|
}
|
||||||
if (!is_dir(APPROOT.'data/setup')) {
|
if (!is_dir(utils::GetDataPath().'setup')) {
|
||||||
mkdir(APPROOT.'data/setup');
|
mkdir(utils::GetDataPath().'setup');
|
||||||
}
|
}
|
||||||
$sUID = hash('sha256', rand());
|
$sUID = hash('sha256', rand());
|
||||||
file_put_contents(APPROOT.'data/setup/authent', $sUID);
|
file_put_contents(utils::GetDataPath().'setup/authent', $sUID);
|
||||||
Session::Set('setup_token', $sUID);
|
Session::Set('setup_token', $sUID);
|
||||||
return $sUID;
|
return $sUID;
|
||||||
}
|
}
|
||||||
@@ -2087,7 +2087,7 @@ JS
|
|||||||
final public static function CheckSetupToken($bRemoveToken = false)
|
final public static function CheckSetupToken($bRemoveToken = false)
|
||||||
{
|
{
|
||||||
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
|
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
|
||||||
$sTokenFile = APPROOT.'data/setup/authent';
|
$sTokenFile = utils::GetDataPath().'setup/authent';
|
||||||
if (!file_exists($sTokenFile) || $sAuthent !== file_get_contents($sTokenFile)) {
|
if (!file_exists($sTokenFile) || $sAuthent !== file_get_contents($sTokenFile)) {
|
||||||
throw new SecurityException('Setup operations are not allowed outside of the setup');
|
throw new SecurityException('Setup operations are not allowed outside of the setup');
|
||||||
}
|
}
|
||||||
@@ -2106,7 +2106,7 @@ JS
|
|||||||
{
|
{
|
||||||
if (Session::IsSet('setup_token')) {
|
if (Session::IsSet('setup_token')) {
|
||||||
$sAuth = Session::Get('setup_token');
|
$sAuth = Session::Get('setup_token');
|
||||||
$sTokenFile = APPROOT.'data/setup/authent';
|
$sTokenFile = utils::GetDataPath().'setup/authent';
|
||||||
if (file_exists($sTokenFile) && $sAuth === file_get_contents($sTokenFile)) {
|
if (file_exists($sTokenFile) && $sAuth === file_get_contents($sTokenFile)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -2120,7 +2120,7 @@ JS
|
|||||||
*/
|
*/
|
||||||
public static function EraseSetupToken()
|
public static function EraseSetupToken()
|
||||||
{
|
{
|
||||||
$sTokenFile = APPROOT.'data/setup/authent';
|
$sTokenFile = utils::GetDataPath().'setup/authent';
|
||||||
if (is_file($sTokenFile)) {
|
if (is_file($sTokenFile)) {
|
||||||
unlink($sTokenFile);
|
unlink($sTokenFile);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ HTML;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$oPage->add_linked_script('../setup/setup.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'setup/setup.js');
|
||||||
$oPage->add_script("function CanMoveForward()\n{\n".$oStep->JSCanMoveForward()."\n}\n");
|
$oPage->add_script("function CanMoveForward()\n{\n".$oStep->JSCanMoveForward()."\n}\n");
|
||||||
$oPage->add_script("function CanMoveBackward()\n{\n".$oStep->JSCanMoveBackward()."\n}\n");
|
$oPage->add_script("function CanMoveBackward()\n{\n".$oStep->JSCanMoveBackward()."\n}\n");
|
||||||
$oPage->add('<form id="wiz_form" class="ibo-setup--wizard" method="post">');
|
$oPage->add('<form id="wiz_form" class="ibo-setup--wizard" method="post">');
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ class WizStepInstallOrUpgrade extends WizardStep
|
|||||||
$sPreviousVersionDir = '';
|
$sPreviousVersionDir = '';
|
||||||
if ($sInstallMode == '')
|
if ($sInstallMode == '')
|
||||||
{
|
{
|
||||||
$sDBBackupPath = APPROOT.'data/backups/manual/setup-'.date('Y-m-d_H_i');
|
$sDBBackupPath = utils::GetDataPath().'backups/manual/setup-'.date('Y-m-d_H_i');
|
||||||
$bDBBackup = true;
|
$bDBBackup = true;
|
||||||
$aPreviousInstance = SetupUtils::GetPreviousInstance(APPROOT);
|
$aPreviousInstance = SetupUtils::GetPreviousInstance(APPROOT);
|
||||||
if ($aPreviousInstance['found']) {
|
if ($aPreviousInstance['found']) {
|
||||||
@@ -2307,7 +2307,7 @@ class WizStepSummary extends WizardStep
|
|||||||
|
|
||||||
$oPage->add('<fieldset id="installation_progress"><legend>Progress of the installation</legend>');
|
$oPage->add('<fieldset id="installation_progress"><legend>Progress of the installation</legend>');
|
||||||
$oPage->add('<div id="progress_content">');
|
$oPage->add('<div id="progress_content">');
|
||||||
$oPage->add_linked_script('../setup/jquery.progression.js');
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'setup/jquery.progression.js');
|
||||||
$oPage->add('<p class="center"><span id="setup_msg">Ready to start...</span></p><div style="display:block;margin-left: auto; margin-right:auto;" id="progress">0%</div>');
|
$oPage->add('<p class="center"><span id="setup_msg">Ready to start...</span></p><div style="display:block;margin-left: auto; margin-right:auto;" id="progress">0%</div>');
|
||||||
$oPage->add('</div>'); // progress_content
|
$oPage->add('</div>'); // progress_content
|
||||||
$oPage->add('</fieldset>');
|
$oPage->add('</fieldset>');
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
* @license http://opensource.org/licenses/AGPL-3.0
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
define ('KEYS_CACHE_FILE', APPROOT.'data/keyscache.tmp');
|
define ('KEYS_CACHE_FILE', utils::GetDataPath().'keyscache.tmp');
|
||||||
/**
|
/**
|
||||||
* Class to load sets of objects from XML files into the database
|
* Class to load sets of objects from XML files into the database
|
||||||
* XML files can be produced by the 'export' web service or by any other means
|
* XML files can be produced by the 'export' web service or by any other means
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ class FormHelper
|
|||||||
*/
|
*/
|
||||||
public static function DisableAttributeBlobInputs(string $sClassName, array &$aExtraParams): void
|
public static function DisableAttributeBlobInputs(string $sClassName, array &$aExtraParams): void
|
||||||
{
|
{
|
||||||
|
|
||||||
// Initialize extra params array
|
// Initialize extra params array
|
||||||
if (!array_key_exists('fieldsFlags', $aExtraParams)) {
|
if (!array_key_exists('fieldsFlags', $aExtraParams)) {
|
||||||
$aExtraParams['fieldsFlags'] = [];
|
$aExtraParams['fieldsFlags'] = [];
|
||||||
@@ -64,13 +63,13 @@ class FormHelper
|
|||||||
$aExtraParams['fieldsComments'] = [];
|
$aExtraParams['fieldsComments'] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate throw class attributes...
|
// Iterate through class attributes...
|
||||||
|
$sAppRootUrl = utils::GetAbsoluteUrlAppRoot();
|
||||||
foreach (MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef) {
|
foreach (MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef) {
|
||||||
|
|
||||||
// Set attribute blobs in read only
|
// Set attribute blobs in read only
|
||||||
if ($oAttDef instanceof AttributeBlob) {
|
if ($oAttDef instanceof AttributeBlob) {
|
||||||
$aExtraParams['fieldsFlags'][$sAttCode] = OPT_ATT_READONLY;
|
$aExtraParams['fieldsFlags'][$sAttCode] = OPT_ATT_READONLY;
|
||||||
$aExtraParams['fieldsComments'][$sAttCode] = ' <img src="../images/transp-lock.png" style="vertical-align:middle" title="'.utils::EscapeHtml(Dict::S('UI:UploadNotSupportedInThisMode')).'"/>';
|
$aExtraParams['fieldsComments'][$sAttCode] = ' <img src="' . $sAppRootUrl . 'images/transp-lock.png" style="vertical-align:middle" title="'.utils::EscapeHtml(Dict::S('UI:UploadNotSupportedInThisMode')).'"/>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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\tUIContentAreas;
|
||||||
use Combodo\iTop\Application\UI\Base\UIBlock;
|
use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||||
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
||||||
use Combodo\iTop\Service\Router\Router;
|
|
||||||
use DBObject;
|
use DBObject;
|
||||||
use Dict;
|
use Dict;
|
||||||
use MetaModel;
|
use MetaModel;
|
||||||
@@ -100,12 +99,11 @@ class ObjectSummary extends ObjectDetails
|
|||||||
*/
|
*/
|
||||||
private function ComputeActions()
|
private function ComputeActions()
|
||||||
{
|
{
|
||||||
$oRouter = Router::GetInstance();
|
|
||||||
$oDetailsButton = null;
|
$oDetailsButton = null;
|
||||||
// We can pass a DBObject to the UIBlock, so we check for the DisplayModifyForm method
|
// 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)) {
|
if(method_exists($this->oObject, 'DisplayModifyForm') && UserRights::IsActionAllowed($this->sClassName, UR_ACTION_MODIFY)) {
|
||||||
$oPopoverMenu = new PopoverMenu();
|
$oPopoverMenu = new PopoverMenu();
|
||||||
|
|
||||||
$oDetailsAction = new URLPopupMenuItem(
|
$oDetailsAction = new URLPopupMenuItem(
|
||||||
'UI:Menu:View',
|
'UI:Menu:View',
|
||||||
Dict::S('UI:Menu:View'),
|
Dict::S('UI:Menu:View'),
|
||||||
@@ -113,12 +111,13 @@ class ObjectSummary extends ObjectDetails
|
|||||||
'_blank'
|
'_blank'
|
||||||
);
|
);
|
||||||
$oModifyButton = ButtonUIBlockFactory::MakeLinkNeutral(
|
$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'),
|
Dict::S('UI:Menu:Modify'),
|
||||||
'fas fa-external-link-alt',
|
'fas fa-external-link-alt',
|
||||||
'_blank',
|
'_blank',
|
||||||
);
|
);
|
||||||
|
|
||||||
$oPopoverMenu->AddItem('more-actions', PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem($oDetailsAction))->SetContainer(PopoverMenu::ENUM_CONTAINER_PARENT);
|
$oPopoverMenu->AddItem('more-actions', PopoverMenuItemFactory::MakeFromApplicationPopupMenuItem($oDetailsAction))->SetContainer(PopoverMenu::ENUM_CONTAINER_PARENT);
|
||||||
|
|
||||||
$oDetailsButton = ButtonGroupUIBlockFactory::MakeButtonWithOptionsMenu($oModifyButton, $oPopoverMenu);
|
$oDetailsButton = ButtonGroupUIBlockFactory::MakeButtonWithOptionsMenu($oModifyButton, $oPopoverMenu);
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ class ErrorPage extends NiceWebPage
|
|||||||
{
|
{
|
||||||
$oKpi = new ExecutionKPI();
|
$oKpi = new ExecutionKPI();
|
||||||
parent::__construct($sTitle);
|
parent::__construct($sTitle);
|
||||||
$this->add_linked_script("../js/jquery.blockUI.js");
|
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "js/jquery.blockUI.js");
|
||||||
$this->add_linked_script("../setup/setup.js");
|
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "setup/setup.js");
|
||||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
|
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css');
|
||||||
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-combodo/font-combodo.css');
|
$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-combodo/font-combodo.css');
|
||||||
$this->add_saas("css/setup.scss");
|
$this->add_saas("css/setup.scss");
|
||||||
@@ -58,7 +58,7 @@ class ErrorPage extends NiceWebPage
|
|||||||
if(utils::IsEasterEggAllowed())
|
if(utils::IsEasterEggAllowed())
|
||||||
{
|
{
|
||||||
$this->add('<div class="message message-valid">'.Dict::S('UI:ErrorPage:UnstableVersion').'</div>');
|
$this->add('<div class="message message-valid">'.Dict::S('UI:ErrorPage:UnstableVersion').'</div>');
|
||||||
$this->add('<img src="../images/alpha-fatal-error.gif">');
|
$this->add('<img src="' . utils::GetAbsoluteUrlAppRoot() . 'images/alpha-fatal-error.gif">');
|
||||||
$this->add('<div class="message message-valid">'.nl2br(Dict::S('UI:ErrorPage:KittyDisclaimer')).'</div>');
|
$this->add('<div class="message message-valid">'.nl2br(Dict::S('UI:ErrorPage:KittyDisclaimer')).'</div>');
|
||||||
}
|
}
|
||||||
$this->log_error($sText);
|
$this->log_error($sText);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ use Dict;
|
|||||||
use ExecutionKPI;
|
use ExecutionKPI;
|
||||||
use IssueLog;
|
use IssueLog;
|
||||||
use MetaModel;
|
use MetaModel;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use UserRights;
|
use UserRights;
|
||||||
use utils;
|
use utils;
|
||||||
|
|
||||||
@@ -734,15 +735,28 @@ class WebPage implements Page
|
|||||||
* Add a script (as an include, i.e. link) to the header of the page.<br>
|
* Add a script (as an include, i.e. link) to the header of the page.<br>
|
||||||
* Handles duplicates : calling twice with the same script will add the script only once
|
* Handles duplicates : calling twice with the same script will add the script only once
|
||||||
*
|
*
|
||||||
* @uses WebPage::$a_linked_scripts
|
* @param string $sLinkedScriptAbsUrl
|
||||||
* @param string $s_linked_script
|
*
|
||||||
* @return void
|
* @return void
|
||||||
|
* @uses WebPage::$a_linked_scripts
|
||||||
|
* @since 3.2.0 N°6935 $sLinkedScriptAbsUrl MUST be an absolute URL
|
||||||
*/
|
*/
|
||||||
public function add_linked_script($s_linked_script)
|
public function add_linked_script($sLinkedScriptAbsUrl)
|
||||||
{
|
{
|
||||||
if (!empty(trim($s_linked_script))) {
|
// Ensure there is actually an URI
|
||||||
$this->a_linked_scripts[$s_linked_script] = $s_linked_script;
|
if (utils::IsNullOrEmptyString(trim($sLinkedScriptAbsUrl))) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if URI is absolute ("://" do allow any protocol), otherwise warn that it's a deprecated behavior
|
||||||
|
if (false === stripos($sLinkedScriptAbsUrl, "://")) {
|
||||||
|
IssueLog::Warning("Linked script added to page with a non absolute URL, which may lead to it not being loaded and causing javascript errors.", null, [
|
||||||
|
"linked_script_url" => $sLinkedScriptAbsUrl,
|
||||||
|
"request_uri" => $_SERVER['REQUEST_URI'],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->a_linked_scripts[$sLinkedScriptAbsUrl] = $sLinkedScriptAbsUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1331,12 +1345,65 @@ JS;
|
|||||||
*/
|
*/
|
||||||
public function output()
|
public function output()
|
||||||
{
|
{
|
||||||
$oKpi = new ExecutionKPI();
|
|
||||||
// Send headers
|
// Send headers
|
||||||
foreach ($this->a_headers as $sHeader) {
|
foreach ($this->a_headers as $sHeader) {
|
||||||
header($sHeader);
|
header($sHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render HTML content
|
||||||
|
$sHtml = $this->RenderContent();
|
||||||
|
|
||||||
|
// Echo global HTML
|
||||||
|
$oKpi = new ExecutionKPI();
|
||||||
|
echo $sHtml;
|
||||||
|
$oKpi->ComputeAndReport('Echoing ('.round(strlen($sHtml) / 1024).' KB)');
|
||||||
|
|
||||||
|
if (class_exists('DBSearch')) {
|
||||||
|
DBSearch::RecordQueryTrace();
|
||||||
|
}
|
||||||
|
ExecutionKPI::ReportStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Symfony\Component\HttpFoundation\Response Generate the Symfony Response object (content + code + headers) for the current page, this is equivalent (and new way) of \WebPage::output() for Symfony controllers
|
||||||
|
* @since 3.2.0 N°6935
|
||||||
|
*/
|
||||||
|
public function GenerateResponse(): Response
|
||||||
|
{
|
||||||
|
// Render HTML content
|
||||||
|
$sHtml = $this->RenderContent();
|
||||||
|
|
||||||
|
// Prepare Symfony Response
|
||||||
|
$oKpi = new ExecutionKPI();
|
||||||
|
|
||||||
|
// Format headers as a key => value array to match Symfony Response format
|
||||||
|
$aHeadersAsAssocArray = [];
|
||||||
|
foreach ($this->a_headers as $sHeader) {
|
||||||
|
// Limit explode to only split at the first occurrence
|
||||||
|
list($sHeaderName, $sHeaderValue) = explode(': ', $sHeader, 2);
|
||||||
|
$aHeadersAsAssocArray[$sHeaderName] = $sHeaderValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$oResponse = new Response($sHtml, Response::HTTP_OK, $aHeadersAsAssocArray);
|
||||||
|
$oKpi->ComputeAndReport('Preparing response ('.round(strlen($sHtml) / 1024).' KB)');
|
||||||
|
|
||||||
|
if (class_exists('DBSearch')) {
|
||||||
|
DBSearch::RecordQueryTrace();
|
||||||
|
}
|
||||||
|
ExecutionKPI::ReportStats();
|
||||||
|
|
||||||
|
return $oResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string Complete HTML content of the \WebPage
|
||||||
|
* @throws \CoreTemplateException
|
||||||
|
* @throws \Twig\Error\LoaderError
|
||||||
|
* @since 3.2.0 N°6935
|
||||||
|
*/
|
||||||
|
protected function RenderContent(): string
|
||||||
|
{
|
||||||
|
$oKpi = new ExecutionKPI();
|
||||||
$s_captured_output = $this->ob_get_clean_safe();
|
$s_captured_output = $this->ob_get_clean_safe();
|
||||||
|
|
||||||
$aData = [];
|
$aData = [];
|
||||||
@@ -1390,16 +1457,10 @@ JS;
|
|||||||
$oTwigEnv = TwigHelper::GetTwigEnvironment(BlockRenderer::TWIG_BASE_PATH, BlockRenderer::TWIG_ADDITIONAL_PATHS);
|
$oTwigEnv = TwigHelper::GetTwigEnvironment(BlockRenderer::TWIG_BASE_PATH, BlockRenderer::TWIG_ADDITIONAL_PATHS);
|
||||||
// Render final TWIG into global HTML
|
// Render final TWIG into global HTML
|
||||||
$sHtml = TwigHelper::RenderTemplate($oTwigEnv, $aData, $this->GetTemplateRelPath());
|
$sHtml = TwigHelper::RenderTemplate($oTwigEnv, $aData, $this->GetTemplateRelPath());
|
||||||
$oKpi->ComputeAndReport(get_class($this).'output');
|
|
||||||
|
|
||||||
// Echo global HTML
|
$oKpi->ComputeAndReport("Rendering content (".static::class.")");
|
||||||
echo $sHtml;
|
|
||||||
$oKpi->ComputeAndReport('Echoing ('.round(strlen($sHtml) / 1024).' Kb)');
|
|
||||||
|
|
||||||
if (class_exists('DBSearch')) {
|
return $sHtml;
|
||||||
DBSearch::RecordQueryTrace();
|
|
||||||
}
|
|
||||||
ExecutionKPI::ReportStats();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -829,6 +829,31 @@ HTML;
|
|||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function output()
|
public function output()
|
||||||
|
{
|
||||||
|
// Send headers
|
||||||
|
if ($this->GetOutputFormat() === 'html') {
|
||||||
|
foreach ($this->a_headers as $sHeader) {
|
||||||
|
header($sHeader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render HTKL content
|
||||||
|
$sHtml = $this->RenderContent();
|
||||||
|
|
||||||
|
// Echo global HTML
|
||||||
|
$oKpi = new ExecutionKPI();
|
||||||
|
echo $sHtml;
|
||||||
|
$oKpi->ComputeAndReport('Echoing ('.round(strlen($sHtml) / 1024).' Kb)');
|
||||||
|
|
||||||
|
DBSearch::RecordQueryTrace();
|
||||||
|
ExecutionKPI::ReportStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
* @since 3.2.0 N°6935
|
||||||
|
*/
|
||||||
|
protected function RenderContent(): string
|
||||||
{
|
{
|
||||||
$oKpi = new ExecutionKPI();
|
$oKpi = new ExecutionKPI();
|
||||||
|
|
||||||
@@ -933,16 +958,16 @@ HTML;
|
|||||||
$aData['aDeferredBlocks']['oPageContent'] = $this->GetDeferredBlocks($this->GetContentLayout());
|
$aData['aDeferredBlocks']['oPageContent'] = $this->GetDeferredBlocks($this->GetContentLayout());
|
||||||
// - Prepare generic templates
|
// - Prepare generic templates
|
||||||
$aData['aTemplates'] = array();
|
$aData['aTemplates'] = array();
|
||||||
|
|
||||||
// TODO 3.1 Replace hardcoded 'Please wait' with dict entries
|
// TODO 3.1 Replace hardcoded 'Please wait' with dict entries
|
||||||
|
|
||||||
// - Modal template with loader
|
// - Modal template with loader
|
||||||
$oModalTemplateContentBlock = new UIContentBlock();
|
$oModalTemplateContentBlock = new UIContentBlock();
|
||||||
$oModalTemplateContentBlock->AddCSSClass('ibo-modal')
|
$oModalTemplateContentBlock->AddCSSClass('ibo-modal')
|
||||||
->AddDataAttribute('role', 'ibo-modal')
|
->AddDataAttribute('role', 'ibo-modal')
|
||||||
->AddSubBlock(SpinnerUIBlockFactory::MakeMedium(null, 'Please wait'));
|
->AddSubBlock(SpinnerUIBlockFactory::MakeMedium(null, 'Please wait'));
|
||||||
$aData['aTemplates'][] = TemplateUIBlockFactory::MakeForBlock('ibo-modal-template', $oModalTemplateContentBlock);
|
$aData['aTemplates'][] = TemplateUIBlockFactory::MakeForBlock('ibo-modal-template', $oModalTemplateContentBlock);
|
||||||
|
|
||||||
// - Small loader template
|
// - Small loader template
|
||||||
$oSmallLoaderTemplateContentBlock = new UIContentBlock();
|
$oSmallLoaderTemplateContentBlock = new UIContentBlock();
|
||||||
$oSmallLoaderTemplateContentBlock->AddSubBlock(SpinnerUIBlockFactory::MakeSmall(null , 'Please wait'));
|
$oSmallLoaderTemplateContentBlock->AddSubBlock(SpinnerUIBlockFactory::MakeSmall(null , 'Please wait'));
|
||||||
@@ -997,66 +1022,14 @@ HTML;
|
|||||||
|
|
||||||
$oTwigEnv = TwigHelper::GetTwigEnvironment(BlockRenderer::TWIG_BASE_PATH, BlockRenderer::TWIG_ADDITIONAL_PATHS);
|
$oTwigEnv = TwigHelper::GetTwigEnvironment(BlockRenderer::TWIG_BASE_PATH, BlockRenderer::TWIG_ADDITIONAL_PATHS);
|
||||||
|
|
||||||
// Send headers
|
|
||||||
if ($this->GetOutputFormat() === 'html') {
|
|
||||||
foreach ($this->a_headers as $sHeader) {
|
|
||||||
header($sHeader);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render final TWIG into global HTML
|
// Render final TWIG into global HTML
|
||||||
$sHtml = TwigHelper::RenderTemplate($oTwigEnv, $aData, $this->GetTemplateRelPath());
|
$sHtml = TwigHelper::RenderTemplate($oTwigEnv, $aData, $this->GetTemplateRelPath());
|
||||||
|
|
||||||
$oKpi->ComputeAndReport(get_class($this).' output');
|
$oKpi->ComputeAndReport("Rendering content (".static::class.")");
|
||||||
|
|
||||||
// Echo global HTML
|
|
||||||
echo $sHtml;
|
|
||||||
$oKpi->ComputeAndReport('Echoing ('.round(strlen($sHtml) / 1024).' Kb)');
|
|
||||||
|
|
||||||
DBSearch::RecordQueryTrace();
|
|
||||||
ExecutionKPI::ReportStats();
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
////////////////// ☢ DANGER ZONE ☢ /////////////////////
|
|
||||||
/////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// Render the tabs in the page (if any)
|
|
||||||
// $this->s_content = $this->m_oTabs->RenderIntoContent($this->s_content, $this);
|
|
||||||
|
|
||||||
// Put here the 'ready scripts' that must be executed after all others
|
|
||||||
$aMultiselectOptions = array(
|
|
||||||
'header' => true,
|
|
||||||
'checkAllText' => Dict::S('UI:SearchValue:CheckAll'),
|
|
||||||
'uncheckAllText' => Dict::S('UI:SearchValue:UncheckAll'),
|
|
||||||
'noneSelectedText' => Dict::S('UI:SearchValue:Any'),
|
|
||||||
'selectedText' => Dict::S('UI:SearchValue:NbSelected'),
|
|
||||||
'selectedList' => 1,
|
|
||||||
);
|
|
||||||
$sJSMultiselectOptions = json_encode($aMultiselectOptions);
|
|
||||||
$this->add_ready_script(
|
|
||||||
<<<EOF
|
|
||||||
// Since the event is only triggered when the hash changes, we need to trigger
|
|
||||||
// the event now, to handle the hash the page may have loaded with.
|
|
||||||
$(window).trigger( 'hashchange' );
|
|
||||||
|
|
||||||
// Some table are sort-able, some are not, let's fix this
|
|
||||||
$('table.listResults').each( function() { FixTableSorter($(this)); } );
|
|
||||||
|
|
||||||
$('.multiselect').multiselect($sJSMultiselectOptions);
|
|
||||||
EOF
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->outputCollapsibleSectionInit();
|
|
||||||
|
|
||||||
// TODO 3.0.0: Is this for the "Debug" popup? We should do a helper to display a popup in various cases (welcome message for example)
|
|
||||||
$s_captured_output = $this->ob_get_clean_safe();
|
|
||||||
|
|
||||||
|
|
||||||
|
return $sHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class iTopWizardWebPage extends iTopWebPage
|
|||||||
$sStyle = ($iIndex == $this->m_iCurrentStep) ? 'wizActiveStep' : 'wizStep';
|
$sStyle = ($iIndex == $this->m_iCurrentStep) ? 'wizActiveStep' : 'wizStep';
|
||||||
$aSteps[] = "<div class=\"$sStyle\"><span>$sStepTitle</span></div>";
|
$aSteps[] = "<div class=\"$sStyle\"><span>$sStepTitle</span></div>";
|
||||||
}
|
}
|
||||||
$sWizardHeader = "<div class=\"wizHeader\"><h1>".utils::EscapeHtml($this->s_title)."</h1>\n".implode("<div class=\"wizSeparator\"><img align=\"bottom\" src=\"../images/wizArrow.gif\"></div>", $aSteps)."<br style=\"clear:both;\"/></div>\n";
|
$sWizardHeader = "<div class=\"wizHeader\"><h1>".utils::EscapeHtml($this->s_title)."</h1>\n".implode("<div class=\"wizSeparator\"><img align=\"bottom\" src=\"" . utils::GetAbsoluteUrlAppRoot() . "images/wizArrow.gif\"></div>", $aSteps)."<br style=\"clear:both;\"/></div>\n";
|
||||||
$this->s_content = "$sWizardHeader<div class=\"wizContainer\">".$this->s_content."</div>";
|
$this->s_content = "$sWizardHeader<div class=\"wizContainer\">".$this->s_content."</div>";
|
||||||
parent::output();
|
parent::output();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* Copyright (C) 2013-2023 Combodo SARL
|
|
||||||
*
|
|
||||||
* This file is part of iTop.
|
|
||||||
*
|
|
||||||
* iTop is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* iTop is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Combodo\iTop\Controller;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class AbstractAppController
|
|
||||||
*
|
|
||||||
* @package Combodo\iTop\Controller
|
|
||||||
* @since 3.2.0
|
|
||||||
*/
|
|
||||||
class AbstractAppController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
namespace Combodo\iTop\Controller;
|
namespace Combodo\iTop\Controller;
|
||||||
|
|
||||||
|
use DeprecatedCallsLog;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as BaseAbstractControllerAlias;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class AbstractController
|
* Class AbstractController
|
||||||
*
|
*
|
||||||
@@ -15,14 +18,17 @@ namespace Combodo\iTop\Controller;
|
|||||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||||
* @package Combodo\iTop\Controller
|
* @package Combodo\iTop\Controller
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
|
* @since 3.2.0 N°6935 Controller is now based on Symfony controller
|
||||||
*/
|
*/
|
||||||
abstract class AbstractController implements iController
|
abstract class AbstractController extends BaseAbstractControllerAlias implements iController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
|
* @deprecated 3.2.0 N°6935 Use \Symfony\Component\HttpFoundation\Request::isXmlHttpRequest() instead
|
||||||
*/
|
*/
|
||||||
public function IsHandlingXmlHttpRequest(): bool
|
public function IsHandlingXmlHttpRequest(): bool
|
||||||
{
|
{
|
||||||
|
DeprecatedCallsLog::NotifyDeprecatedPhpMethod("Use \Symfony\Component\HttpFoundation\Request::isXmlHttpRequest() instead");
|
||||||
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
|
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -845,7 +845,7 @@ EOF
|
|||||||
);
|
);
|
||||||
$sVersionString = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
|
$sVersionString = Dict::Format('UI:iTopVersion:Short', ITOP_APPLICATION, ITOP_VERSION);
|
||||||
$oPage->add('<div id="about_box"><div class="ibo-about-box--top-part">');
|
$oPage->add('<div id="about_box"><div class="ibo-about-box--top-part">');
|
||||||
$oPage->add('<div><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="../images/logos/logo-combodo-dark.svg?t='.utils::GetCacheBusterTimestamp().'"/></a></div>');
|
$oPage->add('<div><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="' . utils::GetAbsoluteUrlAppRoot() . 'images/logos/logo-combodo-dark.svg?t='.utils::GetCacheBusterTimestamp().'"/></a></div>');
|
||||||
$oPage->add('<div>'.$sVersionString.'</div>');
|
$oPage->add('<div>'.$sVersionString.'</div>');
|
||||||
$oPage->add("</div>");
|
$oPage->add("</div>");
|
||||||
self::DisplayAboutLicenses($oPage);
|
self::DisplayAboutLicenses($oPage);
|
||||||
@@ -898,7 +898,7 @@ EOF
|
|||||||
if (file_exists(APPROOT.'extensions')) {
|
if (file_exists(APPROOT.'extensions')) {
|
||||||
$aSearchDirs[] = APPROOT.'extensions';
|
$aSearchDirs[] = APPROOT.'extensions';
|
||||||
}
|
}
|
||||||
$sExtraDir = APPROOT.'data/'.$sCurrEnv.'-modules/';
|
$sExtraDir = utils::GetDataPath().$sCurrEnv.'-modules/';
|
||||||
if (file_exists($sExtraDir)) {
|
if (file_exists($sExtraDir)) {
|
||||||
$aSearchDirs[] = $sExtraDir;
|
$aSearchDirs[] = $sExtraDir;
|
||||||
}
|
}
|
||||||
@@ -927,7 +927,7 @@ EOF
|
|||||||
// Display
|
// Display
|
||||||
//
|
//
|
||||||
$oPage->add('<div id="about_box"><div class="ibo-about-box--top-part">');
|
$oPage->add('<div id="about_box"><div class="ibo-about-box--top-part">');
|
||||||
$oPage->add('<div><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="../images/logos/logo-combodo-dark.svg?t='.utils::GetCacheBusterTimestamp().'"/></a></div>');
|
$oPage->add('<div><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="' . utils::GetAbsoluteUrlAppRoot() . 'images/logos/logo-combodo-dark.svg?t='.utils::GetCacheBusterTimestamp().'"/></a></div>');
|
||||||
$oPage->add('<div>'.$sVersionString.'<br/>'.'MySQL: '.$sMySQLVersion.'<br/>'.'PHP: '.$sPHPVersion.'<br/></div>');
|
$oPage->add('<div>'.$sVersionString.'<br/>'.'MySQL: '.$sMySQLVersion.'<br/>'.'PHP: '.$sPHPVersion.'<br/></div>');
|
||||||
$oPage->add("</div>");
|
$oPage->add("</div>");
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,12 @@ use Combodo\iTop\Application\WebPage\iTopWebPage;
|
|||||||
use Combodo\iTop\Application\WebPage\JsonPage;
|
use Combodo\iTop\Application\WebPage\JsonPage;
|
||||||
use MetaModel;
|
use MetaModel;
|
||||||
use SecurityException;
|
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 Combodo\iTop\Service\SummaryCard\SummaryCardService;
|
||||||
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
use UserRights;
|
use UserRights;
|
||||||
use utils;
|
use utils;
|
||||||
|
|
||||||
@@ -42,30 +47,47 @@ use utils;
|
|||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
* @package Combodo\iTop\Controller\Base\Layout
|
* @package Combodo\iTop\Controller\Base\Layout
|
||||||
*/
|
*/
|
||||||
|
#[Route("/object", name: "b_object_")]
|
||||||
class ObjectController extends AbstractController
|
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
|
* @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $oUrlGenerator
|
||||||
* @throws \MySQLHasGoneAwayException
|
* @since 3.2.0 N°6935
|
||||||
* @throws \MySQLException
|
|
||||||
* @throws \DictExceptionMissingString
|
|
||||||
* @throws \CoreUnexpectedValue
|
|
||||||
* @throws \ConfigException
|
|
||||||
* @throws \ApplicationException
|
|
||||||
* @throws \MissingQueryArgument
|
|
||||||
*/
|
*/
|
||||||
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';
|
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
||||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
|
||||||
$sStateCode = utils::ReadParam('state', '');
|
$sStateCode = utils::ReadParam('state', '');
|
||||||
$bCheckSubClass = utils::ReadParam('checkSubclass', true);
|
$bCheckSubClass = utils::ReadParam('checkSubclass', true);
|
||||||
|
|
||||||
|
// Check parameters
|
||||||
|
if (false === MetaModel::IsValidClass($sClass)) {
|
||||||
|
throw new HttpException(Response::HTTP_NOT_FOUND, Dict::S('UI:ObjectDoesNotExist'));
|
||||||
|
}
|
||||||
|
|
||||||
$oAppContext = new ApplicationContext();
|
$oAppContext = new ApplicationContext();
|
||||||
$oRouter = Router::GetInstance();
|
|
||||||
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
|
||||||
$oPage = new AjaxPage('');
|
$oPage = new AjaxPage('');
|
||||||
} else {
|
} else {
|
||||||
$oPage = new iTopWebPage('', $bPrintable);
|
$oPage = new iTopWebPage('', $bPrintable);
|
||||||
@@ -73,7 +95,6 @@ class ObjectController extends AbstractController
|
|||||||
$this->AddRequiredForModificationJsFilesToPage($oPage);
|
$this->AddRequiredForModificationJsFilesToPage($oPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (empty($sClass))
|
if (empty($sClass))
|
||||||
{
|
{
|
||||||
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'class'));
|
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'class'));
|
||||||
@@ -133,7 +154,7 @@ class ObjectController extends AbstractController
|
|||||||
// - Update flags with parameters set in URL
|
// - Update flags with parameters set in URL
|
||||||
FormHelper::UpdateFlagsFromContext($oObjToClone, $aFormExtraParams);
|
FormHelper::UpdateFlagsFromContext($oObjToClone, $aFormExtraParams);
|
||||||
|
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$aFormExtraParams['js_handlers'] = [];
|
$aFormExtraParams['js_handlers'] = [];
|
||||||
$aFormExtraParams['noRelations'] = true;
|
$aFormExtraParams['noRelations'] = true;
|
||||||
$aFormExtraParams['hide_transitions'] = true;
|
$aFormExtraParams['hide_transitions'] = true;
|
||||||
@@ -187,9 +208,9 @@ JS;
|
|||||||
|
|
||||||
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObjToClone, array(), $aFormExtraParams);
|
cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, $oObjToClone, array(), $aFormExtraParams);
|
||||||
} else {
|
} else {
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$oClassForm = cmdbAbstractObject::DisplayFormBlockSelectClassToCreate($sClass, MetaModel::GetName($sClass), $oAppContext, $aPossibleClasses, ['state' => $sStateCode]);
|
$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(
|
$oClassForm->SetOnSubmitJsCode(
|
||||||
<<<JS
|
<<<JS
|
||||||
let me = this;
|
let me = this;
|
||||||
@@ -208,25 +229,35 @@ JS
|
|||||||
cmdbAbstractObject::DisplaySelectClassToCreate($sClass, $oPage, $oAppContext, $aPossibleClasses,['state' => $sStateCode]);
|
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 \ApplicationException
|
||||||
* @throws \ArchivedObjectException
|
* @throws \ArchivedObjectException
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \SecurityException
|
* @throws \SecurityException
|
||||||
* @throws \Exception
|
* @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';
|
$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);
|
$sFormTitle = utils::ReadPostedParam('form_title', null, utils::ENUM_SANITIZATION_FILTER_STRING);
|
||||||
|
|
||||||
// Check parameters
|
// 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))
|
if (utils::IsNullOrEmptyString($sClass) || utils::IsNullOrEmptyString($sId))
|
||||||
{
|
{
|
||||||
throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'id'));
|
throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'id'));
|
||||||
@@ -254,7 +285,7 @@ JS
|
|||||||
$aFormExtraParams['form_title'] = $sFormTitle;
|
$aFormExtraParams['form_title'] = $sFormTitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$oPage = new AjaxPage('');
|
$oPage = new AjaxPage('');
|
||||||
$aFormExtraParams['js_handlers'] = [];
|
$aFormExtraParams['js_handlers'] = [];
|
||||||
$aFormExtraParams['noRelations'] = true;
|
$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
|
// 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
|
$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 \ApplicationException
|
||||||
* @throws \ArchivedObjectException
|
* @throws \ArchivedObjectException
|
||||||
* @throws \CoreException
|
* @throws \CoreException
|
||||||
* @throws \SecurityException
|
* @throws \SecurityException
|
||||||
*/
|
*/
|
||||||
public function OperationApplyNew()
|
#[Route('/apply_new', name: 'apply_new')]
|
||||||
|
public function OperationApplyNew(Request $oRequest): Response
|
||||||
{
|
{
|
||||||
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
||||||
$aResult = [];
|
$aResult = [];
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$oPage = new JsonPage();
|
$oPage = new JsonPage();
|
||||||
$oPage->SetOutputDataOnly(true);
|
$oPage->SetOutputDataOnly(true);
|
||||||
$aResult['success'] = false;
|
$aResult['success'] = false;
|
||||||
@@ -367,7 +402,7 @@ JS;
|
|||||||
$sUser = UserRights::GetUser();
|
$sUser = UserRights::GetUser();
|
||||||
IssueLog::Error(__CLASS__.'::'.__METHOD__." : invalid transaction_id ! data: user='$sUser', class='$sClass'");
|
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')];
|
$aResult['data'] = ['error_message' => Dict::S('UI:Error:ObjectAlreadyCreated')];
|
||||||
} else {
|
} else {
|
||||||
$oErrorAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:Error:ObjectAlreadyCreated'));
|
$oErrorAlert = AlertUIBlockFactory::MakeForFailure(Dict::S('UI:Error:ObjectAlreadyCreated'));
|
||||||
@@ -464,7 +499,7 @@ JS;
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Nothing more to do
|
// Nothing more to do
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$aResult['success'] = true;
|
$aResult['success'] = true;
|
||||||
$aResult['data'] = ['object' => ObjectRepository::ConvertObjectToArray($oObj, $sClass)];
|
$aResult['data'] = ['object' => ObjectRepository::ConvertObjectToArray($oObj, $sClass)];
|
||||||
} else {
|
} else {
|
||||||
@@ -476,7 +511,7 @@ JS;
|
|||||||
// Found issues, explain and give the user a second chance
|
// Found issues, explain and give the user a second chance
|
||||||
//
|
//
|
||||||
$aIssues = $e->getIssues();
|
$aIssues = $e->getIssues();
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$aResult['data'] = ['error_message' => $e->getHtmlMessage()];
|
$aResult['data'] = ['error_message' => $e->getHtmlMessage()];
|
||||||
} else {
|
} else {
|
||||||
$sClassLabel = MetaModel::GetName($sClass);
|
$sClassLabel = MetaModel::GetName($sClass);
|
||||||
@@ -494,15 +529,18 @@ JS;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$oPage->SetData($aResult);
|
$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 \ApplicationException
|
||||||
* @throws \ArchivedObjectException
|
* @throws \ArchivedObjectException
|
||||||
* @throws \ConfigException
|
* @throws \ConfigException
|
||||||
@@ -511,10 +549,12 @@ JS;
|
|||||||
* @throws \DictExceptionMissingString
|
* @throws \DictExceptionMissingString
|
||||||
* @throws \MySQLException
|
* @throws \MySQLException
|
||||||
*/
|
*/
|
||||||
public function OperationApplyModify(){
|
public function OperationApplyModify(Request $oRequest): Response
|
||||||
|
{
|
||||||
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
||||||
$aResult = [];
|
$aResult = [];
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
|
||||||
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$oPage = new JsonPage();
|
$oPage = new JsonPage();
|
||||||
$oPage->SetOutputDataOnly(true);
|
$oPage->SetOutputDataOnly(true);
|
||||||
$aResult['success'] = false;
|
$aResult['success'] = false;
|
||||||
@@ -546,7 +586,7 @@ JS;
|
|||||||
{
|
{
|
||||||
$bDisplayDetails = false;
|
$bDisplayDetails = false;
|
||||||
|
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$aResult['data'] = ['error_message' => Dict::S('UI:ObjectDoesNotExist')];
|
$aResult['data'] = ['error_message' => Dict::S('UI:ObjectDoesNotExist')];
|
||||||
} else {
|
} else {
|
||||||
$oPage->set_title(Dict::S('UI:ErrorPageTitle'));
|
$oPage->set_title(Dict::S('UI:ErrorPageTitle'));
|
||||||
@@ -572,7 +612,7 @@ JS;
|
|||||||
$sUser = UserRights::GetUser();
|
$sUser = UserRights::GetUser();
|
||||||
IssueLog::Error(__CLASS__.'::'.__METHOD__." : invalid transaction_id ! data: user='$sUser', class='$sClass'");
|
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')];
|
$aResult['data'] = ['error_message' => Dict::S('UI:Error:ObjectAlreadyUpdated')];
|
||||||
} else {
|
} else {
|
||||||
$oPage->set_title(Dict::Format('UI:ModificationPageTitle_Object_Class', $oObj->GetRawName(), $sClassLabel)); // Set title will take care of the encoding
|
$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 (!$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())];
|
$aResult['data'] = ['error_message' => Dict::Format('UI:Class_Object_NotUpdated', MetaModel::GetName(get_class($oObj)), $oObj->GetName())];
|
||||||
} else {
|
} else {
|
||||||
$oPage->set_title(Dict::Format('UI:ModificationPageTitle_Object_Class', $oObj->GetRawName(), $sClassLabel)); // Set title will take care of the encoding
|
$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());
|
$sMessage = Dict::Format('UI:Class_Object_Updated', MetaModel::GetName(get_class($oObj)), $oObj->GetName());
|
||||||
$sSeverity = 'ok';
|
$sSeverity = 'ok';
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$aResult['success'] = true;
|
$aResult['success'] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -656,7 +696,7 @@ JS;
|
|||||||
//
|
//
|
||||||
$bDisplayDetails = false;
|
$bDisplayDetails = false;
|
||||||
$aIssues = $e->getIssues();
|
$aIssues = $e->getIssues();
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$aResult['data'] = ['error_message' => $e->getHtmlMessage()];
|
$aResult['data'] = ['error_message' => $e->getHtmlMessage()];
|
||||||
} else {
|
} else {
|
||||||
$oPage->AddHeaderMessage($e->getHtmlMessage(), 'message_error');
|
$oPage->AddHeaderMessage($e->getHtmlMessage(), 'message_error');
|
||||||
@@ -667,7 +707,7 @@ JS;
|
|||||||
}
|
}
|
||||||
catch (DeleteException $e)
|
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())];
|
$aResult['data'] = ['error_message' => Dict::Format('UI:Class_Object_NotUpdated', MetaModel::GetName(get_class($oObj)), $oObj->GetName())];
|
||||||
} else {
|
} else {
|
||||||
// Say two things:
|
// Say two things:
|
||||||
@@ -706,7 +746,7 @@ JS;
|
|||||||
// Nothing more to do
|
// Nothing more to do
|
||||||
$sMessage = isset($sMessage) ? $sMessage : '';
|
$sMessage = isset($sMessage) ? $sMessage : '';
|
||||||
$sSeverity = isset($sSeverity) ? $sSeverity : null;
|
$sSeverity = isset($sSeverity) ? $sSeverity : null;
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
;
|
;
|
||||||
} else {
|
} else {
|
||||||
ReloadAndDisplay($oPage, $oObj, 'update', $sMessage, $sSeverity);
|
ReloadAndDisplay($oPage, $oObj, 'update', $sMessage, $sSeverity);
|
||||||
@@ -724,27 +764,38 @@ JS;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->IsHandlingXmlHttpRequest()) {
|
if ($oRequest->isXmlHttpRequest()) {
|
||||||
$oPage->SetData($aResult);
|
$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('');
|
$oPage = new AjaxPage('');
|
||||||
|
|
||||||
$sClass = utils::ReadParam('obj_class', '', false, utils::ENUM_SANITIZATION_FILTER_CLASS);
|
// Check parameters
|
||||||
$sObjectKey = utils::ReadParam('obj_key', 0, false);
|
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
|
// - Check if we are allowed to see/make summary for this class
|
||||||
if(SummaryCardService::IsAllowedForClass($sClass)){
|
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
|
else
|
||||||
{
|
{
|
||||||
$oObj = MetaModel::GetObjectByName($sClass, $sObjectKey, false /* MustBeFound */);
|
$oObj = MetaModel::GetObjectByName($sClass, $sId, false /* MustBeFound */);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($oObj !== null) {
|
if($oObj !== null) {
|
||||||
@@ -758,7 +809,7 @@ JS;
|
|||||||
->SetIsClosable(false)
|
->SetIsClosable(false)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return $oPage;
|
return $oPage->GenerateResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -771,7 +822,7 @@ JS;
|
|||||||
protected function AddRequiredForModificationJsFilesToPage(iTopWebPage &$oPage): void
|
protected function AddRequiredForModificationJsFilesToPage(iTopWebPage &$oPage): void
|
||||||
{
|
{
|
||||||
foreach (static::EnumRequiredForModificationJsFilesRelPaths() as $sJsFileRelPath) {
|
foreach (static::EnumRequiredForModificationJsFilesRelPaths() as $sJsFileRelPath) {
|
||||||
$oPage->add_linked_script("../$sJsFileRelPath");
|
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . "$sJsFileRelPath");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,13 @@
|
|||||||
|
|
||||||
namespace Combodo\iTop\Controller;
|
namespace Combodo\iTop\Controller;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
* @package Combodo\iTop\Controller
|
* @package Combodo\iTop\Controller
|
||||||
|
*
|
||||||
|
* @deprecated 3.2.0 N°6935 As we now use Symfony controller and routing components, extend \Combodo\iTop\Controller\AbstractController instead
|
||||||
*/
|
*/
|
||||||
interface iController
|
interface iController
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,17 +6,42 @@
|
|||||||
|
|
||||||
namespace Combodo\iTop\Service\Router\Exception;
|
namespace Combodo\iTop\Service\Router\Exception;
|
||||||
|
|
||||||
|
use DeprecatedCallsLog;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class RouteNotFoundException
|
* Class RouteNotFoundException
|
||||||
*
|
*
|
||||||
* Means that a said route (eg. "object.modify") could not be found
|
* Means that a said route (eg. "object.modify") could not be found
|
||||||
*
|
*
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @deprecated 3.2.0 N°6935 As we now use Symfony routing component, use the corresponding exceptions instead
|
||||||
|
*
|
||||||
|
* Note that we can't call \DeprecatedCallsLog::NotifyDeprecatedFile() at the beginning at the file instead.
|
||||||
|
* Because
|
||||||
|
* - As the class is part of the autoloader it will be read when something calls \utils::GetClassesForInterface() which will pop the deprecation message (and break redirection)
|
||||||
|
* - Not all controllers using Combodo\iTop\Service\Router\Router service can be migrated yet for backward compatibility with extensions reasons
|
||||||
|
*
|
||||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||||
* @package Combodo\iTop\Service\Router\Exception
|
* @package Combodo\iTop\Service\Router\Exception
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
* @internal
|
|
||||||
*/
|
*/
|
||||||
class RouteNotFoundException extends RouterException
|
class RouteNotFoundException extends RouterException
|
||||||
{
|
{
|
||||||
|
public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @deprecated 3.2.0 N°6935
|
||||||
|
*
|
||||||
|
* Note that we can't call \DeprecatedCallsLog::NotifyDeprecatedFile() at the beginning at the file instead.
|
||||||
|
* Because
|
||||||
|
* - As the class is part of the autoloader it will be read when something calls \utils::GetClassesForInterface() which will pop the deprecation message (and break redirection)
|
||||||
|
* - Not all controllers using Combodo\iTop\Service\Router\Router service can be migrated yet for backward compatibility with extensions reasons
|
||||||
|
*/
|
||||||
|
DeprecatedCallsLog::NotifyDeprecatedFile("As we now use Symfony routing component, use the corresponding exceptions instead");
|
||||||
|
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,19 +6,42 @@
|
|||||||
|
|
||||||
namespace Combodo\iTop\Service\Router\Exception;
|
namespace Combodo\iTop\Service\Router\Exception;
|
||||||
|
|
||||||
|
use DeprecatedCallsLog;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class RouterException
|
* Class RouterException
|
||||||
*
|
*
|
||||||
* Base router exception class in case we need to catch all kind of router exceptions (see derived exceptions)
|
* Base router exception class in case we need to catch all kind of router exceptions (see derived exceptions)
|
||||||
*
|
*
|
||||||
|
* @internal
|
||||||
|
*
|
||||||
|
* @deprecated 3.2.0 N°6935 As we now use Symfony routing component, use the corresponding exceptions instead
|
||||||
|
*
|
||||||
|
* Note that we can't call \DeprecatedCallsLog::NotifyDeprecatedFile() at the beginning at the file instead.
|
||||||
|
* Because
|
||||||
|
* - As the class is part of the autoloader it will be read when something calls \utils::GetClassesForInterface() which will pop the deprecation message (and break redirection)
|
||||||
|
* - Not all controllers using Combodo\iTop\Service\Router\Router service can be migrated yet for backward compatibility with extensions reasons
|
||||||
|
*
|
||||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||||
* @package Combodo\iTop\Service\Router\Exception
|
* @package Combodo\iTop\Service\Router\Exception
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
* @internal
|
|
||||||
*/
|
*/
|
||||||
class RouterException extends Exception
|
class RouterException extends Exception
|
||||||
{
|
{
|
||||||
|
public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @deprecated 3.2.0 N°6935
|
||||||
|
*
|
||||||
|
* Note that we can't call \DeprecatedCallsLog::NotifyDeprecatedFile() at the beginning at the file instead.
|
||||||
|
* Because
|
||||||
|
* - As the class is part of the autoloader it will be read when something calls \utils::GetClassesForInterface() which will pop the deprecation message (and break redirection)
|
||||||
|
* - Not all controllers using Combodo\iTop\Service\Router\Router service can be migrated yet for backward compatibility with extensions reasons
|
||||||
|
*/
|
||||||
|
DeprecatedCallsLog::NotifyDeprecatedFile("As we now use Symfony routing component, use the corresponding exceptions instead");
|
||||||
|
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,20 +7,29 @@
|
|||||||
namespace Combodo\iTop\Service\Router;
|
namespace Combodo\iTop\Service\Router;
|
||||||
|
|
||||||
use Combodo\iTop\Service\Router\Exception\RouteNotFoundException;
|
use Combodo\iTop\Service\Router\Exception\RouteNotFoundException;
|
||||||
|
use DeprecatedCallsLog;
|
||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
use ReflectionMethod;
|
use ReflectionMethod;
|
||||||
use utils;
|
use utils;
|
||||||
use SetupUtils;
|
use SetupUtils;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Router
|
* Class Router
|
||||||
*
|
*
|
||||||
* Service to find the corresponding controller / method for a given "route" parameter.
|
* Service to find the corresponding controller / method for a given "route" parameter.
|
||||||
*
|
*
|
||||||
|
* @deprecated 3.2.0 N°6935 As we now use Symfony routing component, use the corresponding service instead
|
||||||
|
*
|
||||||
|
* Note that we can't call \DeprecatedCallsLog::NotifyDeprecatedFile() at the beginning at the file instead.
|
||||||
|
* Because
|
||||||
|
* - As the class is part of the autoloader it will be read when something calls \utils::GetClassesForInterface() which will pop the deprecation message (and break redirection)
|
||||||
|
* - Not all controllers using Combodo\iTop\Service\Router\Router service can be migrated yet for backward compatibility with extensions reasons
|
||||||
|
*
|
||||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||||
* @package Combodo\iTop\Service\Router
|
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
* @api
|
*
|
||||||
|
* @package Combodo\iTop\Service\Router
|
||||||
*/
|
*/
|
||||||
class Router
|
class Router
|
||||||
{
|
{
|
||||||
@@ -123,6 +132,9 @@ class Router
|
|||||||
*/
|
*/
|
||||||
public function DispatchRoute(string $sRoute)
|
public function DispatchRoute(string $sRoute)
|
||||||
{
|
{
|
||||||
|
/** @deprecated 3.2.0 N°6935 */
|
||||||
|
DeprecatedCallsLog::NotifyDeprecatedFile("As we now use Symfony routing component, use the corresponding service instead");
|
||||||
|
|
||||||
$aMethodSpecs = $this->GetDispatchSpecsForRoute($sRoute);
|
$aMethodSpecs = $this->GetDispatchSpecsForRoute($sRoute);
|
||||||
$mResponse = call_user_func_array([new $aMethodSpecs[0](), $aMethodSpecs[1]], []);
|
$mResponse = call_user_func_array([new $aMethodSpecs[0](), $aMethodSpecs[1]], []);
|
||||||
|
|
||||||
@@ -175,8 +187,15 @@ class Router
|
|||||||
// If no cache, force to re-scan for routes
|
// If no cache, force to re-scan for routes
|
||||||
if (count($aRoutes) === 0) {
|
if (count($aRoutes) === 0) {
|
||||||
foreach (utils::GetClassesForInterface('Combodo\iTop\Controller\iController', '', ['[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]']) as $sControllerFQCN) {
|
foreach (utils::GetClassesForInterface('Combodo\iTop\Controller\iController', '', ['[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]']) as $sControllerFQCN) {
|
||||||
$sRouteNamespace = $sControllerFQCN::ROUTE_NAMESPACE;
|
|
||||||
// Ignore controller with no namespace
|
// Ignore controller with no namespace
|
||||||
|
// - No ROUTE_NAMESPACE constant
|
||||||
|
// This case could be for controller extending Combodo\iTop\Controller\AbstractController which is still implementing Combodo\iTop\Controller\iController for compatibility reasons
|
||||||
|
// but have already been migrated to Symfony router (when migrated, constant must be removed from the controller so it doesn't use the compatibility router)
|
||||||
|
if (false === defined("$sControllerFQCN::ROUTE_NAMESPACE")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$sRouteNamespace = $sControllerFQCN::ROUTE_NAMESPACE;
|
||||||
|
// - Namespace is empty
|
||||||
if (is_null($sRouteNamespace)) {
|
if (is_null($sRouteNamespace)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ namespace Combodo\iTop\Service\SummaryCard;
|
|||||||
|
|
||||||
use appUserPreferences;
|
use appUserPreferences;
|
||||||
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
use Combodo\iTop\Core\MetaModel\FriendlyNameType;
|
||||||
use Combodo\iTop\Service\Router\Router;
|
|
||||||
use MetaModel;
|
use MetaModel;
|
||||||
|
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||||
use UserRights;
|
use UserRights;
|
||||||
|
use utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class SummaryCardService
|
* Class SummaryCardService
|
||||||
@@ -19,10 +20,22 @@ use UserRights;
|
|||||||
*
|
*
|
||||||
* @since 3.1.0
|
* @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
|
* @param $sObjKey
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
@@ -30,9 +43,9 @@ class SummaryCardService {
|
|||||||
*/
|
*/
|
||||||
public static function GetHyperlinkMarkup(string $sObjClass, $sObjKey): string
|
public static function GetHyperlinkMarkup(string $sObjClass, $sObjKey): string
|
||||||
{
|
{
|
||||||
$oRouter = Router::GetInstance();
|
// 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 = $oRouter->GenerateUrl("object.summary", ["obj_class" => $sObjClass, "obj_key" => $sObjKey]);
|
$sRoute = utils::GetAbsoluteUrlAppRoot() . "app.php/object/summary/$sObjClass/$sObjKey";
|
||||||
return
|
return
|
||||||
<<<HTML
|
<<<HTML
|
||||||
data-tooltip-content="$sRoute"
|
data-tooltip-content="$sRoute"
|
||||||
data-tooltip-interaction-enabled="true"
|
data-tooltip-interaction-enabled="true"
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
{% apply spaceless %}
|
{% apply spaceless %}
|
||||||
<div style="height:250px;width:100%" class="dashboard_chart" id="my_chart_{{ oUIBlock.sChartId }}{{ oUIBlock.iChartCounter }}">
|
<div style="height:250px;width:100%" class="dashboard_chart" id="my_chart_{{ oUIBlock.sChartId }}{{ oUIBlock.iChartCounter }}">
|
||||||
<div style="height:200px;line-height:200px;vertical-align:center;text-align:center;width:100%">
|
<div style="height:200px;line-height:200px;vertical-align:center;text-align:center;width:100%">
|
||||||
<img src="../images/indicator.gif">
|
<img src="{{ get_absolute_url_app_root() }}images/indicator.gif">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endapply %}
|
{% endapply %}
|
||||||
@@ -22,7 +22,7 @@ use Combodo\iTop\Application\WebPage\WebPage;
|
|||||||
|
|
||||||
function LogResult($sString)
|
function LogResult($sString)
|
||||||
{
|
{
|
||||||
file_put_contents(APPROOT.'data/queries.results.log', "\n".$sString, FILE_APPEND);
|
file_put_contents(utils::GetDataPath().'queries.results.log', "\n".$sString, FILE_APPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
function LogBenchmarkCSV()
|
function LogBenchmarkCSV()
|
||||||
@@ -40,7 +40,7 @@ function LogBenchmarkCSV()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$sLine = implode(';', $aValues); // the preferred for MS Excel
|
$sLine = implode(';', $aValues); // the preferred for MS Excel
|
||||||
file_put_contents(APPROOT.'data/queries.benchmark.csv', "\n".$sLine, FILE_APPEND);
|
file_put_contents(utils::GetDataPath().'queries.benchmark.csv', "\n".$sLine, FILE_APPEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
class QueryLogEntry
|
class QueryLogEntry
|
||||||
@@ -311,8 +311,8 @@ case 'check':
|
|||||||
case 'benchmark':
|
case 'benchmark':
|
||||||
$oP->add("<h2>Create data/queries.xxx reports</h2>\n");
|
$oP->add("<h2>Create data/queries.xxx reports</h2>\n");
|
||||||
// Reset the log contents
|
// Reset the log contents
|
||||||
file_put_contents(APPROOT.'data/queries.results.log', date('Y-m-d H:i:s')."\n");
|
file_put_contents(utils::GetDataPath().'queries.results.log', date('Y-m-d H:i:s')."\n");
|
||||||
file_put_contents(APPROOT.'data/queries.benchmark.csv', '');
|
file_put_contents(utils::GetDataPath().'queries.benchmark.csv', '');
|
||||||
LogBenchmarkCSV('type', 'properties', 'make duration', 'class', 'tables', 'query length', 'exec duration', 'rows', 'oql');
|
LogBenchmarkCSV('type', 'properties', 'make duration', 'class', 'tables', 'query length', 'exec duration', 'rows', 'oql');
|
||||||
|
|
||||||
$iErrors = 0;
|
$iErrors = 0;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class TestsRunStartHook implements BeforeFirstTestHook, AfterLastTestHook
|
|||||||
{
|
{
|
||||||
// Note: This can't be put in the cache-<ENV> folder as we have multiple <ENV> running across the test cases
|
// Note: This can't be put in the cache-<ENV> folder as we have multiple <ENV> running across the test cases
|
||||||
// We also don't want to put it in the unit tests folder as it is not supposed to be writable
|
// We also don't want to put it in the unit tests folder as it is not supposed to be writable
|
||||||
return APPROOT.'data/.php-unit-tests-run-started';
|
return utils::GetDataPath().'.php-unit-tests-run-started';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user