mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-18 23:08:46 +02:00
N°5655 - Refactor object modification logic to a dedicated controller for both page / modal modes
This commit is contained in:
@@ -1838,7 +1838,7 @@ class MenuBlock extends DisplayBlock
|
||||
if ($bIsModifyAllowed) {
|
||||
$aRegularActions['UI:Menu:Modify'] = array(
|
||||
'label' => Dict::S('UI:Menu:Modify'),
|
||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=modify&class=$sClass&id=$id{$sContext}#",
|
||||
'url' => "{$sRootUrl}pages/$sUIPage?operation=object.modify&class=$sClass&id=$id{$sContext}#",
|
||||
) + $aActionParams;
|
||||
}
|
||||
if ($bIsCreationAllowed) {
|
||||
|
||||
@@ -349,6 +349,7 @@ return array(
|
||||
'Combodo\\iTop\\Controller\\AbstractController' => $baseDir . '/sources/Controller/AbstractController.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\\ObjectController' => $baseDir . '/sources/Controller/Base/Layout/ObjectController.php',
|
||||
'Combodo\\iTop\\Controller\\OAuth\\OAuthLandingController' => $baseDir . '/sources/Controller/OAuth/OAuthLandingController.php',
|
||||
'Combodo\\iTop\\Controller\\PreferencesController' => $baseDir . '/sources/Controller/PreferencesController.php',
|
||||
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\IOAuthClientProvider' => $baseDir . '/sources/Core/Authentication/Client/OAuth/IOAuthClientProvider.php',
|
||||
|
||||
@@ -714,6 +714,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Controller\\AbstractController' => __DIR__ . '/../..' . '/sources/Controller/AbstractController.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\\ObjectController' => __DIR__ . '/../..' . '/sources/Controller/Base/Layout/ObjectController.php',
|
||||
'Combodo\\iTop\\Controller\\OAuth\\OAuthLandingController' => __DIR__ . '/../..' . '/sources/Controller/OAuth/OAuthLandingController.php',
|
||||
'Combodo\\iTop\\Controller\\PreferencesController' => __DIR__ . '/../..' . '/sources/Controller/PreferencesController.php',
|
||||
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\IOAuthClientProvider' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/OAuth/IOAuthClientProvider.php',
|
||||
|
||||
44
pages/UI.php
44
pages/UI.php
@@ -19,6 +19,7 @@ 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\UIContentBlock;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
|
||||
use Combodo\iTop\Controller\Base\Layout\ObjectController;
|
||||
|
||||
/**
|
||||
* Displays a popup welcome message, once per session at maximum
|
||||
@@ -301,7 +302,7 @@ require_once(APPROOT.'/application/startup.inc.php');
|
||||
|
||||
try
|
||||
{
|
||||
$operation = utils::ReadParam('operation', '');
|
||||
$operation = utils::ReadParam('operation', '', false, utils::ENUM_SANITIZATION_FILTER_OPERATION);
|
||||
$bPrintable = (utils::ReadParam('printable', 0) == '1');
|
||||
|
||||
$oKPI = new ExecutionKPI();
|
||||
@@ -321,22 +322,16 @@ try
|
||||
switch($operation)
|
||||
{
|
||||
case 'new': // Form to create a new object
|
||||
case 'modify': // Form to modify an object
|
||||
case 'apply_new': // Creation of a new object
|
||||
case 'apply_modify': // Applying the modifications to an existing object
|
||||
case 'form_for_modify_all': // Form to modify multiple objects (bulk modify)
|
||||
case 'bulk_stimulus': // For to apply a stimulus to multiple objects
|
||||
case 'stimulus': // Form displayed when applying a stimulus (state change)
|
||||
case 'apply_stimulus': // Form displayed when applying a stimulus (state change)
|
||||
$oP->add_linked_script("../js/json.js");
|
||||
$oP->add_linked_script("../js/forms-json-utils.js");
|
||||
$oP->add_linked_script("../js/wizardhelper.js");
|
||||
$oP->add_linked_script("../js/wizard.utils.js");
|
||||
$oP->add_linked_script("../js/linkswidget.js");
|
||||
$oP->add_linked_script("../js/linksdirectwidget.js");
|
||||
$oP->add_linked_script("../js/extkeywidget.js");
|
||||
$oP->add_linked_script("../js/jquery.blockUI.js");
|
||||
break;
|
||||
foreach (ObjectController::EnumRequiredForModificationJsFilesRelPaths() as $sJsFileRelPath) {
|
||||
$oP->add_linked_script("../$sJsFileRelPath");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
switch($operation)
|
||||
@@ -659,29 +654,10 @@ EOF
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
case 'modify': // Form to modify an object
|
||||
$oP->DisableBreadCrumb();
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$id = utils::ReadParam('id', '');
|
||||
if (empty($sClass) || empty($id)) // TO DO: check that the class name is valid !
|
||||
{
|
||||
throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'id'));
|
||||
}
|
||||
// Check if the user can modify this object
|
||||
$oObj = MetaModel::GetObject($sClass, $id, false /* MustBeFound */);
|
||||
if (is_null($oObj)) {
|
||||
$oP->set_title(Dict::S('UI:ErrorPageTitle'));
|
||||
$oP->P(Dict::S('UI:ObjectDoesNotExist'));
|
||||
} else {
|
||||
// The object could be read - check if it is allowed to modify it
|
||||
$oSet = CMDBObjectSet::FromObject($oObj);
|
||||
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_NO) {
|
||||
throw new SecurityException('User not allowed to modify this object', array('class' => $sClass, 'id' => $id));
|
||||
}
|
||||
$oP->SetContentLayout(PageContentFactory::MakeForObjectDetails($oObj, cmdbAbstractObject::ENUM_DISPLAY_MODE_EDIT));
|
||||
// Note: code duplicated to the case 'apply_modify' when a data integrity issue has been found
|
||||
$oObj->DisplayModifyForm($oP, array('wizard_container' => 1)); // wizard_container: Display the title above the form
|
||||
}
|
||||
case 'modify': // Legacy operation
|
||||
case 'object.modify': // New operation
|
||||
$oController = new ObjectController();
|
||||
$oP = $oController->Modify();
|
||||
break;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -11,6 +11,7 @@ use Combodo\iTop\Application\UI\Base\Component\Html\Html;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
|
||||
use Combodo\iTop\Controller\AjaxRenderController;
|
||||
use Combodo\iTop\Controller\Base\Layout\ActivityPanelController;
|
||||
use Combodo\iTop\Controller\Base\Layout\ObjectController;
|
||||
use Combodo\iTop\Controller\PreferencesController;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleFormRenderer;
|
||||
@@ -2668,6 +2669,14 @@ EOF
|
||||
$oAjaxRenderController->GetMenusCount($oPage);
|
||||
break;
|
||||
|
||||
//--------------------------------
|
||||
// Object
|
||||
//--------------------------------
|
||||
case 'object.modify':
|
||||
$oController = new ObjectController();
|
||||
$oPage = $oController->Modify();
|
||||
break;
|
||||
|
||||
default:
|
||||
$oPage->p("Invalid query.");
|
||||
}
|
||||
|
||||
@@ -529,9 +529,9 @@ JS
|
||||
*/
|
||||
public function SetContentLayout(PageContent $oLayout)
|
||||
{
|
||||
$oPrevContentLayout=$this->oContentLayout;
|
||||
$oPrevContentLayout = $this->oContentLayout;
|
||||
$this->oContentLayout = $oLayout;
|
||||
foreach ($oPrevContentLayout->GetSubBlocks() as $oBlock){
|
||||
foreach ($oPrevContentLayout->GetSubBlocks() as $oBlock) {
|
||||
$this->AddUiBlock($oBlock);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,5 +17,16 @@ namespace Combodo\iTop\Controller;
|
||||
*/
|
||||
class AbstractController
|
||||
{
|
||||
// Empty stub for now, factorized needs might come later
|
||||
/**
|
||||
* It works if your JavaScript library sets an X-Requested-With HTTP header.
|
||||
* It is known to work with common JavaScript frameworks: {@link https://wikipedia.org/wiki/List_of_Ajax_frameworks#JavaScript}
|
||||
*
|
||||
* @see \Symfony\Component\HttpFoundation\Request::isXmlHttpRequest() Inspired by
|
||||
*
|
||||
* @return bool True if the current request is an XmlHttpRequest (eg. an AJAX request)
|
||||
*/
|
||||
public function IsHandlingXmlHttpRequest(): bool
|
||||
{
|
||||
return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && ($_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
|
||||
}
|
||||
}
|
||||
107
sources/Controller/Base/Layout/ObjectController.php
Normal file
107
sources/Controller/Base/Layout/ObjectController.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2022 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Controller\Base\Layout;
|
||||
|
||||
use AjaxPage;
|
||||
use ApplicationException;
|
||||
use cmdbAbstractObject;
|
||||
use CMDBObjectSet;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
|
||||
use Dict;
|
||||
use iTopWebPage;
|
||||
use MetaModel;
|
||||
use SecurityException;
|
||||
use utils;
|
||||
use UserRights;
|
||||
use WebPage;
|
||||
|
||||
/**
|
||||
* Class ObjectController
|
||||
*
|
||||
* @internal
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @since 3.1.0
|
||||
* @package Combodo\iTop\Controller\Base\Layout
|
||||
*/
|
||||
class ObjectController extends \Combodo\iTop\Controller\AbstractController
|
||||
{
|
||||
public function View()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \iTopWebPage|\AjaxPage Object edit form in its webpage
|
||||
* @throws \ApplicationException
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \SecurityException
|
||||
*/
|
||||
public function Modify()
|
||||
{
|
||||
$bPrintable = utils::ReadParam('printable', '0') === '1';
|
||||
$sClass = utils::ReadParam('class', '', false, 'class');
|
||||
$sId = utils::ReadParam('id', '');
|
||||
|
||||
$sClass = 'Person';
|
||||
$sId = 6;
|
||||
|
||||
// Check parameters
|
||||
if (utils::IsNullOrEmptyString($sClass) || utils::IsNullOrEmptyString($sId))
|
||||
{
|
||||
throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'id'));
|
||||
}
|
||||
|
||||
$oObj = MetaModel::GetObject($sClass, $sId, false);
|
||||
// Check user permissions
|
||||
// - Is allowed to view it?
|
||||
if (is_null($oObj)) {
|
||||
throw new ApplicationException(Dict::S('UI:ObjectDoesNotExist'));
|
||||
}
|
||||
|
||||
// - Is allowed to edit it?
|
||||
$oSet = CMDBObjectSet::FromObject($oObj);
|
||||
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_NO) {
|
||||
throw new SecurityException('User not allowed to modify this object', array('class' => $sClass, 'id' => $sId));
|
||||
}
|
||||
|
||||
// Prepare web page (should more likely be some kind of response object like for Symfony)
|
||||
if ($this->IsHandlingXmlHttpRequest()) {
|
||||
$oPage = new AjaxPage('');
|
||||
} else {
|
||||
$oPage = new iTopWebPage('', $bPrintable);
|
||||
$oPage->DisableBreadCrumb();
|
||||
$oPage->SetContentLayout(PageContentFactory::MakeForObjectDetails($oObj, cmdbAbstractObject::ENUM_DISPLAY_MODE_EDIT));
|
||||
}
|
||||
// - JS files
|
||||
foreach (static::EnumRequiredForModificationJsFilesRelPaths() as $sJsFileRelPath) {
|
||||
$oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot().$sJsFileRelPath);
|
||||
}
|
||||
|
||||
// Note: Code duplicated to the case 'apply_modify' in UI.php when a data integrity issue has been found
|
||||
$oObj->DisplayModifyForm($oPage, array('wizard_container' => 1)); // wizard_container: Display the title above the form
|
||||
|
||||
return $oPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Rel. paths (to iTop root folder) of required JS files for object modification (create, edit, stimulus, ...)
|
||||
*/
|
||||
public static function EnumRequiredForModificationJsFilesRelPaths(): array
|
||||
{
|
||||
return [
|
||||
'js/json.js',
|
||||
'js/forms-json-utils.js',
|
||||
'js/wizardhelper.js',
|
||||
'js/wizard.utils.js',
|
||||
'js/linkswidget.js',
|
||||
'js/linksdirectwidget.js',
|
||||
'js/extkeywidget.js',
|
||||
'js/jquery.blockUI.js',
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user