mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°8772 - PropertyTrees definition in DataModel
This commit is contained in:
@@ -1185,5 +1185,106 @@
|
||||
</property>
|
||||
</properties>
|
||||
</attribute_properties_definition>
|
||||
<property_trees _delta="define" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://www.combodo.com/itop-schema/3.3">
|
||||
<property_tree id="DashletGroupBy" xsi:type="Combodo-PropertyTree">
|
||||
<extends>Dashlet</extends>
|
||||
<nodes>
|
||||
<node id="title" xsi:type="Combodo-Property">
|
||||
<label>UI:DashletGroupBy:Prop-Title</label>
|
||||
<value-type xsi:type="Combodo-ValueTypeLabel"/><!-- LabelFormBlock -->
|
||||
</node>
|
||||
<node id="query" xsi:type="Combodo-Property">
|
||||
<label>UI:DashletGroupBy:Prop-Query</label>
|
||||
<data-transform>
|
||||
<xml-node-empty-not-allowed/> <!-- mandatory quoi ! -->
|
||||
</data-transform>
|
||||
<value-type xsi:type="Combodo-ValueTypeOQL"/><!-- OqlFormBlock -->
|
||||
</node>
|
||||
<node id="group_by" xsi:type="Combodo-Property">
|
||||
<label>UI:DashletGroupBy:Prop-GroupBy</label>
|
||||
<data-transform>
|
||||
<xml-node-empty-not-allowed/>
|
||||
</data-transform>
|
||||
<value-type xsi:type="Combodo-ValueTypeClassAttributeGroupBy"> <!-- par défaut, il proposera le state attribute de la classe -->
|
||||
<class>{{query.selected_class}}</class>
|
||||
</value-type>
|
||||
</node>
|
||||
<node id="style" xsi:type="Combodo-Property"> <!-- possible de le cacher, etc.... celui-ci nous met dedans -->
|
||||
<label>UI:DashletGroupBy:Prop-Style</label>
|
||||
<data-transform>
|
||||
<xml-node-empty-defaults-to>bars</xml-node-empty-defaults-to>
|
||||
</data-transform>
|
||||
<value-type xsi:type="Combodo-ValueTypeChoice">
|
||||
<values>
|
||||
<value id="bars">
|
||||
<label>UI:DashletGroupByBars:Label</label>
|
||||
</value>
|
||||
<value id="pie">
|
||||
<label>UI:DashletGroupByPie:Label</label>
|
||||
</value>
|
||||
<value id="table">
|
||||
<label>UI:DashletGroupByTable:Label</label>
|
||||
</value>
|
||||
</values>
|
||||
</value-type>
|
||||
</node>
|
||||
<node id="aggregation_function" xsi:type="Combodo-Property">
|
||||
<label>UI:DashletGroupBy:Prop-Function</label>
|
||||
<data-transform>
|
||||
<xml-node-empty-not-allowed/> <!-- mandatory quoi ! -->
|
||||
</data-transform>
|
||||
<value-type xsi:type="Combodo-ValueTypeAggregateFunction"> <!-- par défaut : count -->
|
||||
<class>{{query.selected_class}}</class> <!-- pour savoir si il y a des attributs additionnables -->
|
||||
</value-type>
|
||||
</node>
|
||||
<node id="aggregation_attribute" xsi:type="Combodo-Property">
|
||||
<label>UI:DashletGroupBy:Prop-FunctionAttribute</label>
|
||||
<relevance-condition>{{aggregation_function.value != 'count'}}</relevance-condition>
|
||||
<data-transform>
|
||||
<xml-node-empty-not-allowed/> <!-- mandatory quoi ! -->
|
||||
</data-transform>
|
||||
<value-type xsi:type="Combodo-ValueTypeClassAttribute">
|
||||
<class>{{query.selected_class}}</class>
|
||||
<category>numeric</category>
|
||||
</value-type>
|
||||
</node>
|
||||
<node id="order_by" xsi:type="Combodo-Property">
|
||||
<label>UI:DashletGroupBy:Prop-OrderField</label>
|
||||
<value-type xsi:type="Combodo-ValueTypeChoice">
|
||||
<values>
|
||||
<value id="attribute">
|
||||
<label>{{aggregation_attribute.label}}</label>
|
||||
</value>
|
||||
<value id="function">
|
||||
<label>{{aggregation_function.label}}</label>
|
||||
</value>
|
||||
</values>
|
||||
</value-type>
|
||||
</node>
|
||||
<node id="limit" xsi:type="Combodo-Property">
|
||||
<label>UI:DashletGroupBy:Prop-Limit</label>
|
||||
<relevance-condition>{{order_by.value = 'function'}}</relevance-condition>
|
||||
<value-type xsi:type="Combodo-ValueTypeInteger"/>
|
||||
</node>
|
||||
<node id="order_direction" xsi:type="Combodo-Property">
|
||||
<label>UI:DashletGroupBy:Prop-OrderDirection</label>
|
||||
<data-transform>
|
||||
<xml-node-empty-not-allowed/>
|
||||
</data-transform>
|
||||
<value-type xsi:type="Combodo-ValueTypeChoice">
|
||||
<values>
|
||||
<value id="asc">
|
||||
<label>UI:DashletGroupBy:Order:asc</label>
|
||||
</value>
|
||||
<value id="desc">
|
||||
<label>UI:DashletGroupBy:Order:desc</label>
|
||||
</value>
|
||||
</values>
|
||||
</value-type>
|
||||
<display-default>desc</display-default>
|
||||
</node>
|
||||
</nodes>
|
||||
</property_tree>
|
||||
</property_trees>
|
||||
</meta>
|
||||
</itop_design>
|
||||
|
||||
@@ -509,7 +509,7 @@ return array(
|
||||
'Combodo\\iTop\\Forms\\Block\\IFormBlock' => $baseDir . '/sources/Forms/Block/IFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Compiler\\FormsCompiler' => $baseDir . '/sources/Forms/Compiler/FormsCompiler.php',
|
||||
'Combodo\\iTop\\Forms\\Compiler\\FormsCompilerException' => $baseDir . '/sources/Forms/Compiler/FormsCompilerException.php',
|
||||
'Combodo\\iTop\\Forms\\Compiler\\FormsController' => $baseDir . '/sources/Forms/Compiler/FormsController.php',
|
||||
'Combodo\\iTop\\Forms\\Controller\\FormsController' => $baseDir . '/sources/Forms/Controller/FormsController.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => $baseDir . '/sources/Forms/FormBuilder/DependencyHandler.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyMap' => $baseDir . '/sources/Forms/FormBuilder/DependencyMap.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilder' => $baseDir . '/sources/Forms/FormBuilder/FormBuilder.php',
|
||||
@@ -555,6 +555,7 @@ return array(
|
||||
'Combodo\\iTop\\PropertyTree\\CollectionOfValues' => $baseDir . '/sources/PropertyTree/CollectionOfValues.php',
|
||||
'Combodo\\iTop\\PropertyTree\\Property' => $baseDir . '/sources/PropertyTree/Property.php',
|
||||
'Combodo\\iTop\\PropertyTree\\PropertyTree' => $baseDir . '/sources/PropertyTree/PropertyTree.php',
|
||||
'Combodo\\iTop\\PropertyTree\\PropertyTreeDesign' => $baseDir . '/sources/PropertyTree/PropertyTreeDesign.php',
|
||||
'Combodo\\iTop\\PropertyTree\\PropertyTreeException' => $baseDir . '/sources/PropertyTree/PropertyTreeException.php',
|
||||
'Combodo\\iTop\\PropertyTree\\PropertyTreeFactory' => $baseDir . '/sources/PropertyTree/PropertyTreeFactory.php',
|
||||
'Combodo\\iTop\\PropertyTree\\ValueType\\AbstractValueType' => $baseDir . '/sources/PropertyTree/ValueType/AbstractValueType.php',
|
||||
|
||||
@@ -895,7 +895,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Forms\\Block\\IFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/IFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Compiler\\FormsCompiler' => __DIR__ . '/../..' . '/sources/Forms/Compiler/FormsCompiler.php',
|
||||
'Combodo\\iTop\\Forms\\Compiler\\FormsCompilerException' => __DIR__ . '/../..' . '/sources/Forms/Compiler/FormsCompilerException.php',
|
||||
'Combodo\\iTop\\Forms\\Compiler\\FormsController' => __DIR__ . '/../..' . '/sources/Forms/Compiler/FormsController.php',
|
||||
'Combodo\\iTop\\Forms\\Controller\\FormsController' => __DIR__ . '/../..' . '/sources/Forms/Controller/FormsController.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyHandler' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/DependencyHandler.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\DependencyMap' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/DependencyMap.php',
|
||||
'Combodo\\iTop\\Forms\\FormBuilder\\FormBuilder' => __DIR__ . '/../..' . '/sources/Forms/FormBuilder/FormBuilder.php',
|
||||
@@ -941,6 +941,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\PropertyTree\\CollectionOfValues' => __DIR__ . '/../..' . '/sources/PropertyTree/CollectionOfValues.php',
|
||||
'Combodo\\iTop\\PropertyTree\\Property' => __DIR__ . '/../..' . '/sources/PropertyTree/Property.php',
|
||||
'Combodo\\iTop\\PropertyTree\\PropertyTree' => __DIR__ . '/../..' . '/sources/PropertyTree/PropertyTree.php',
|
||||
'Combodo\\iTop\\PropertyTree\\PropertyTreeDesign' => __DIR__ . '/../..' . '/sources/PropertyTree/PropertyTreeDesign.php',
|
||||
'Combodo\\iTop\\PropertyTree\\PropertyTreeException' => __DIR__ . '/../..' . '/sources/PropertyTree/PropertyTreeException.php',
|
||||
'Combodo\\iTop\\PropertyTree\\PropertyTreeFactory' => __DIR__ . '/../..' . '/sources/PropertyTree/PropertyTreeFactory.php',
|
||||
'Combodo\\iTop\\PropertyTree\\ValueType\\AbstractValueType' => __DIR__ . '/../..' . '/sources/PropertyTree/ValueType/AbstractValueType.php',
|
||||
|
||||
@@ -23,6 +23,7 @@ use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use Combodo\iTop\Application\WebPage\Page;
|
||||
use Combodo\iTop\DesignElement;
|
||||
use Combodo\iTop\DesignDocument;
|
||||
use Combodo\iTop\PropertyTree\PropertyTreeDesign;
|
||||
|
||||
require_once(APPROOT.'setup/setuputils.class.inc.php');
|
||||
require_once(APPROOT.'setup/modelfactory.class.inc.php');
|
||||
@@ -699,6 +700,10 @@ PHP;
|
||||
$oModuleDesignsNode = $this->oFactory->GetNodes('/itop_design/module_designs')->item(0);
|
||||
$this->CompileModuleDesigns($oModuleDesignsNode, $sTempTargetDir, $sFinalTargetDir);
|
||||
|
||||
// Create property trees XML files
|
||||
$oPropertyTreesNode = $this->oFactory->GetNodes('/itop_design/meta/property_trees')->item(0);
|
||||
$this->CompilePropertyTrees($oPropertyTreesNode, $sTempTargetDir, $sFinalTargetDir);
|
||||
|
||||
// Compile the XML parameters
|
||||
/** @var \MFElement $oParametersNode */
|
||||
$oParametersNode = $this->oFactory->GetNodes('/itop_design/module_parameters')->item(0);
|
||||
@@ -3572,6 +3577,21 @@ EOF;
|
||||
}
|
||||
}
|
||||
|
||||
protected function CompilePropertyTrees(?DOMNode $oPropertyTrees, string $sTempTargetDir, string $sFinalTargetDir): void
|
||||
{
|
||||
if ($oPropertyTrees) {
|
||||
foreach ($oPropertyTrees->GetNodes('property_tree') as $oPropertyTree) {
|
||||
$oDoc = new PropertyTreeDesign();
|
||||
$oClone = $oDoc->importNode($oPropertyTree->cloneNode(true), true);
|
||||
$oDoc->appendChild($oClone);
|
||||
/** @var DesignElement $oPropertyTree */
|
||||
$sExtends = $oPropertyTree->GetChildText('extends', 'Default');
|
||||
SetupUtils::builddir($sTempTargetDir.'/core/property_trees/'.$sExtends);
|
||||
$oDoc->save($sTempTargetDir.'/core/property_trees/'.$sExtends.'/'.$oPropertyTree->getAttribute('id').'.xml');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \DOMFormatException
|
||||
*/
|
||||
|
||||
@@ -9,8 +9,7 @@ namespace Combodo\iTop\Application\UI\Base\Component\TurboForm;
|
||||
|
||||
use Combodo\iTop\Application\UI\Base\AbstractUIBlockFactory;
|
||||
use Combodo\iTop\Forms\Block\FormBlockService;
|
||||
use Combodo\iTop\Forms\Compiler\FormsCompiler;
|
||||
use Combodo\iTop\Forms\Compiler\FormsController;
|
||||
use Combodo\iTop\Forms\Controller\FormsController;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use utils;
|
||||
|
||||
@@ -60,7 +59,7 @@ class TurboFormUIBlockFactory extends AbstractUIBlockFactory
|
||||
*/
|
||||
public static function MakeForDashletConfiguration(string $sDashletId, array $aData = [], string $sId = null): TurboForm
|
||||
{
|
||||
$oBlockForm = FormBlockService::GetInstance()->GetFormBlockById($sDashletId);
|
||||
$oBlockForm = FormBlockService::GetInstance()->GetFormBlockById($sDashletId, 'Dashlet');
|
||||
$oController = new FormsController();
|
||||
$oBuilder = $oController->GetFormBuilder($oBlockForm, $aData);
|
||||
$oForm = $oBuilder->getForm();
|
||||
|
||||
@@ -13,9 +13,11 @@ use Combodo\iTop\Service\Cache\DataModelDependantCache;
|
||||
use Combodo\iTop\Service\DependencyInjection\DIService;
|
||||
use ModelReflection;
|
||||
use ModelReflectionRuntime;
|
||||
use utils;
|
||||
|
||||
class FormBlockService
|
||||
{
|
||||
public const CACHE_POOL = 'Forms';
|
||||
private static FormBlockService $oInstance;
|
||||
private DataModelDependantCache $oCacheService;
|
||||
|
||||
@@ -36,22 +38,29 @@ class FormBlockService
|
||||
|
||||
/**
|
||||
* @param string $sId name of the form to retrieve
|
||||
* @param string $sType
|
||||
*
|
||||
* @return \Combodo\iTop\Forms\Block\Base\FormBlock
|
||||
* @throws \Combodo\iTop\Forms\Block\FormBlockException
|
||||
* @throws \Combodo\iTop\Forms\Compiler\FormsCompilerException
|
||||
* @throws \Combodo\iTop\PropertyTree\PropertyTreeException
|
||||
* @throws \DOMFormatException
|
||||
*/
|
||||
public function GetFormBlockById(string $sId): FormBlock
|
||||
public function GetFormBlockById(string $sId, string $sType): FormBlock
|
||||
{
|
||||
$sFilteredId = preg_replace('/[^0-9a-zA-Z_]/', '', $sId);
|
||||
if (strlen($sFilteredId) === 0) {
|
||||
throw new FormBlockException('Malformed name for block: '.json_encode($sId));
|
||||
}
|
||||
if (!$this->oCacheService->HasEntry(FormsCompiler::CACHE_POOL, $sFilteredId)) {
|
||||
throw new FormBlockException('No block found for: '.json_encode($sFilteredId).' original value asked: '.json_encode($sId));
|
||||
if (!$this->oCacheService->HasEntry(self::CACHE_POOL, $sFilteredId) || utils::IsDevelopmentEnvironment()) {
|
||||
// Cache not found, compile the form
|
||||
$sPHPContent = FormsCompiler::GetInstance()->CompileForm($sFilteredId, $sType);
|
||||
$this->oCacheService->StorePhpContent(FormBlockService::CACHE_POOL, $sId, "<?php\n\n$sPHPContent");
|
||||
}
|
||||
$this->oCacheService->Fetch(FormsCompiler::CACHE_POOL, $sFilteredId);
|
||||
$this->oCacheService->Fetch(self::CACHE_POOL, $sFilteredId);
|
||||
$sFormBlockClass = 'FormFor__'.$sFilteredId;
|
||||
|
||||
return new $sFilteredId($sFilteredId);
|
||||
return new $sFormBlockClass($sFilteredId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,15 +9,22 @@ namespace Combodo\iTop\Forms\Compiler;
|
||||
|
||||
use Combodo\iTop\DesignDocument;
|
||||
use Combodo\iTop\Forms\Block\Base\FormBlock;
|
||||
use Combodo\iTop\Forms\Block\FormBlockService;
|
||||
use Combodo\iTop\PropertyTree\PropertyTreeFactory;
|
||||
use Combodo\iTop\Service\Cache\DataModelDependantCache;
|
||||
use DOMFormatException;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* XML to PHP Forms compiler.
|
||||
*
|
||||
* @package Combodo\iTop\Forms\Compiler
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class FormsCompiler
|
||||
{
|
||||
private static FormsCompiler $oInstance;
|
||||
private DataModelDependantCache $oCacheService;
|
||||
public const CACHE_POOL = 'Forms';
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
@@ -38,7 +45,7 @@ class FormsCompiler
|
||||
*
|
||||
* @param string $sXMLContent property tree structure in xml
|
||||
*
|
||||
* @return string
|
||||
* @return string Generated PHP
|
||||
* @throws \Combodo\iTop\Forms\Compiler\FormsCompilerException
|
||||
* @throws \Combodo\iTop\PropertyTree\PropertyTreeException
|
||||
* @throws \DOMFormatException
|
||||
@@ -60,8 +67,24 @@ class FormsCompiler
|
||||
return $oPropertyTree->ToPHPFormBlock();
|
||||
}
|
||||
|
||||
public function StoreFormFromContent(string $sId, string $sPHPContent): void
|
||||
/**
|
||||
* @param string $sId
|
||||
* @param string $sType
|
||||
*
|
||||
* @return string Generated PHP
|
||||
* @throws \Combodo\iTop\Forms\Compiler\FormsCompilerException
|
||||
* @throws \Combodo\iTop\PropertyTree\PropertyTreeException
|
||||
* @throws \DOMFormatException
|
||||
*/
|
||||
public function CompileForm(string $sId, string $sType): string
|
||||
{
|
||||
$this->oCacheService->StorePhpContent(self::CACHE_POOL, $sId, $sPHPContent);
|
||||
$sPath = utils::GetAbsoluteModulePath('core')."property_trees/$sType/$sId.xml";
|
||||
if (!file_exists($sPath)) {
|
||||
throw new FormsCompilerException("Properties definition $sType/$sId not present");
|
||||
}
|
||||
|
||||
$sXMLContent = file_get_contents($sPath);
|
||||
|
||||
return $this->CompileFormFromXML($sXMLContent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Forms\Compiler;
|
||||
namespace Combodo\iTop\Forms\Controller;
|
||||
|
||||
use Combodo\iTop\Application\TwigBase\Controller\Controller;
|
||||
use Combodo\iTop\Forms\Block\FormBlockService;
|
||||
use Combodo\iTop\ItopSdkFormDemonstrator\Helper\ItopSdkFormDemonstratorLog;
|
||||
use Exception;
|
||||
use IssueLog;
|
||||
use utils;
|
||||
|
||||
class FormsController extends Controller
|
||||
{
|
||||
@@ -32,7 +31,7 @@ class FormsController extends Controller
|
||||
$sDashletId = $oRequest->query->get('dashlet_code');
|
||||
|
||||
// Get the form block from the service (and the compiler)
|
||||
$oFormBlock = FormBlockService::GetInstance()->GetFormBlockById($sDashletId);
|
||||
$oFormBlock = FormBlockService::GetInstance()->GetFormBlockById($sDashletId, 'Dashlet');
|
||||
$oBuilder = $this->GetFormBuilder($oFormBlock, []);
|
||||
$oForm = $oBuilder->getForm();
|
||||
$oForm->handleRequest($oRequest);
|
||||
80
sources/PropertyTree/PropertyTreeDesign.php
Normal file
80
sources/PropertyTree/PropertyTreeDesign.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\PropertyTree;
|
||||
|
||||
use Combodo\iTop\DesignDocument;
|
||||
use Exception;
|
||||
use utils;
|
||||
|
||||
class PropertyTreeDesign extends DesignDocument
|
||||
{
|
||||
public function __construct(string $sDesignSourceId = null, string $sType = 'Default')
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
if (!is_null($sDesignSourceId)) {
|
||||
$this->LoadFromCompiledDesigns($sDesignSourceId, $sType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the data where the compiler has left them...
|
||||
* @param $sDesignSourceId String Identifier of the section module_design (generally a module name)
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function LoadFromCompiledDesigns(string $sDesignSourceId, string $sType)
|
||||
{
|
||||
$sDesignDir = APPROOT.'env-'.utils::GetCurrentEnvironment()."/core/property_trees/$sType/";
|
||||
$sFile = $sDesignDir.$sDesignSourceId.'.xml';
|
||||
if (!file_exists($sFile)) {
|
||||
$aFiles = glob($sDesignDir.'/*/*.xml');
|
||||
if (count($aFiles) == 0) {
|
||||
$sAvailable = 'none!';
|
||||
} else {
|
||||
$aAvailable = [];
|
||||
foreach ($aFiles as $sFile) {
|
||||
$aAvailable[] = "'".basename($sFile, '.xml')."'";
|
||||
}
|
||||
$sAvailable = implode(', ', $aAvailable);
|
||||
}
|
||||
throw new Exception("Could not load property tree design '$sDesignSourceId'. Available designs: $sAvailable");
|
||||
}
|
||||
|
||||
// Silently keep track of errors
|
||||
libxml_use_internal_errors(true);
|
||||
libxml_clear_errors();
|
||||
$this->load($sFile);
|
||||
//$bValidated = $oDocument->schemaValidate(APPROOT.'setup/itop_design.xsd');
|
||||
$aErrors = libxml_get_errors();
|
||||
if (count($aErrors) > 0) {
|
||||
$aDisplayErrors = [];
|
||||
foreach ($aErrors as $oXmlError) {
|
||||
$aDisplayErrors[] = 'Line '.$oXmlError->line.': '.$oXmlError->message;
|
||||
}
|
||||
|
||||
throw new Exception("Invalid XML in '$sFile'. Errors: ".implode(', ', $aDisplayErrors));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Overload of the standard API
|
||||
*
|
||||
* @param $filename
|
||||
* @param int $options
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
// Return type union is not supported by PHP 7.4, we can remove the following PHP attribute and add the return type once iTop min PHP version is PHP 8.0+
|
||||
#[\ReturnTypeWillChange]
|
||||
public function save($filename, $options = null)
|
||||
{
|
||||
$this->documentElement->setAttribute('xsi:noNamespaceSchemaLocation', 'https://www.combodo.com/itop-schema/'.ITOP_DESIGN_LATEST_VERSION);
|
||||
|
||||
return parent::save($filename);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user