mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
N°1192 Introduce navigation_rules in the end-users portal
This commit is contained in:
@@ -121,6 +121,9 @@ services:
|
||||
context_manipulator:
|
||||
alias: Combodo\iTop\Portal\Helper\ContextManipulatorHelper
|
||||
public: true
|
||||
navigation_rule_helper:
|
||||
alias: Combodo\iTop\Portal\Helper\NavigationRuleHelper
|
||||
public: true
|
||||
lifecycle_validator:
|
||||
alias: Combodo\iTop\Portal\Helper\LifecycleValidatorHelper
|
||||
public: true
|
||||
|
||||
@@ -26,21 +26,35 @@ $(function()
|
||||
$.widget( 'itop.portal_form_handler', $.itop.form_handler,
|
||||
{
|
||||
options: {
|
||||
submit_url: null,
|
||||
cancel_url: null
|
||||
submit_url: null, // Deprecated. We kept those properties to preserve compatibility with extensions
|
||||
cancel_url: null, // but you should start using xxx_rule.url as soon as possible.
|
||||
submit_rule: {
|
||||
category: 'redirect',
|
||||
url: null,
|
||||
modal: false,
|
||||
},
|
||||
cancel_rule: {
|
||||
category: 'close',
|
||||
url: null,
|
||||
modal: false,
|
||||
},
|
||||
},
|
||||
|
||||
// the constructor
|
||||
_create: function()
|
||||
{
|
||||
this.element
|
||||
.addClass('portal_form_handler');
|
||||
this.element.addClass('portal_form_handler');
|
||||
|
||||
// Safe check for options
|
||||
if(this.options.submit_url === "")
|
||||
this.options.submit_url = null;
|
||||
if(this.options.cancel_url === "")
|
||||
this.options.cancel_url = null;
|
||||
if(this.options.submit_rule.url === '')
|
||||
this.options.submit_rule.url = null;
|
||||
if(this.options.cancel_rule.url === '')
|
||||
this.options.cancel_rule.url = null;
|
||||
// Deprecated, see this.options.submit_url
|
||||
if((this.options.submit_url !== null) && (this.options.submit_url !== ''))
|
||||
this.options.submit_rule.url = this.options.submit_url;
|
||||
if((this.options.cancel_url !== null) && (this.options.cancel_url !== ''))
|
||||
this.options.cancel_rule.url = this.options.cancel_url;
|
||||
|
||||
this._super();
|
||||
},
|
||||
@@ -160,69 +174,34 @@ $(function()
|
||||
// If everything is okay, we close the form and reload it.
|
||||
if(oValidation.valid)
|
||||
{
|
||||
var bRedirectInModal = me.options.submit_rule.modal;
|
||||
var sRedirectUrl = me.options.submit_rule.url;
|
||||
|
||||
$('body').trigger('unregister_blocker.portal.itop', {'sBlockerId': me.element.attr('id')});
|
||||
|
||||
if(me.options.is_modal)
|
||||
{
|
||||
me.element.closest('.modal').modal('hide');
|
||||
}
|
||||
|
||||
// Checking if we have to redirect to another page
|
||||
// Typically this happens when applying a stimulus, we redirect to transition form
|
||||
if(oValidation.redirection !== undefined)
|
||||
{
|
||||
var oRedirection = oValidation.redirection;
|
||||
var bRedirectionAjax = (oRedirection.ajax !== undefined) ? oRedirection.ajax : false;
|
||||
var sUrl = null;
|
||||
|
||||
// URL priority order :
|
||||
// redirection.url > me.option.submit_url > redirection.alternative_url
|
||||
if(oRedirection.modal !== undefined)
|
||||
{
|
||||
bRedirectInModal = oRedirection.modal;
|
||||
}
|
||||
if(oRedirection.url !== undefined)
|
||||
{
|
||||
sUrl = oRedirection.url;
|
||||
}
|
||||
else if(me.options.submit_url !== null)
|
||||
{
|
||||
sUrl = me.options.submit_url;
|
||||
}
|
||||
else if(oRedirection.alternative_url !== undefined)
|
||||
{
|
||||
sUrl = oRedirection.alternative_url;
|
||||
}
|
||||
|
||||
if(sUrl !== null)
|
||||
{
|
||||
if(bRedirectionAjax)
|
||||
{
|
||||
// Creating a new modal
|
||||
CombodoPortalToolbox.OpenModal({
|
||||
content: {
|
||||
endpoint: sUrl,
|
||||
data: {
|
||||
// Passing form manager data to the next page, just in case it needs it (eg. when applying stimulus)
|
||||
formmanager_class: me.options.formmanager_class,
|
||||
formmanager_data: JSON.stringify(me.options.formmanager_data)
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Showing loader while redirecting, otherwise user tend to click somewhere in the page.
|
||||
// Note : We use a timeout because .always() is called right after here and will hide the loader
|
||||
setTimeout(function(){ me._disableFormBeforeLoading(); }, 50);
|
||||
// Redirecting after a few ms so the user can see what happend
|
||||
setTimeout(function() { location.href = sUrl; }, 400);
|
||||
}
|
||||
sRedirectUrl = oRedirection.url;
|
||||
}
|
||||
me._applyRedirectRule(sRedirectUrl, bRedirectInModal);
|
||||
}
|
||||
else if(me.options.submit_url !== null)
|
||||
else if(me.options.submit_rule.category === 'redirect')
|
||||
{
|
||||
// Showing loader while redirecting, otherwise user tend to click somewhere in the page.
|
||||
// Note : We use a timeout because .always() is called right after here and will hide the loader
|
||||
setTimeout(function(){ me._disableFormBeforeLoading(); }, 50);
|
||||
// Redirecting after a few ms so the user can see what happend
|
||||
setTimeout(function() { location.href = me.options.submit_url; }, 400);
|
||||
me._applyRedirectRule(sRedirectUrl, bRedirectInModal);
|
||||
}
|
||||
// Close rule only needs to be applied to non modal forms (modal is always closed on submit)
|
||||
else if(me.options.submit_rule.category === 'close')
|
||||
{
|
||||
me._applyCloseRule();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -269,38 +248,31 @@ $(function()
|
||||
},
|
||||
function(oData)
|
||||
{
|
||||
if(me.options.cancel_url !== null)
|
||||
if(me.options.cancel_rule.category === 'redirect')
|
||||
{
|
||||
location.href = me.options.cancel_url;
|
||||
me._applyRedirectRule(me.options.cancel_rule.url, me.options.cancel_rule.modal);
|
||||
}
|
||||
else if(me.options.cancel_rule.category === 'close')
|
||||
{
|
||||
me._applyCloseRule();
|
||||
}
|
||||
}
|
||||
)
|
||||
.always(function(){
|
||||
// Close the modal only if fields had to be cancelled
|
||||
if(me.options.is_modal)
|
||||
{
|
||||
me.element.closest('.modal').modal('hide');
|
||||
}
|
||||
.always(function()
|
||||
{
|
||||
me._enableFormAfterLoading();
|
||||
});
|
||||
}
|
||||
// Otherwise we can close the modal immediately
|
||||
else
|
||||
{
|
||||
if(me.options.cancel_url !== null)
|
||||
if(me.options.cancel_rule.category === 'redirect')
|
||||
{
|
||||
location.href = me.options.cancel_url;
|
||||
me._applyRedirectRule(me.options.cancel_rule.url, me.options.cancel_rule.modal);
|
||||
}
|
||||
else
|
||||
else if(me.options.cancel_rule.category === 'close')
|
||||
{
|
||||
if(me.options.is_modal)
|
||||
{
|
||||
me.element.closest('.modal').modal('hide');
|
||||
}
|
||||
else
|
||||
{
|
||||
location.reload();
|
||||
}
|
||||
me._applyCloseRule();
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -343,6 +315,53 @@ $(function()
|
||||
{
|
||||
$('#page_overlay').fadeOut(200);
|
||||
},
|
||||
_applyRedirectRule: function(sRedirectUrl, bRedirectInModal)
|
||||
{
|
||||
var me = this;
|
||||
|
||||
// Always close current modal
|
||||
if(this.options.is_modal)
|
||||
{
|
||||
this.element.closest('.modal').modal('hide');
|
||||
}
|
||||
|
||||
if(sRedirectUrl !== null)
|
||||
{
|
||||
if(bRedirectInModal === true)
|
||||
{
|
||||
// Creating a new modal
|
||||
CombodoPortalToolbox.OpenModal({
|
||||
content: {
|
||||
endpoint: sRedirectUrl,
|
||||
data: {
|
||||
// Passing form manager data to the next page, just in case it needs it (eg. when applying stimulus)
|
||||
formmanager_class: this.options.formmanager_class,
|
||||
formmanager_data: JSON.stringify(this.options.formmanager_data)
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Showing loader while redirecting, otherwise user tend to click somewhere in the page.
|
||||
// Note: We use a timeout because .always() is called right after here and will hide the loader
|
||||
setTimeout(function(){ me._disableFormBeforeLoading(); }, 50);
|
||||
// Redirecting after a few ms so the user can see what happend
|
||||
setTimeout(function() { location.href = sRedirectUrl; }, 400);
|
||||
}
|
||||
}
|
||||
},
|
||||
_applyCloseRule: function()
|
||||
{
|
||||
if(this.options.is_modal)
|
||||
{
|
||||
this.element.closest('.modal').modal('hide');
|
||||
}
|
||||
else
|
||||
{
|
||||
window.close();
|
||||
}
|
||||
},
|
||||
submit: function(oEvent)
|
||||
{
|
||||
this._onSubmitClick(oEvent);
|
||||
|
||||
@@ -15,12 +15,11 @@
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Portal\DependencyInjection\SilexCompatBootstrap\PortalXmlConfiguration;
|
||||
|
||||
use Combodo\iTop\Portal\Helper\NavigationRuleHelper;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use DOMFormatException;
|
||||
use Exception;
|
||||
@@ -66,7 +65,19 @@ class Forms extends AbstractConfiguration
|
||||
$aFormProperties = array(
|
||||
'display_mode' => ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE,
|
||||
'always_show_submit' => ApplicationHelper::FORM_DEFAULT_ALWAYS_SHOW_SUBMIT,
|
||||
'navigation_rules' => array(
|
||||
'submit' => array(
|
||||
NavigationRuleHelper::ENUM_ORIGIN_PAGE => null,
|
||||
NavigationRuleHelper::ENUM_ORIGIN_MODAL => null,
|
||||
),
|
||||
'cancel' => array(
|
||||
NavigationRuleHelper::ENUM_ORIGIN_PAGE => null,
|
||||
NavigationRuleHelper::ENUM_ORIGIN_MODAL => null,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$aAllowedNavRulesButtonCodes = array_keys($aFormProperties['navigation_rules']);
|
||||
if ($oFormNode->GetOptionalElement('properties') !== null)
|
||||
{
|
||||
/** @var \MFElement $oPropertyNode */
|
||||
@@ -77,9 +88,48 @@ class Forms extends AbstractConfiguration
|
||||
case 'display_mode':
|
||||
$aFormProperties['display_mode'] = $oPropertyNode->GetText(ApplicationHelper::FORM_DEFAULT_DISPLAY_MODE);
|
||||
break;
|
||||
|
||||
case 'always_show_submit':
|
||||
$aFormProperties['always_show_submit'] = ($oPropertyNode->GetText('false') === 'true') ? true : false;
|
||||
break;
|
||||
|
||||
case 'navigation_rules':
|
||||
/** @var \MFElement $oNavRuleButtonNode */
|
||||
foreach($oPropertyNode->childNodes as $oNavRuleButtonNode)
|
||||
{
|
||||
$sNavRuleButtonCode = $oNavRuleButtonNode->nodeName;
|
||||
if(!in_array($sNavRuleButtonCode, $aAllowedNavRulesButtonCodes))
|
||||
{
|
||||
throw new DOMFormatException('navigation_rules tag must only contain '.implode('|', $aAllowedNavRulesButtonCodes).' tags, "'.$sNavRuleButtonCode.'" given.', null, null, $oPropertyNode);
|
||||
}
|
||||
|
||||
/** @var \MFElement $oNavRuleOriginNode */
|
||||
foreach($oNavRuleButtonNode->childNodes as $oNavRuleOriginNode)
|
||||
{
|
||||
$sNavRuleOrigin = $oNavRuleOriginNode->nodeName;
|
||||
if(!in_array($sNavRuleOrigin, NavigationRuleHelper::GetAllowedOrigins()))
|
||||
{
|
||||
throw new DOMFormatException($sNavRuleButtonCode. ' tag must only contain '.implode('|', NavigationRuleHelper::GetAllowedOrigins()).' tags, "'.$sNavRuleOrigin.'" given.', null, null, $oPropertyNode);
|
||||
}
|
||||
|
||||
$sNavRuleId = $oNavRuleOriginNode->GetText();
|
||||
// Note: We don't check is rule exists as it would introduce a dependency to the NavigationRuleHelper service.
|
||||
// Maybe we will consider it later.
|
||||
if(empty($sNavRuleId))
|
||||
{
|
||||
throw new DOMFormatException($sNavRuleButtonCode.' tag cannot be empty.', null, null, $oPropertyNode);
|
||||
}
|
||||
|
||||
$aFormProperties['navigation_rules'][$sNavRuleButtonCode][$sNavRuleOrigin] = $sNavRuleId;
|
||||
}
|
||||
|
||||
// Set modal rule as the same as default is not present.
|
||||
// We preset it so we don't have to make checks elsewhere in the code when using it.
|
||||
if(empty($aFormProperties['navigation_rules'][$sNavRuleButtonCode][NavigationRuleHelper::ENUM_ORIGIN_MODAL]))
|
||||
{
|
||||
$aFormProperties['navigation_rules'][$sNavRuleButtonCode][NavigationRuleHelper::ENUM_ORIGIN_MODAL] = $aFormProperties['navigation_rules'][$sNavRuleButtonCode][NavigationRuleHelper::ENUM_ORIGIN_PAGE];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -98,7 +148,7 @@ class Forms extends AbstractConfiguration
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new DOMFormatException('Mode tag must have an id attribute', null, null,
|
||||
throw new DOMFormatException('mode tag must have an id attribute', null, null,
|
||||
$oFormNode);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Portal\Helper;
|
||||
@@ -374,6 +372,10 @@ class ApplicationHelper
|
||||
'properties' => array(
|
||||
'display_mode' => static::FORM_DEFAULT_DISPLAY_MODE,
|
||||
'always_show_submit' => static::FORM_DEFAULT_ALWAYS_SHOW_SUBMIT,
|
||||
'navigation_rules' => array(
|
||||
'submit' => null,
|
||||
'cancel' => null,
|
||||
),
|
||||
),
|
||||
'fields' => array(),
|
||||
'layout' => array(
|
||||
|
||||
@@ -0,0 +1,638 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2013-2019 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\Portal\Helper;
|
||||
|
||||
use Combodo\iTop\DesignElement;
|
||||
use Combodo\iTop\Portal\Brick\BrickCollection;
|
||||
use Combodo\iTop\Portal\Brick\ManageBrick;
|
||||
use DBObject;
|
||||
use DBObjectSet;
|
||||
use DBSearch;
|
||||
use DOMFormatException;
|
||||
use DOMNodeList;
|
||||
use Exception;
|
||||
use ModuleDesign;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Class NavigationRuleHelper ⛵
|
||||
*
|
||||
* @author Guillaume Lajarige <guillaume.lajarige@combodo.com>
|
||||
* @since 2.7.0
|
||||
* @package Combodo\iTop\Portal\Helper
|
||||
*/
|
||||
class NavigationRuleHelper
|
||||
{
|
||||
// Available point of origin for the navigation
|
||||
const ENUM_ORIGIN_PAGE = 'default';
|
||||
const ENUM_ORIGIN_MODAL = 'modal';
|
||||
|
||||
// Available rule categories (of rule types)
|
||||
/** @var string ENUM_RULE_CAT_CLOSE (eg. close modal/window) */
|
||||
const ENUM_RULE_CAT_CLOSE = 'close';
|
||||
/** @var string ENUM_RULE_CAT_REDIRECT (eg. go-to-homepage, go-to-object, go-to-brick, ...) */
|
||||
const ENUM_RULE_CAT_REDIRECT = 'redirect';
|
||||
|
||||
// Available rule types
|
||||
/** @var string ENUM_RULE_CLOSE */
|
||||
const ENUM_RULE_CLOSE = 'close';
|
||||
/** @var string ENUM_RULE_GO_TO_HOMEPAGE */
|
||||
const ENUM_RULE_GO_TO_HOMEPAGE = 'go-to-homepage';
|
||||
/** @var string ENUM_RULE_GO_TO_OBJECT */
|
||||
const ENUM_RULE_GO_TO_OBJECT = 'go-to-object';
|
||||
/** @var string ENUM_RULE_GO_TO_BRICK */
|
||||
const ENUM_RULE_GO_TO_BRICK = 'go-to-brick';
|
||||
/** @var string ENUM_RULE_GO_TO_MANAGE_BRICK */
|
||||
const ENUM_RULE_GO_TO_MANAGE_BRICK = 'go-to-manage-brick';
|
||||
/** @var string ENUM_RULE_GO_TO_BROWSE_BRICK */
|
||||
const ENUM_RULE_GO_TO_BROWSE_BRICK = 'go-to-browse-brick';
|
||||
// - Defaults
|
||||
/** @var string DEFAULT_RULE_SUBMIT_PAGE */
|
||||
const DEFAULT_RULE_SUBMIT_PAGE = self::ENUM_RULE_GO_TO_OBJECT;
|
||||
/** @var string DEFAULT_RULE_SUBMIT_MODAL */
|
||||
const DEFAULT_RULE_SUBMIT_MODAL = self::DEFAULT_RULE_SUBMIT_PAGE;
|
||||
/** @var string DEFAULT_RULE_CANCEL_PAGE */
|
||||
const DEFAULT_RULE_CANCEL_PAGE = self::ENUM_RULE_CLOSE;
|
||||
/** @var string DEFAULT_RULE_CANCEL_MODAL */
|
||||
const DEFAULT_RULE_CANCEL_MODAL = self::DEFAULT_RULE_CANCEL_PAGE;
|
||||
|
||||
// Rule go-to-object properties
|
||||
/** @var string DEFAULT_RULE_GO_TO_OBJECT_PROP_MODE */
|
||||
const DEFAULT_RULE_GO_TO_OBJECT_PROP_MODE = ObjectFormHandlerHelper::ENUM_MODE_VIEW;
|
||||
|
||||
/** @var string ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL */
|
||||
const ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL = 'modal';
|
||||
/** @var string ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_PAGE */
|
||||
const ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_PAGE = 'page';
|
||||
/** @var string ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_CURRENT */
|
||||
const ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_CURRENT = 'current';
|
||||
/** @var string DEFAULT_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET */
|
||||
const DEFAULT_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET = self::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL;
|
||||
|
||||
// Rule go-to-brick properties
|
||||
// TODO
|
||||
|
||||
/** @var array $aRules */
|
||||
protected $aRules;
|
||||
/** @var \Symfony\Component\Routing\RouterInterface */
|
||||
private $oRouter;
|
||||
/** @var \Combodo\iTop\Portal\Brick\BrickCollection */
|
||||
private $oBrickCollection;
|
||||
/** @var \Combodo\iTop\Portal\Helper\ScopeValidatorHelper */
|
||||
private $oScopeValidator;
|
||||
|
||||
/**
|
||||
* NavigationRuleHelper constructor.
|
||||
*
|
||||
* @param \ModuleDesign $oModuleDesign
|
||||
* @param \Symfony\Component\Routing\RouterInterface $oRouter
|
||||
* @param \Combodo\iTop\Portal\Brick\BrickCollection $oBrickCollection
|
||||
* @param \Combodo\iTop\Portal\Helper\ScopeValidatorHelper $oScopeValidator
|
||||
*
|
||||
* @throws \DOMFormatException
|
||||
*/
|
||||
public function __construct(
|
||||
ModuleDesign $oModuleDesign, RouterInterface $oRouter, BrickCollection $oBrickCollection, ScopeValidatorHelper $oScopeValidator
|
||||
) {
|
||||
$this->aRules = array();
|
||||
$this->oRouter = $oRouter;
|
||||
$this->oBrickCollection = $oBrickCollection;
|
||||
|
||||
$this->Init($oModuleDesign->GetNodes('/module_design/navigation_rules/navigation_rule'));
|
||||
$this->oScopeValidator = $oScopeValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the NavigationRuleHelper by caching rules in memory.
|
||||
*
|
||||
* @param \DOMNodeList $oNodes
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \DOMFormatException
|
||||
*/
|
||||
public function Init(DOMNodeList $oNodes)
|
||||
{
|
||||
$this->aRules = array();
|
||||
|
||||
// Iterating over the navigation_rule nodes
|
||||
/** @var \Combodo\iTop\DesignElement $oRuleNode */
|
||||
foreach ($oNodes as $oRuleNode)
|
||||
{
|
||||
// Checking node name
|
||||
if ($oRuleNode->nodeName !== 'navigation_rule')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Retrieving mandatory attributes
|
||||
// - ID
|
||||
$sRuleId = $oRuleNode->getAttribute('id');
|
||||
if ($sRuleId === '')
|
||||
{
|
||||
throw new DOMFormatException('Rule tag must have an id attribute.', null, null, $oRuleNode);
|
||||
}
|
||||
// - Type
|
||||
$sRuleType = $oRuleNode->getAttribute('xsi:type');
|
||||
if (($sRuleType === '') || !in_array($sRuleType, static::GetAllowedTypes()))
|
||||
{
|
||||
throw new DOMFormatException('Navigation rule tag must have a valid xsi:type, "'.$sRuleType.'" given, expected '.implode('|',
|
||||
static::GetAllowedTypes()), null, null, $oRuleNode);
|
||||
}
|
||||
|
||||
// Load rule from XML
|
||||
$sRuleLoadingFunction = 'Load'.utils::ToCamelCase($sRuleType).'RuleFromXML';
|
||||
$this->aRules[$sRuleId] = $this->$sRuleLoadingFunction($oRuleNode);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// Enumeration helpers
|
||||
//--------------------
|
||||
|
||||
/**
|
||||
* Return an array of the allowed point of origin for the navigation
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function GetAllowedOrigins()
|
||||
{
|
||||
return array(
|
||||
static::ENUM_ORIGIN_PAGE,
|
||||
static::ENUM_ORIGIN_MODAL,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of allowed navigation rule types (those in <navigation_rule xsi:type"XXX" />)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function GetAllowedTypes()
|
||||
{
|
||||
return array(
|
||||
static::ENUM_RULE_CLOSE,
|
||||
static::ENUM_RULE_GO_TO_HOMEPAGE,
|
||||
static::ENUM_RULE_GO_TO_OBJECT,
|
||||
static::ENUM_RULE_GO_TO_BRICK,
|
||||
static::ENUM_RULE_GO_TO_BROWSE_BRICK,
|
||||
static::ENUM_RULE_GO_TO_MANAGE_BRICK,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the definition of the rule identified by its ID, as a hash array
|
||||
*
|
||||
* @param string $sId
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function GetRuleDefinition($sId)
|
||||
{
|
||||
if (!array_key_exists($sId, $this->aRules))
|
||||
{
|
||||
throw new Exception('NavigationRuleHelper: Could not find "'.$sId.'" in the rules list');
|
||||
}
|
||||
|
||||
return $this->aRules[$sId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash array of ID => rule definition
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetRulesDefinitions()
|
||||
{
|
||||
return $this->aRules;
|
||||
}
|
||||
|
||||
//-------------------------
|
||||
// Default rules definition
|
||||
//-------------------------
|
||||
|
||||
/**
|
||||
* Return the default definition of the "Close" rule
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetDefaultCloseRuleDefinition()
|
||||
{
|
||||
return array(
|
||||
'category' => static::ENUM_RULE_CAT_CLOSE,
|
||||
'type' => static::ENUM_RULE_CLOSE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default definition of the "Go to homepage" rule
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetDefaultGoToHomepageRuleDefinition()
|
||||
{
|
||||
return array(
|
||||
'category' => static::ENUM_RULE_CAT_REDIRECT,
|
||||
'type' => static::ENUM_RULE_GO_TO_HOMEPAGE,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default definition of the "Go to object" rule
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetDefaultGoToObjectRuleDefinition()
|
||||
{
|
||||
return array(
|
||||
'category' => static::ENUM_RULE_CAT_REDIRECT,
|
||||
'type' => static::ENUM_RULE_GO_TO_OBJECT,
|
||||
'properties' => array(
|
||||
'mode' => static::DEFAULT_RULE_GO_TO_OBJECT_PROP_MODE,
|
||||
'opening_target' => static::DEFAULT_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET,
|
||||
'oql' => null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default definition of the "Go to brick" rule
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetDefaultGoToBrickRuleDefinition()
|
||||
{
|
||||
return array(
|
||||
'category' => static::ENUM_RULE_CAT_REDIRECT,
|
||||
'type' => static::ENUM_RULE_GO_TO_BRICK,
|
||||
'properties' => array(
|
||||
'route' => array(
|
||||
'id' => null,
|
||||
'params' => array(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
//----------------------------
|
||||
// Rules definition XML loader
|
||||
//----------------------------
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnused Called dynamically by static::Init()
|
||||
*
|
||||
* @param \Combodo\iTop\DesignElement $oRuleNode
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function LoadCloseRuleFromXML(DesignElement $oRuleNode)
|
||||
{
|
||||
// No special configuration needed
|
||||
return $this->GetDefaultCloseRuleDefinition();
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnused Called dynamically by static::Init()
|
||||
*
|
||||
* @param \Combodo\iTop\DesignElement $oRuleNode
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function LoadGoToHomepageRuleFromXML(DesignElement $oRuleNode)
|
||||
{
|
||||
// No special configuration needed
|
||||
return $this->GetDefaultGoToHomepageRuleDefinition();
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnused Called dynamically by static::Init()
|
||||
*
|
||||
* @param \Combodo\iTop\DesignElement $oRuleNode
|
||||
*
|
||||
* @return array
|
||||
* @throws \DOMFormatException
|
||||
*/
|
||||
protected function LoadGoToObjectRuleFromXML(DesignElement $oRuleNode)
|
||||
{
|
||||
$sRuleId = $oRuleNode->getAttribute('id');
|
||||
// Default values
|
||||
$aRule = $this->GetDefaultGoToObjectRuleDefinition();
|
||||
|
||||
$aAllowedOpeningTarget = array(
|
||||
static::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_CURRENT,
|
||||
static::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL,
|
||||
static::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_PAGE,
|
||||
);
|
||||
|
||||
/** @var \Combodo\iTop\DesignElement $oPropNode */
|
||||
foreach($oRuleNode->childNodes as $oPropNode)
|
||||
{
|
||||
switch($oPropNode->nodeName)
|
||||
{
|
||||
case 'mode':
|
||||
$sMode = $oPropNode->GetText();
|
||||
if(!in_array($sMode, ObjectFormHandlerHelper::GetAllowedModes()))
|
||||
{
|
||||
throw new DOMFormatException('mode tag of navigation_rule "'.$sRuleId.'" must be valid. Expected '.implode('|', ObjectFormHandlerHelper::GetAllowedModes()).', "'.$sMode.'" given.', null, null, $oRuleNode);
|
||||
}
|
||||
$aRule['properties']['mode'] = $sMode;
|
||||
break;
|
||||
|
||||
case 'opening_target':
|
||||
$sOpeningTarget = $oPropNode->GetText();
|
||||
if(!in_array($sOpeningTarget, $aAllowedOpeningTarget))
|
||||
{
|
||||
throw new DOMFormatException('opening_target tag of navigation_rule "'.$sRuleId.'" must be valid. Expected '.implode('|', $aAllowedOpeningTarget).', "'.$sOpeningTarget.'" given.', null, null, $oRuleNode);
|
||||
}
|
||||
$aRule['properties']['opening_target'] = $sOpeningTarget;
|
||||
break;
|
||||
|
||||
case 'oql':
|
||||
$sOQL = $oPropNode->GetText();
|
||||
if(empty($sOQL))
|
||||
{
|
||||
throw new DOMFormatException('oql tag of navigation_rule "'.$sRuleId.'" can not be empty.');
|
||||
}
|
||||
$aRule['properties']['oql'] = $sOQL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $aRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnused Called dynamically by static::Init()
|
||||
*
|
||||
* @param \Combodo\iTop\DesignElement $oRuleNode
|
||||
*
|
||||
* @return array
|
||||
* @throws \DOMFormatException
|
||||
*/
|
||||
protected function LoadGoToBrickRuleFromXML(DesignElement $oRuleNode)
|
||||
{
|
||||
$sRuleId = $oRuleNode->getAttribute('id');
|
||||
// Default values
|
||||
$aRule = $this->GetDefaultGoToBrickRuleDefinition();
|
||||
|
||||
/** @var \Combodo\iTop\DesignElement $oPropNode */
|
||||
foreach($oRuleNode->childNodes as $oPropNode)
|
||||
{
|
||||
switch($oPropNode->nodeName)
|
||||
{
|
||||
case 'route':
|
||||
/** @var array $aRouteProperties Route ID and parameters */
|
||||
$aRouteProperties = array();
|
||||
/** @var DesignElement $oRoutePropNode */
|
||||
foreach($oPropNode->childNodes as $oRoutePropNode)
|
||||
{
|
||||
switch($oRoutePropNode->nodeName)
|
||||
{
|
||||
case 'id':
|
||||
$aRouteProperties['id'] = $oRoutePropNode->GetText();
|
||||
break;
|
||||
|
||||
case 'params':
|
||||
/** @var DesignElement $oRouteParamNode */
|
||||
foreach($oRoutePropNode->childNodes as $oRouteParamNode)
|
||||
{
|
||||
$sRouteParamId = $oRouteParamNode->getAttribute('id');
|
||||
$sRouteParamValue = $oRouteParamNode->GetText();
|
||||
if(empty($sRouteParamId) || empty($sRouteParamValue))
|
||||
{
|
||||
throw new DOMFormatException('param tag of navigation_rule "'.$sRuleId.'" must have a valid ID and value.', null, null, $oRuleNode);
|
||||
}
|
||||
|
||||
$aRouteProperties['params'][$sRouteParamId] = $sRouteParamValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Consistency check
|
||||
if(empty($aRouteProperties['id']))
|
||||
{
|
||||
throw new DOMFormatException('navigation_rule "'.$sRuleId.'" must have a valid ID', null, null, $oRuleNode);
|
||||
}
|
||||
|
||||
$aRule['properties']['route'] = $aRouteProperties;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $aRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnused Called dynamically by static::Init()
|
||||
*
|
||||
* Load definition of a "go-to-manage-brick" rule from XML.
|
||||
* This is a shortcut to a classic "go-to-brick" rule.
|
||||
*
|
||||
* @param \Combodo\iTop\DesignElement $oRuleNode
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function LoadGoToManageBrickRuleFromXML(DesignElement $oRuleNode)
|
||||
{
|
||||
$sRuleId = $oRuleNode->getAttribute('id');
|
||||
// Default values
|
||||
$aRule = $this->GetDefaultGoToBrickRuleDefinition();
|
||||
$aRule['properties']['route']['id'] = 'p_manage_brick_display_as';
|
||||
|
||||
// Rule parameters to automatically map to the route parameters
|
||||
$aParamsMapping = array(
|
||||
'id' => 'sBrickId',
|
||||
'display_mode' => 'sDisplayMode',
|
||||
'grouping_tab' => 'sGroupingTab',
|
||||
'filter' => 'sSearchValue',
|
||||
);
|
||||
|
||||
/** @var \Combodo\iTop\DesignElement $oPropNode */
|
||||
foreach($oRuleNode->childNodes as $oPropNode)
|
||||
{
|
||||
$sRouteParamId = (array_key_exists($oPropNode->nodeName, $aParamsMapping)) ? $aParamsMapping[$oPropNode->nodeName] : $oPropNode->nodeName;
|
||||
$aRule['properties']['route']['params'][$sRouteParamId] = $oPropNode->GetText();
|
||||
}
|
||||
|
||||
return $aRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnused Called dynamically by static::Init()
|
||||
*
|
||||
* Load definition of a "go-to-browse-brick" rule from XML.
|
||||
* This is a shortcut to a classic "go-to-brick" rule.
|
||||
*
|
||||
* @param \Combodo\iTop\DesignElement $oRuleNode
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function LoadGoToBrowseBrickRuleFromXML(DesignElement $oRuleNode)
|
||||
{
|
||||
$sRuleId = $oRuleNode->getAttribute('id');
|
||||
// Default values
|
||||
$aRule = $this->GetDefaultGoToBrickRuleDefinition();
|
||||
$aRule['properties']['route']['id'] = 'p_browse_brick_mode';
|
||||
|
||||
// Rule parameters to automatically map to the route parameters
|
||||
$aParamsMapping = array(
|
||||
'id' => 'sBrickId',
|
||||
'browse_mode' => 'sBrowseMode',
|
||||
'filter' => 'sSearchValue',
|
||||
);
|
||||
|
||||
/** @var \Combodo\iTop\DesignElement $oPropNode */
|
||||
foreach($oRuleNode->childNodes as $oPropNode)
|
||||
{
|
||||
$sRouteParamId = (array_key_exists($oPropNode->nodeName, $aParamsMapping)) ? $aParamsMapping[$oPropNode->nodeName] : $oPropNode->nodeName;
|
||||
$aRule['properties']['route']['params'][$sRouteParamId] = $oPropNode->GetText();
|
||||
}
|
||||
|
||||
return $aRule;
|
||||
}
|
||||
|
||||
//------------------------
|
||||
// Business logic function
|
||||
//------------------------
|
||||
|
||||
/**
|
||||
* Returns a hash array containing the target URL and if it should be opened in a modal for each type of callbacks (submit and cancel)
|
||||
*
|
||||
* eg :
|
||||
* array(
|
||||
* 'submit' => array(
|
||||
* 'type' => 'redirect',
|
||||
* 'url' => 'http://localhost/',
|
||||
* 'modal' => false,
|
||||
* 'cancel' => array(
|
||||
* 'type' => 'close',
|
||||
* 'url' => null,
|
||||
* 'modal' => false,
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* @param array $aFormProperties
|
||||
* @param \DBObject $oCurrentObject
|
||||
* @param boolean $bIsCurrentFormInModal
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function PrepareRulesForForm(array $aFormProperties, DBObject $oCurrentObject, $bIsCurrentFormInModal = false)
|
||||
{
|
||||
// Default values
|
||||
$aResults = array(
|
||||
'submit' => array(
|
||||
'category' => static::ENUM_RULE_CAT_REDIRECT,
|
||||
'url' => null,
|
||||
'modal' => false,
|
||||
),
|
||||
'cancel' => array(
|
||||
'category' => static::ENUM_RULE_CAT_CLOSE,
|
||||
'url' => null,
|
||||
'modal' => false,
|
||||
),
|
||||
);
|
||||
|
||||
// Get form's navigation rules
|
||||
$aFormNavRules = (isset($aFormProperties['properties'])) ? $aFormProperties['properties']['navigation_rules'] : array('submit' => null, 'cancel' => null);
|
||||
|
||||
// Check from which origin the rule will be called
|
||||
$sRuleCallOrigin = ($bIsCurrentFormInModal) ? 'modal' : 'default';
|
||||
|
||||
foreach(array_keys($aResults) as $sButtonCode)
|
||||
{
|
||||
// Retrieve rule definition
|
||||
// - Default behavior when no rule specified
|
||||
if(empty($aFormNavRules[$sButtonCode][$sRuleCallOrigin]))
|
||||
{
|
||||
switch($sButtonCode)
|
||||
{
|
||||
case 'submit':
|
||||
$aRuleDef = $this->GetDefaultGoToObjectRuleDefinition();
|
||||
break;
|
||||
|
||||
case 'cancel':
|
||||
$aRuleDef = $this->GetDefaultCloseRuleDefinition();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// - Specified rule
|
||||
else
|
||||
{
|
||||
$sRuleId = $aFormNavRules[$sButtonCode][$sRuleCallOrigin];
|
||||
$aRuleDef = $this->GetRuleDefinition($sRuleId);
|
||||
}
|
||||
|
||||
// Set category
|
||||
$aResults[$sButtonCode]['category'] = $aRuleDef['category'];
|
||||
|
||||
// Set properties regarding the type
|
||||
switch($aRuleDef['type'])
|
||||
{
|
||||
case static::ENUM_RULE_GO_TO_HOMEPAGE:
|
||||
$aResults[$sButtonCode]['url'] = $this->oRouter->generate('p_home');
|
||||
break;
|
||||
|
||||
case static::ENUM_RULE_GO_TO_OBJECT:
|
||||
// Target opening mode to modal if specified or should be as current form
|
||||
if( ($aRuleDef['properties']['opening_target'] === static::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_MODAL)
|
||||
|| (($aRuleDef['properties']['opening_target'] === static::ENUM_RULE_GO_TO_OBJECT_PROP_OPENING_TARGET_CURRENT) && ($bIsCurrentFormInModal === true))
|
||||
)
|
||||
{
|
||||
$aResults[$sButtonCode]['modal'] = true;
|
||||
}
|
||||
|
||||
// Target URL
|
||||
// - Find object
|
||||
if(empty($aRuleDef['properties']['oql']))
|
||||
{
|
||||
$oTargetObject = $oCurrentObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
$oSearch = DBSearch::FromOQL($aRuleDef['properties']['oql']);
|
||||
$oSet = new DBObjectSet($oSearch, array(), array('this' => $oCurrentObject));
|
||||
$oSet->OptimizeColumnLoad(array());
|
||||
$oTargetObject = $oSet->Fetch();
|
||||
}
|
||||
// - Build URL
|
||||
$aResults[$sButtonCode]['url'] = $this->oRouter->generate('p_object_'.$aRuleDef['properties']['mode'], array('sObjectClass' => get_class($oTargetObject), 'sObjectId' => $oTargetObject->GetKey()));
|
||||
break;
|
||||
|
||||
case static::ENUM_RULE_GO_TO_BRICK:
|
||||
// Build URL
|
||||
$aRouteProperties = $aRuleDef['properties']['route'];
|
||||
$aResults[$sButtonCode]['url'] = $this->oRouter->generate($aRouteProperties['id'], $aRouteProperties['params']);
|
||||
break;
|
||||
|
||||
case static::ENUM_RULE_CLOSE:
|
||||
default:
|
||||
// Don't set the URL
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $aResults;
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,6 @@
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -63,6 +61,8 @@ class ObjectFormHandlerHelper
|
||||
private $oRequestManipulator;
|
||||
/** @var \Combodo\iTop\Portal\Helper\ContextManipulatorHelper */
|
||||
private $oContextManipulator;
|
||||
/** @var \Combodo\iTop\Portal\Helper\NavigationRuleHelper */
|
||||
private $oNavigationRuleHelper;
|
||||
/** @var \Combodo\iTop\Portal\Helper\ScopeValidatorHelper */
|
||||
private $oScopeValidator;
|
||||
/** @var \Combodo\iTop\Portal\Helper\SecurityHelper */
|
||||
@@ -81,20 +81,22 @@ class ObjectFormHandlerHelper
|
||||
/**
|
||||
* ObjectFormHandlerHelper constructor.
|
||||
*
|
||||
* @param \Combodo\iTop\Portal\Helper\RequestManipulatorHelper $oRequestManipulator
|
||||
* @param \Combodo\iTop\Portal\Helper\ContextManipulatorHelper $oContextManipulator
|
||||
* @param \Combodo\iTop\Portal\Helper\ScopeValidatorHelper $oScopeValidator
|
||||
* @param \Combodo\iTop\Portal\Helper\SecurityHelper $oSecurityHelper
|
||||
* @param \Combodo\iTop\Portal\Helper\RequestManipulatorHelper $oRequestManipulator
|
||||
* @param \Combodo\iTop\Portal\Helper\ContextManipulatorHelper $oContextManipulator
|
||||
* @param \Combodo\iTop\Portal\Helper\NavigationRuleHelper $oNavigationRuleHelper
|
||||
* @param \Combodo\iTop\Portal\Helper\ScopeValidatorHelper $oScopeValidator
|
||||
* @param \Combodo\iTop\Portal\Helper\SecurityHelper $oSecurityHelper
|
||||
* @param \Symfony\Component\Routing\Generator\UrlGeneratorInterface $oUrlGenerator
|
||||
* @param array $aCombodoPortalInstanceConf
|
||||
* @param string $sPortalId
|
||||
* @param \Combodo\iTop\Portal\Twig\AppExtension $oAppExtension
|
||||
* @param \Symfony\Component\DependencyInjection\ContainerInterface $oContainer
|
||||
* @param array $aCombodoPortalInstanceConf
|
||||
* @param string $sPortalId
|
||||
* @param \Combodo\iTop\Portal\Twig\AppExtension $oAppExtension
|
||||
* @param \Symfony\Component\DependencyInjection\ContainerInterface $oContainer
|
||||
*/
|
||||
public function __construct(RequestManipulatorHelper $oRequestManipulator, ContextManipulatorHelper $oContextManipulator, ScopeValidatorHelper $oScopeValidator, SecurityHelper $oSecurityHelper, UrlGeneratorInterface $oUrlGenerator, $aCombodoPortalInstanceConf, $sPortalId, AppExtension $oAppExtension, ContainerInterface $oContainer)
|
||||
public function __construct(RequestManipulatorHelper $oRequestManipulator, ContextManipulatorHelper $oContextManipulator, NavigationRuleHelper $oNavigationRuleHelper, ScopeValidatorHelper $oScopeValidator, SecurityHelper $oSecurityHelper, UrlGeneratorInterface $oUrlGenerator, $aCombodoPortalInstanceConf, $sPortalId, AppExtension $oAppExtension, ContainerInterface $oContainer)
|
||||
{
|
||||
$this->oRequestManipulator = $oRequestManipulator;
|
||||
$this->oContextManipulator = $oContextManipulator;
|
||||
$this->oNavigationRuleHelper = $oNavigationRuleHelper;
|
||||
$this->oScopeValidator = $oScopeValidator;
|
||||
$this->oSecurityHelper = $oSecurityHelper;
|
||||
$this->oUrlGenerator = $oUrlGenerator;
|
||||
@@ -222,10 +224,13 @@ class ObjectFormHandlerHelper
|
||||
$oObject->PrefillForm('state_change', $aPrefillFormParam);
|
||||
}
|
||||
|
||||
// Preparing callback urls
|
||||
$aCallbackUrls = $this->oContextManipulator->GetCallbackUrls($aActionRules, $oObject, $bModal);
|
||||
$aFormData['submit_callback'] = $aCallbackUrls['submit'];
|
||||
$aFormData['cancel_callback'] = $aCallbackUrls['cancel'];
|
||||
// Preparing navigation rules
|
||||
$aNavigationRules = $this->oNavigationRuleHelper->PrepareRulesForForm($aFormProperties, $oObject, $bModal);
|
||||
$aFormData['submit_rule'] = $aNavigationRules['submit'];
|
||||
$aFormData['cancel_rule'] = $aNavigationRules['cancel'];
|
||||
/** @deprecated We keep the "xxx_callback" name to keep compatibility with extensions using the portal_form_handler.js widget but they will be removed in a future version. */
|
||||
$aFormData['submit_callback'] = $aNavigationRules['submit']['url'];
|
||||
$aFormData['cancel_callback'] = $aNavigationRules['cancel']['url'];
|
||||
|
||||
// Preparing renderer
|
||||
// Note : We might need to distinguish form & renderer endpoints
|
||||
@@ -292,23 +297,16 @@ class ObjectFormHandlerHelper
|
||||
);
|
||||
if ($aFormData['validation']['valid'] === true)
|
||||
{
|
||||
// Note : We don't use $sObjectId there as it can be null if we are creating a new one. Instead we use the id from the created object once it has been seralized
|
||||
// Note : We don't use $sObjectId there as it can be null if we are creating a new one. Instead we use the id from the created object once it has been serialized
|
||||
// Check if stimulus has to be applied
|
||||
$sStimulusCode = $this->oRequestManipulator->ReadParam('stimulus_code', '');
|
||||
if (!empty($sStimulusCode))
|
||||
{
|
||||
$aFormData['validation']['redirection'] = array(
|
||||
'url' => $this->oUrlGenerator->generate('p_object_apply_stimulus', array('sObjectClass' => $sObjectClass, 'sObjectId' => $oFormManager->GetObject()->GetKey(), 'sStimulusCode' => $sStimulusCode)),
|
||||
'ajax' => true,
|
||||
'modal' => true,
|
||||
);
|
||||
}
|
||||
// Otherwise, we show the object if there is no default
|
||||
// else
|
||||
// {
|
||||
// $aFormData['validation']['redirection'] = array(
|
||||
// 'alternative_url' => $this->oUrlGenerator->generate('p_object_edit', array('sObjectClass' => $sObjectClass, 'sObjectId' => $oFormManager->GetObject()->GetKey()))
|
||||
// );
|
||||
// }
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -410,4 +408,19 @@ class ObjectFormHandlerHelper
|
||||
|
||||
return $oTwig->render($sId, $aData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of the available modes for a form.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @return array
|
||||
*/
|
||||
public static function GetAllowedModes()
|
||||
{
|
||||
return array(
|
||||
static::ENUM_MODE_VIEW,
|
||||
static::ENUM_MODE_EDIT,
|
||||
static::ENUM_MODE_CREATE,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -76,8 +76,8 @@
|
||||
field_set: oFieldSet_{{ sFormIdSanitized }},
|
||||
submit_btn_selector: $('#{{ sFormId }}').parent().find('.form_btn_submit, .form_btn_transition'),
|
||||
cancel_btn_selector: $('#{{ sFormId }}').parent().find('.form_btn_cancel'),
|
||||
submit_url: {% if form.submit_callback is not null %}"{{ form.submit_callback|raw }}"{% else %}null{% endif %},
|
||||
cancel_url: {% if form.cancel_callback is not null %}"{{ form.cancel_callback|raw }}"{% else %}null{% endif %},
|
||||
{% if form.submit_rule is not null %}submit_rule: {{ form.submit_rule|json_encode|raw }}{% endif %},
|
||||
{% if form.cancel_rule is not null %}cancel_rule: {{ form.cancel_rule|json_encode|raw }}{% endif %},
|
||||
endpoint: "{{ form.renderer.GetEndpoint()|raw }}",
|
||||
is_modal: {% if tIsModal == true %}true{% else %}false{% endif %}
|
||||
});
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
/**
|
||||
* Copyright (C) 2013-2019 Combodo SARL
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
* 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 Composer\Autoload;
|
||||
@@ -279,7 +287,7 @@ class ClassLoader
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2019 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
|
||||
*/
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
@@ -30,8 +47,8 @@ return array(
|
||||
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\Basic' => $baseDir . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Basic.php',
|
||||
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\Forms' => $baseDir . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Forms.php',
|
||||
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\Lists' => $baseDir . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Lists.php',
|
||||
'Combodo\\iTop\\Portal\\EventListener\\ApplicationContextSetUrlMakerClass' => $baseDir . '/src/EventListener/ApplicationContextSetUrlMakerClass.php',
|
||||
'Combodo\\iTop\\Portal\\EventListener\\ApplicationContextSetPluginPropertyClass' => $baseDir . '/src/EventListener/ApplicationContextSetPluginPropertyClass.php',
|
||||
'Combodo\\iTop\\Portal\\EventListener\\ApplicationContextSetUrlMakerClass' => $baseDir . '/src/EventListener/ApplicationContextSetUrlMakerClass.php',
|
||||
'Combodo\\iTop\\Portal\\EventListener\\UserProvider' => $baseDir . '/src/EventListener/UserProvider.php',
|
||||
'Combodo\\iTop\\Portal\\Form\\ObjectFormManager' => $baseDir . '/src/Form/ObjectFormManager.php',
|
||||
'Combodo\\iTop\\Portal\\Form\\PasswordFormManager' => $baseDir . '/src/Form/PasswordFormManager.php',
|
||||
@@ -41,6 +58,7 @@ return array(
|
||||
'Combodo\\iTop\\Portal\\Helper\\BrowseBrickHelper' => $baseDir . '/src/Helper/BrowseBrickHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\ContextManipulatorHelper' => $baseDir . '/src/Helper/ContextManipulatorHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\LifecycleValidatorHelper' => $baseDir . '/src/Helper/LifecycleValidatorHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\NavigationRuleHelper' => $baseDir . '/src/Helper/NavigationRuleHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\ObjectFormHandlerHelper' => $baseDir . '/src/Helper/ObjectFormHandlerHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\RequestManipulatorHelper' => $baseDir . '/src/Helper/RequestManipulatorHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\ScopeValidatorHelper' => $baseDir . '/src/Helper/ScopeValidatorHelper.php',
|
||||
|
||||
@@ -1,4 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2013-2019 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
|
||||
*/
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
@@ -50,8 +67,8 @@ class ComposerStaticInitdf408f3f8ea034d298269cdf7647358b
|
||||
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\Basic' => __DIR__ . '/../..' . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Basic.php',
|
||||
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\Forms' => __DIR__ . '/../..' . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Forms.php',
|
||||
'Combodo\\iTop\\Portal\\DependencyInjection\\SilexCompatBootstrap\\PortalXmlConfiguration\\Lists' => __DIR__ . '/../..' . '/src/DependencyInjection/SilexCompatBootstrap/PortalXmlConfiguration/Lists.php',
|
||||
'Combodo\\iTop\\Portal\\EventListener\\ApplicationContextSetUrlMakerClass' => __DIR__ . '/../..' . '/src/EventListener/ApplicationContextSetUrlMakerClass.php',
|
||||
'Combodo\\iTop\\Portal\\EventListener\\ApplicationContextSetPluginPropertyClass' => __DIR__ . '/../..' . '/src/EventListener/ApplicationContextSetPluginPropertyClass.php',
|
||||
'Combodo\\iTop\\Portal\\EventListener\\ApplicationContextSetUrlMakerClass' => __DIR__ . '/../..' . '/src/EventListener/ApplicationContextSetUrlMakerClass.php',
|
||||
'Combodo\\iTop\\Portal\\EventListener\\UserProvider' => __DIR__ . '/../..' . '/src/EventListener/UserProvider.php',
|
||||
'Combodo\\iTop\\Portal\\Form\\ObjectFormManager' => __DIR__ . '/../..' . '/src/Form/ObjectFormManager.php',
|
||||
'Combodo\\iTop\\Portal\\Form\\PasswordFormManager' => __DIR__ . '/../..' . '/src/Form/PasswordFormManager.php',
|
||||
@@ -61,6 +78,7 @@ class ComposerStaticInitdf408f3f8ea034d298269cdf7647358b
|
||||
'Combodo\\iTop\\Portal\\Helper\\BrowseBrickHelper' => __DIR__ . '/../..' . '/src/Helper/BrowseBrickHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\ContextManipulatorHelper' => __DIR__ . '/../..' . '/src/Helper/ContextManipulatorHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\LifecycleValidatorHelper' => __DIR__ . '/../..' . '/src/Helper/LifecycleValidatorHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\NavigationRuleHelper' => __DIR__ . '/../..' . '/src/Helper/NavigationRuleHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\ObjectFormHandlerHelper' => __DIR__ . '/../..' . '/src/Helper/ObjectFormHandlerHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\RequestManipulatorHelper' => __DIR__ . '/../..' . '/src/Helper/RequestManipulatorHelper.php',
|
||||
'Combodo\\iTop\\Portal\\Helper\\ScopeValidatorHelper' => __DIR__ . '/../..' . '/src/Helper/ScopeValidatorHelper.php',
|
||||
|
||||
Reference in New Issue
Block a user