mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-20 00:58:48 +02:00
Add Icon selection formBlock
This commit is contained in:
@@ -89,9 +89,17 @@ abstract class ModelReflection
|
||||
* @param string $defaultValue
|
||||
*
|
||||
* @return \RunTimeIconSelectionField
|
||||
* @deprecated since 3.3.0 replaced by GetAvailableIcons
|
||||
*/
|
||||
abstract public function GetIconSelectionField($sCode, $sLabel = '', $defaultValue = '');
|
||||
|
||||
/**
|
||||
* Find available icons for the current context
|
||||
*
|
||||
* @return array of ['value', 'label', 'icon'] where 'value' is the relative path on disk, 'label' the name to display and 'icon' is the URL to get the image
|
||||
*/
|
||||
abstract public function GetAvailableIcons(): array;
|
||||
|
||||
abstract public function GetRootClass($sClass);
|
||||
abstract public function EnumChildClasses($sClass, $iOption = ENUM_CHILD_CLASSES_EXCLUDETOP);
|
||||
}
|
||||
@@ -109,6 +117,8 @@ abstract class QueryReflection
|
||||
|
||||
class ModelReflectionRuntime extends ModelReflection
|
||||
{
|
||||
private static array $aAllIcons = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
@@ -255,6 +265,52 @@ class ModelReflectionRuntime extends ModelReflection
|
||||
return new RunTimeIconSelectionField($sCode, $sLabel, $defaultValue);
|
||||
}
|
||||
|
||||
public function GetAvailableIcons(): array
|
||||
{
|
||||
$aFolderList = [
|
||||
APPROOT.'env-'.utils::GetCurrentEnvironment() => utils::GetAbsoluteUrlModulesRoot(),
|
||||
APPROOT.'images/icons' => utils::GetAbsoluteUrlAppRoot().'images/icons',
|
||||
];
|
||||
if (count(self::$aAllIcons) == 0) {
|
||||
foreach ($aFolderList as $sFolderPath => $sUrlPrefix) {
|
||||
$aIcons = self::FindIconsOnDisk($sFolderPath);
|
||||
ksort($aIcons);
|
||||
|
||||
foreach ($aIcons as $sFilePath) {
|
||||
self::$aAllIcons[] = ['value' => $sFilePath, 'label' => basename($sFilePath), 'icon' => $sUrlPrefix.$sFilePath];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self::$aAllIcons;
|
||||
}
|
||||
|
||||
private static function FindIconsOnDisk(string $sBaseDir, string $sDir = '', array &$aFilesSpecs = []): array
|
||||
{
|
||||
$aResult = [];
|
||||
// Populate automatically the list of icon files
|
||||
if ($hDir = @opendir($sBaseDir.'/'.$sDir)) {
|
||||
while (($sFile = readdir($hDir)) !== false) {
|
||||
$aMatches = [];
|
||||
if (($sFile != '.') && ($sFile != '..') && ($sFile != 'lifecycle') && is_dir($sBaseDir.'/'.$sDir.'/'.$sFile)) {
|
||||
$sDirSubPath = ($sDir == '') ? $sFile : $sDir.'/'.$sFile;
|
||||
$aResult = array_merge($aResult, self::FindIconsOnDisk($sBaseDir, $sDirSubPath, $aFilesSpecs));
|
||||
}
|
||||
$sSize = filesize($sBaseDir.'/'.$sDir.'/'.$sFile);
|
||||
if (isset($aFilesSpecs[$sFile]) && $aFilesSpecs[$sFile] == $sSize) {
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/\.(png|jpg|jpeg|gif|svg)$/i', $sFile, $aMatches)) { // png, jp(e)g, gif and svg are considered valid
|
||||
$aResult[$sFile.'_'.$sDir] = $sDir.'/'.$sFile;
|
||||
$aFilesSpecs[$sFile] = $sSize;
|
||||
}
|
||||
}
|
||||
closedir($hDir);
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
public function GetRootClass($sClass)
|
||||
{
|
||||
return MetaModel::GetRootClass($sClass);
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
|
||||
namespace Combodo\iTop\PropertyType\ValueType\Leaf;
|
||||
|
||||
use Combodo\iTop\DesignElement;
|
||||
use Combodo\iTop\Forms\Block\Base\ChoiceFormBlock;
|
||||
use Combodo\iTop\PropertyType\ValueType\Branch\AbstractBranchValueType;
|
||||
use Combodo\iTop\Service\DependencyInjection\ServiceLocator;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* @since 3.3.0
|
||||
@@ -18,4 +22,26 @@ class ValueTypeIcon extends AbstractLeafValueType
|
||||
{
|
||||
return ChoiceFormBlock::class;
|
||||
}
|
||||
|
||||
public function InitFromDomNode(DesignElement $oDomNode, ?AbstractBranchValueType $oParent = null): void
|
||||
{
|
||||
parent::InitFromDomNode($oDomNode, $oParent);
|
||||
|
||||
// Search icons in iTop and extensions
|
||||
/** @var \ModelReflection $oModelReflection */
|
||||
$oModelReflection = ServiceLocator::GetInstance()->get('ModelReflection');
|
||||
|
||||
$sChoices = "[\n";
|
||||
$aIcons = $oModelReflection->GetAvailableIcons();
|
||||
foreach ($aIcons as $aIcon) {
|
||||
$sValue = utils::QuoteForPHP($aIcon['label']);
|
||||
$sCode = utils::QuoteForPHP($aIcon['value']);
|
||||
$sChoices .= <<<PHP
|
||||
\t\t\t\t$sCode => $sValue,\n
|
||||
PHP;
|
||||
}
|
||||
$sChoices .= "\t\t\t]";
|
||||
|
||||
$this->aFormBlockOptionsForPHP['choices'] = $sChoices;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,6 +593,7 @@ abstract class ItopTestCase extends KernelTestCase
|
||||
{
|
||||
try {
|
||||
eval($sPHPCode);
|
||||
self::AssertTrue(true);
|
||||
} catch (ParseError $e) {
|
||||
$aLines = explode("\n", $sPHPCode);
|
||||
foreach ($aLines as $iLine => $sLine) {
|
||||
|
||||
@@ -849,4 +849,75 @@ XML,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function testCompileFormForIconSelection()
|
||||
{
|
||||
ServiceLocator::GetInstance()->RegisterService('ModelReflection', new ModelReflectionRuntime());
|
||||
|
||||
$sXMLContent = <<<XML
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<property_type id="basic_test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Combodo-PropertyType" xsi:noNamespaceSchemaLocation = "https://www.combodo.com/itop-schema/3.3">
|
||||
<extends>Dashlet</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<nodes>
|
||||
<node id="icon-selection" xsi:type="Combodo-ValueType-Icon">
|
||||
<label>Icon</label>
|
||||
</node>
|
||||
</nodes>
|
||||
</definition>
|
||||
</property_type>
|
||||
XML;
|
||||
|
||||
$sExpectedStart = <<<PHP
|
||||
class FormFor__basic_test extends Combodo\iTop\Forms\Block\Base\FormBlock
|
||||
{
|
||||
protected function BuildForm(): void
|
||||
{
|
||||
\$this->Add('icon-selection', 'Combodo\iTop\Forms\Block\Base\ChoiceFormBlock', [
|
||||
'label' => 'Icon',
|
||||
'choices' => [
|
||||
|
||||
PHP;
|
||||
|
||||
$sProducedPHP = PropertyTypeCompiler::GetInstance()->CompileFormFromXML($sXMLContent);
|
||||
|
||||
$this->AssertPHPCodeIsValid($sProducedPHP);
|
||||
$this->assertStringStartsWith($sExpectedStart, $sProducedPHP);
|
||||
}
|
||||
|
||||
public function testCompileFormForClassSelection()
|
||||
{
|
||||
ServiceLocator::GetInstance()->RegisterService('ModelReflection', new ModelReflectionRuntime());
|
||||
|
||||
$sXMLContent = <<<XML
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<property_type id="basic_test" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Combodo-PropertyType" xsi:noNamespaceSchemaLocation = "https://www.combodo.com/itop-schema/3.3">
|
||||
<extends>Dashlet</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<nodes>
|
||||
<node id="class-selection" xsi:type="Combodo-ValueType-Class">
|
||||
<label>Class</label>
|
||||
</node>
|
||||
</nodes>
|
||||
</definition>
|
||||
</property_type>
|
||||
XML;
|
||||
|
||||
$sExpectedStart = <<<PHP
|
||||
class FormFor__basic_test extends Combodo\iTop\Forms\Block\Base\FormBlock
|
||||
{
|
||||
protected function BuildForm(): void
|
||||
{
|
||||
\$this->Add('class-selection', 'Combodo\iTop\Forms\Block\Base\ChoiceFormBlock', [
|
||||
'label' => 'Class',
|
||||
'choices' => [
|
||||
|
||||
PHP;
|
||||
|
||||
$sProducedPHP = PropertyTypeCompiler::GetInstance()->CompileFormFromXML($sXMLContent);
|
||||
|
||||
$this->AssertPHPCodeIsValid($sProducedPHP);
|
||||
$this->assertStringStartsWith($sExpectedStart, $sProducedPHP);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user