mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-20 00:58:48 +02:00
Add ModelReflection Service as dependency injection + tests
This commit is contained in:
@@ -435,6 +435,8 @@ return array(
|
||||
'Combodo\\iTop\\Dependencies\\AbstractFolderAnalyzer' => $baseDir . '/sources/Dependencies/AbstractFolderAnalyzer.php',
|
||||
'Combodo\\iTop\\Dependencies\\Composer\\iTopComposer' => $baseDir . '/sources/Dependencies/Composer/iTopComposer.php',
|
||||
'Combodo\\iTop\\Dependencies\\NPM\\iTopNPM' => $baseDir . '/sources/Dependencies/NPM/iTopNPM.php',
|
||||
'Combodo\\iTop\\DependencyInjection\\DIException' => $baseDir . '/sources/DependencyInjection/DIException.php',
|
||||
'Combodo\\iTop\\DependencyInjection\\DIService' => $baseDir . '/sources/DependencyInjection/DIService.php',
|
||||
'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\Form\\Field\\AbstractSimpleField' => $baseDir . '/sources/Form/Field/AbstractSimpleField.php',
|
||||
@@ -491,12 +493,9 @@ return array(
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeValueChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\IDataModelBlock' => $baseDir . '/sources/Forms/Block/DataModel/IDataModelBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/OqlFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Expression\\ExpressionFormBlock' => $baseDir . '/sources/Forms/Block/Expression/ExpressionFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockDescription' => $baseDir . '/sources/Forms/Block/FormBlockDescription.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockException' => $baseDir . '/sources/Forms/Block/FormBlockException.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockFactory' => $baseDir . '/sources/Forms/Block/FormBlockFactory.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',
|
||||
@@ -523,6 +522,7 @@ return array(
|
||||
'Combodo\\iTop\\Forms\\IO\\FormBlockIOException' => $baseDir . '/sources/Forms/IO/FormBlockIOException.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\FormInput' => $baseDir . '/sources/Forms/IO/FormInput.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\FormOutput' => $baseDir . '/sources/Forms/IO/FormOutput.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AbstractIOFormat' => $baseDir . '/sources/Forms/IO/Format/AbstractIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AttributeIOFormat' => $baseDir . '/sources/Forms/IO/Format/AttributeIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\BooleanIOFormat' => $baseDir . '/sources/Forms/IO/Format/BooleanIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\ClassIOFormat' => $baseDir . '/sources/Forms/IO/Format/ClassIOFormat.php',
|
||||
|
||||
@@ -816,6 +816,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Dependencies\\AbstractFolderAnalyzer' => __DIR__ . '/../..' . '/sources/Dependencies/AbstractFolderAnalyzer.php',
|
||||
'Combodo\\iTop\\Dependencies\\Composer\\iTopComposer' => __DIR__ . '/../..' . '/sources/Dependencies/Composer/iTopComposer.php',
|
||||
'Combodo\\iTop\\Dependencies\\NPM\\iTopNPM' => __DIR__ . '/../..' . '/sources/Dependencies/NPM/iTopNPM.php',
|
||||
'Combodo\\iTop\\DependencyInjection\\DIException' => __DIR__ . '/../..' . '/sources/DependencyInjection/DIException.php',
|
||||
'Combodo\\iTop\\DependencyInjection\\DIService' => __DIR__ . '/../..' . '/sources/DependencyInjection/DIService.php',
|
||||
'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\Form\\Field\\AbstractSimpleField' => __DIR__ . '/../..' . '/sources/Form/Field/AbstractSimpleField.php',
|
||||
@@ -872,12 +874,9 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeValueChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\IDataModelBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/IDataModelBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/OqlFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Expression\\ExpressionFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Expression/ExpressionFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockDescription' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockDescription.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockException' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockException.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\FormBlockFactory' => __DIR__ . '/../..' . '/sources/Forms/Block/FormBlockFactory.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',
|
||||
@@ -904,6 +903,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Forms\\IO\\FormBlockIOException' => __DIR__ . '/../..' . '/sources/Forms/IO/FormBlockIOException.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\FormInput' => __DIR__ . '/../..' . '/sources/Forms/IO/FormInput.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\FormOutput' => __DIR__ . '/../..' . '/sources/Forms/IO/FormOutput.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AbstractIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AbstractIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AttributeIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AttributeIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\BooleanIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/BooleanIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\ClassIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/ClassIOFormat.php',
|
||||
|
||||
@@ -169,10 +169,7 @@ abstract class Controller extends AbstractController
|
||||
$this->SetViewPath($sViewPath, $aAdditionalPaths);
|
||||
if ($sModuleName != 'core') {
|
||||
try {
|
||||
$this->aDefaultParams = [
|
||||
'sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php'),
|
||||
'sAPPROOTURL' => utils::GetAbsoluteUrlAppRoot(),
|
||||
];
|
||||
$this->aDefaultParams = ['sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')];
|
||||
} catch (Exception $e) {
|
||||
IssueLog::Error($e->getMessage());
|
||||
}
|
||||
@@ -200,10 +197,7 @@ abstract class Controller extends AbstractController
|
||||
$this->SetModuleName(basename($sModulePath));
|
||||
$this->SetViewPath($sModulePath.'/view');
|
||||
try {
|
||||
$this->aDefaultParams = [
|
||||
'sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php'),
|
||||
'sAPPROOTURL' => utils::GetAbsoluteUrlAppRoot(),
|
||||
];
|
||||
$this->aDefaultParams = ['sIndexURL' => utils::GetAbsoluteUrlModulePage($this->m_sModule, 'index.php')];
|
||||
} catch (Exception $e) {
|
||||
IssueLog::Error($e->getMessage());
|
||||
}
|
||||
|
||||
19
sources/DependencyInjection/DIException.php
Normal file
19
sources/DependencyInjection/DIException.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\DependencyInjection;
|
||||
|
||||
use IssueLog;
|
||||
use Throwable;
|
||||
|
||||
class DIException extends \Exception
|
||||
{
|
||||
public function __construct(string $sMessage = '', int $iCode = 0, ?Throwable $oPrevious = null, array $aContext = [])
|
||||
{
|
||||
parent::__construct($sMessage, $iCode, $oPrevious);
|
||||
IssueLog::Exception(get_class($this).' occurs: '.$sMessage, $this, null, $aContext);
|
||||
}
|
||||
}
|
||||
60
sources/DependencyInjection/DIService.php
Normal file
60
sources/DependencyInjection/DIService.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\DependencyInjection;
|
||||
|
||||
class DIService
|
||||
{
|
||||
private static DIService $oInstance;
|
||||
private array $aServices = [];
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
final public static function GetInstance(): DIService
|
||||
{
|
||||
if (!isset(static::$oInstance)) {
|
||||
static::$oInstance = new DIService();
|
||||
}
|
||||
|
||||
return static::$oInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a service by name
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param string $sName Name of the service to register
|
||||
* @param mixed $oService Service to register
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
final public function RegisterService(string $sName, mixed $oService): void
|
||||
{
|
||||
$aServices[$sName] = $oService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a previously registered service
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @param string $sName name of the service to get
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Combodo\iTop\DependencyInjection\DIException
|
||||
*/
|
||||
final public function GetService(string $sName): mixed
|
||||
{
|
||||
if (!isset($this->aServices[$sName])) {
|
||||
throw new DIException("Service ".json_encode($sName)." not found");
|
||||
}
|
||||
|
||||
return $this->aServices[$sName];
|
||||
}
|
||||
}
|
||||
@@ -7,13 +7,14 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\DataModel;
|
||||
|
||||
use Combodo\iTop\DependencyInjection\DIService;
|
||||
use Combodo\iTop\Forms\Block\Base\ChoiceFormBlock;
|
||||
use Combodo\iTop\Forms\IO\Converter\StringToAttributeConverter;
|
||||
use Combodo\iTop\Forms\IO\Format\AttributeIOFormat;
|
||||
use Combodo\iTop\Forms\IO\Format\ClassIOFormat;
|
||||
use Combodo\iTop\Forms\Register\IORegister;
|
||||
use Combodo\iTop\Forms\Register\OptionsRegister;
|
||||
use MetaModel;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Form block for choice of class attributes.
|
||||
@@ -43,24 +44,32 @@ class AttributeChoiceFormBlock extends ChoiceFormBlock
|
||||
$oIORegister->AddOutput(self::OUTPUT_ATTRIBUTE, AttributeIOFormat::class, new StringToAttributeConverter());
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
/**
|
||||
* @param \Combodo\iTop\Forms\Register\OptionsRegister $oOptionsRegister
|
||||
*
|
||||
* @throws \Combodo\iTop\DependencyInjection\DIException
|
||||
* @throws \Combodo\iTop\Forms\Block\FormBlockException
|
||||
* @throws \Combodo\iTop\Forms\Register\RegisterException
|
||||
*/
|
||||
public function UpdateOptions(OptionsRegister $oOptionsRegister): void
|
||||
{
|
||||
parent::UpdateOptions($oOptionsRegister);
|
||||
|
||||
$oClass = $this->GetInputValue(self::INPUT_CLASS_NAME);
|
||||
$sClass = strval($this->GetInputValue(self::INPUT_CLASS_NAME));
|
||||
|
||||
if ($oClass === null) {
|
||||
if (utils::IsNullOrEmptyString($sClass)) {
|
||||
$oOptionsRegister->SetOption('choices', []);
|
||||
return;
|
||||
}
|
||||
|
||||
$aAttributeCodes = MetaModel::GetAttributesList($oClass);
|
||||
/** @var \ModelReflection $oModelReflection */
|
||||
$oModelReflection = DIService::GetInstance()->GetService('ModelReflection');
|
||||
$aAttributeCodes = array_keys($oModelReflection->ListAttributes($sClass));
|
||||
|
||||
$aAttributes = [];
|
||||
foreach ($aAttributeCodes as $sAttributeCode) {
|
||||
$oAttribute = MetaModel::GetAttributeDef(strval($oClass), $sAttributeCode);
|
||||
$aAttributes[$oAttribute->GetLabel()] = $sAttributeCode;
|
||||
foreach ($aAttributeCodes as $sAttCode) {
|
||||
$oAttribute =$oModelReflection->GetLabel($sClass, $sAttCode);
|
||||
$aAttributes[$oAttribute->GetLabel()] = $sAttCode;
|
||||
}
|
||||
|
||||
$oOptionsRegister->SetOption('choices', $aAttributes);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\DataModel;
|
||||
|
||||
use Combodo\iTop\DependencyInjection\DIService;
|
||||
use Combodo\iTop\Forms\Block\Base\ChoiceFormBlock;
|
||||
use Combodo\iTop\Forms\Block\FormBlockException;
|
||||
use Combodo\iTop\Forms\IO\Format\AttributeIOFormat;
|
||||
@@ -15,7 +16,6 @@ use Combodo\iTop\Forms\IO\Format\RawFormat;
|
||||
use Combodo\iTop\Forms\Register\IORegister;
|
||||
use Combodo\iTop\Forms\Register\OptionsRegister;
|
||||
use Exception;
|
||||
use MetaModel;
|
||||
|
||||
/**
|
||||
* Form block for choice of class attribute values.
|
||||
@@ -56,12 +56,13 @@ class AttributeValueChoiceFormBlock extends ChoiceFormBlock
|
||||
{
|
||||
parent::UpdateOptions($oOptionsRegister);
|
||||
|
||||
$oClassName = $this->GetInputValue(self::INPUT_CLASS_NAME);
|
||||
$oAttribute = $this->GetInputValue(self::INPUT_ATTRIBUTE);
|
||||
$sClass = strval($this->GetInputValue(self::INPUT_CLASS_NAME));
|
||||
$sAttCode = strval($this->GetInputValue(self::INPUT_ATTRIBUTE));
|
||||
|
||||
try {
|
||||
$oAttDef = MetaModel::GetAttributeDef(strval($oClassName), strval($oAttribute));
|
||||
$aValues = $oAttDef->GetAllowedValues();
|
||||
/** @var \ModelReflection $oModelReflection */
|
||||
$oModelReflection = DIService::GetInstance()->GetService('ModelReflection');
|
||||
$aValues = $oModelReflection->GetAllowedValues_att($sClass, $sAttCode);
|
||||
|
||||
$oOptionsRegister->SetOption('choices', array_flip($aValues ?? []));
|
||||
} catch (Exception $e) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
namespace Combodo\iTop\Forms\IO;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Combodo\iTop\Forms\IO\Format\AbstractIOFormat;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
|
||||
/**
|
||||
@@ -43,6 +44,9 @@ class AbstractFormIO
|
||||
*/
|
||||
public function __construct(string $sName, string $sType, AbstractFormBlock $oOwnerBlock)
|
||||
{
|
||||
if (!is_a($sType, AbstractIOFormat::class, true)) {
|
||||
throw new FormBlockIOException('invalid form format type '.json_encode($sType).' given');
|
||||
}
|
||||
$this->sType = $sType;
|
||||
$this->oOwnerBlock = $oOwnerBlock;
|
||||
$this->SetName($sName);
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\IO\Converter;
|
||||
|
||||
use Combodo\iTop\DependencyInjection\DIService;
|
||||
use Combodo\iTop\Forms\IO\Format\ClassIOFormat;
|
||||
use Combodo\iTop\Forms\IO\FormBlockIOException;
|
||||
use MetaModel;
|
||||
|
||||
/**
|
||||
* OQL expression to class converter.
|
||||
@@ -18,6 +18,7 @@ class OqlToClassConverter extends AbstractConverter
|
||||
{
|
||||
/** @inheritdoc
|
||||
* @throws \Combodo\iTop\Forms\IO\FormBlockIOException
|
||||
* @throws \Combodo\iTop\DependencyInjection\DIException
|
||||
*/
|
||||
public function Convert(mixed $oData): ?ClassIOFormat
|
||||
{
|
||||
@@ -31,7 +32,9 @@ class OqlToClassConverter extends AbstractConverter
|
||||
// Selected class
|
||||
if (isset($aMatches[1])) {
|
||||
$sSelectedClass = $aMatches[1];
|
||||
if (!MetaModel::IsValidClass($sSelectedClass)) {
|
||||
/** @var \ModelReflection $oModelReflection */
|
||||
$oModelReflection = DIService::GetInstance()->GetService('ModelReflection');
|
||||
if (!$oModelReflection->IsValidClass($sSelectedClass)) {
|
||||
throw new FormBlockIOException('Class '.json_encode($sSelectedClass).' not found');
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,12 @@ class FormBinding
|
||||
*/
|
||||
public function __construct(AbstractFormIO $oSourceIO, AbstractFormIO $oDestinationIO)
|
||||
{
|
||||
// Check IOFormat validity
|
||||
$sSourceDataType = $oSourceIO->GetDataType();
|
||||
$sDestinationDataType = $oDestinationIO->GetDataType();
|
||||
if (!$sSourceDataType::IsCompatible($sDestinationDataType)) {
|
||||
throw new FormBlockIOException('binding '.json_encode($sSourceDataType).' to '.json_encode($sDestinationDataType).' is not supported');
|
||||
}
|
||||
$this->oDestinationIO = $oDestinationIO;
|
||||
$this->oSourceIO = $oSourceIO;
|
||||
$oDestinationIO->Attach($this);
|
||||
|
||||
16
sources/Forms/IO/Format/AbstractIOFormat.php
Normal file
16
sources/Forms/IO/Format/AbstractIOFormat.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SAS
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Forms\IO\Format;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
abstract class AbstractIOFormat implements JsonSerializable
|
||||
{
|
||||
abstract public function jsonSerialize(): mixed;
|
||||
|
||||
abstract public static function IsCompatible(string $sOtherFormatClass): bool;
|
||||
}
|
||||
@@ -2,9 +2,8 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\IO\Format;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
class AttributeIOFormat implements JsonSerializable
|
||||
class AttributeIOFormat extends AbstractIOFormat
|
||||
{
|
||||
public string $sAttributeName;
|
||||
|
||||
@@ -23,4 +22,9 @@ class AttributeIOFormat implements JsonSerializable
|
||||
{
|
||||
return $this->sAttributeName;
|
||||
}
|
||||
|
||||
public static function IsCompatible(string $sOtherFormatClass): bool
|
||||
{
|
||||
return is_a($sOtherFormatClass, AttributeIOFormat::class, true) || is_a($sOtherFormatClass, RawFormat::class, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,7 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\IO\Format;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
class BooleanIOFormat implements JsonSerializable
|
||||
class BooleanIOFormat extends AbstractIOFormat
|
||||
{
|
||||
public bool $bValue;
|
||||
|
||||
@@ -32,4 +30,9 @@ class BooleanIOFormat implements JsonSerializable
|
||||
{
|
||||
return $this->bValue;
|
||||
}
|
||||
|
||||
public static function IsCompatible(string $sOtherFormatClass): bool
|
||||
{
|
||||
return is_a($sOtherFormatClass, BooleanIOFormat::class, true) || is_a($sOtherFormatClass, RawFormat::class, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,26 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\IO\Format;
|
||||
|
||||
use JsonSerializable;
|
||||
use Combodo\iTop\DependencyInjection\DIService;
|
||||
use Combodo\iTop\Forms\IO\FormBlockIOException;
|
||||
|
||||
class ClassIOFormat implements JsonSerializable
|
||||
class ClassIOFormat extends AbstractIOFormat
|
||||
{
|
||||
public string $sClassName;
|
||||
|
||||
/**
|
||||
* @throws \Combodo\iTop\DependencyInjection\DIException
|
||||
* @throws \Combodo\iTop\Forms\IO\FormBlockIOException
|
||||
*/
|
||||
public function __construct(string $sClassName)
|
||||
{
|
||||
// Check class validity
|
||||
/** @var \ModelReflection $oModelReflection */
|
||||
$oModelReflection = DIService::GetInstance()->GetService('ModelReflection');
|
||||
if (!$oModelReflection->IsValidClass($sClassName)) {
|
||||
throw new FormBlockIOException("Class ".json_encode($sClassName)." is not valid");
|
||||
}
|
||||
$this->sClassName = $sClassName;
|
||||
// validation du format sinon exception
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
@@ -23,4 +33,9 @@ class ClassIOFormat implements JsonSerializable
|
||||
{
|
||||
return $this->sClassName;
|
||||
}
|
||||
|
||||
public static function IsCompatible(string $sOtherFormatClass): bool
|
||||
{
|
||||
return is_a($sOtherFormatClass, ClassIOFormat::class, true) || is_a($sOtherFormatClass, RawFormat::class, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,27 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\IO\Format;
|
||||
|
||||
class NumberIOFormat
|
||||
class NumberIOFormat extends AbstractIOFormat
|
||||
{
|
||||
public mixed $oValue;
|
||||
|
||||
public function __construct(string $oValue)
|
||||
{
|
||||
$this->oValue = $oValue;
|
||||
// validation du format sinon exception
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->oValue;
|
||||
return strval($this->oValue);
|
||||
}
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return strval($this->oValue);
|
||||
}
|
||||
|
||||
public static function IsCompatible(string $sOtherFormatClass): bool
|
||||
{
|
||||
return is_a($sOtherFormatClass, NumberIOFormat::class, true) || is_a($sOtherFormatClass, RawFormat::class, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,27 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\IO\Format;
|
||||
|
||||
class RawFormat
|
||||
class RawFormat extends AbstractIOFormat
|
||||
{
|
||||
public string $sValue;
|
||||
|
||||
public function __construct(string $sValue)
|
||||
{
|
||||
$this->sValue = $sValue;
|
||||
// validation du format sinon exception
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return strval($this->sValue);
|
||||
return $this->sValue;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return $this->sValue;
|
||||
}
|
||||
|
||||
public static function IsCompatible(string $sOtherFormatClass): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ class AbstractFormIOTest extends AbstractFormsTest
|
||||
public function NameFormatSupportsOnlyLettersUnderscoreAndNumbersProvider()
|
||||
{
|
||||
return [
|
||||
// Incorrects
|
||||
'Spaces not supported' => ['The test name'],
|
||||
'Minus not supported' => ['The-test-name'],
|
||||
'Percent not supported' => ['name%'],
|
||||
@@ -94,4 +95,9 @@ class AbstractFormIOTest extends AbstractFormsTest
|
||||
];
|
||||
}
|
||||
|
||||
public function testCreatingIOWithUnknownFormatThrowsException()
|
||||
{
|
||||
$this->expectException(FormBlockIOException::class);
|
||||
$oInput = $this->GivenInput('test', 'test_toto');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
|
||||
namespace Combodo\iTop\Test\UnitTest\Forms\IO;
|
||||
|
||||
use Combodo\iTop\Forms\IO\Format\AttributeIOFormat;
|
||||
use Combodo\iTop\Forms\IO\Format\BooleanIOFormat;
|
||||
use Combodo\iTop\Forms\IO\Format\ClassIOFormat;
|
||||
use Combodo\iTop\Forms\IO\Format\NumberIOFormat;
|
||||
use Combodo\iTop\Forms\IO\Format\RawFormat;
|
||||
use Combodo\iTop\Forms\IO\FormBinding;
|
||||
use Combodo\iTop\Forms\IO\FormBlockIOException;
|
||||
use Combodo\iTop\Test\UnitTest\sources\Forms\AbstractFormsTest;
|
||||
@@ -148,6 +153,84 @@ class FormBindingTest extends AbstractFormsTest
|
||||
|
||||
// Then
|
||||
$this->assertEquals('The Value', $oOutputIO1->GetValue(FormEvents::PRE_SET_DATA));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider BindingIncompatibleFormatsProvider
|
||||
*
|
||||
* @param string $sSourceFormat
|
||||
* @param string $sDestinationFormat
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBindingIncompatibleFormatsThrowsException(string $sSourceFormat, string $sDestinationFormat)
|
||||
{
|
||||
$oOutputIO = $this->GivenOutput('test', $sSourceFormat);
|
||||
$oInputIO = $this->GivenInput('test', $sDestinationFormat);
|
||||
|
||||
$this->expectException(FormBlockIOException::class);
|
||||
$oOutputIO->BindToInput($oInputIO);
|
||||
}
|
||||
|
||||
public function BindingIncompatibleFormatsProvider(): array
|
||||
{
|
||||
return [
|
||||
'Attribute -> Boolean' => [AttributeIOFormat::class, BooleanIOFormat::class],
|
||||
'Attribute -> Class' => [AttributeIOFormat::class, ClassIOFormat::class],
|
||||
'Attribute -> Number' => [AttributeIOFormat::class, NumberIOFormat::class],
|
||||
|
||||
'Boolean => Attribute' => [BooleanIOFormat::class, AttributeIOFormat::class],
|
||||
'Boolean => Class' => [BooleanIOFormat::class, ClassIOFormat::class],
|
||||
'Boolean => Number' => [BooleanIOFormat::class, NumberIOFormat::class],
|
||||
|
||||
'Class => Attribute' => [ClassIOFormat::class, AttributeIOFormat::class],
|
||||
'Class => Boolean' => [ClassIOFormat::class, BooleanIOFormat::class],
|
||||
'Class => Number' => [ClassIOFormat::class, NumberIOFormat::class],
|
||||
|
||||
'Number => Attribute' => [NumberIOFormat::class, AttributeIOFormat::class],
|
||||
'Number => Class' => [NumberIOFormat::class, ClassIOFormat::class],
|
||||
'Number => Boolean' => [NumberIOFormat::class, BooleanIOFormat::class],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider BindingCompatibleFormatsProvider
|
||||
*
|
||||
* @param string $sSourceFormat
|
||||
* @param string $sDestinationFormat
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testBindingCompatibleFormatsWorks(string $sSourceFormat, string $sDestinationFormat)
|
||||
{
|
||||
$oOutputIO = $this->GivenOutput('test', $sSourceFormat);
|
||||
$oInputIO = $this->GivenInput('test', $sDestinationFormat);
|
||||
|
||||
$oBinding = $oOutputIO->BindToInput($oInputIO);
|
||||
$this->assertTrue(is_a($oBinding, FormBinding::class));
|
||||
}
|
||||
|
||||
public function BindingCompatibleFormatsProvider(): array
|
||||
{
|
||||
return [
|
||||
'Attribute -> Attribute' => [AttributeIOFormat::class, AttributeIOFormat::class],
|
||||
'Attribute -> Raw' => [AttributeIOFormat::class, RawFormat::class],
|
||||
|
||||
'Boolean => Boolean' => [BooleanIOFormat::class, BooleanIOFormat::class],
|
||||
'Boolean => Raw' => [BooleanIOFormat::class, RawFormat::class],
|
||||
|
||||
'Class => Class' => [ClassIOFormat::class, ClassIOFormat::class],
|
||||
'Class => Raw' => [ClassIOFormat::class, RawFormat::class],
|
||||
|
||||
'Number => Number' => [NumberIOFormat::class, NumberIOFormat::class],
|
||||
'Number => Raw' => [NumberIOFormat::class, RawFormat::class],
|
||||
|
||||
'Raw => Raw' => [RawFormat::class, RawFormat::class],
|
||||
'Raw => Attribute' => [RawFormat::class, AttributeIOFormat::class],
|
||||
'Raw => Boolean' => [RawFormat::class, BooleanIOFormat::class],
|
||||
'Raw => Class' => [RawFormat::class, ClassIOFormat::class],
|
||||
'Raw => Number' => [RawFormat::class, NumberIOFormat::class],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user