Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7cd5e25
Permit to Inject GlpiAsset
tsmr May 7, 2026
5a3c6ef
Add forget files
tsmr May 7, 2026
269e08a
Fix php-stan, php-cs-fixer fix, rector
tsmr Jul 21, 2026
0ba9457
Merge branch 'main' into InjectGlpiAsset
tsmr Jul 21, 2026
ed80738
Update header
tsmr Jul 21, 2026
8c4e3f5
Merge branch 'InjectGlpiAsset' of https://github.com/InfotelGLPI/data…
tsmr Jul 21, 2026
33fffc8
Fix reactor
tsmr Jul 21, 2026
730276d
Other fix phpstan
tsmr Jul 21, 2026
1723053
Update ChangeLog & .php-cs-fixer.php
tsmr Jul 21, 2026
612f0d5
Add new feature inject Asset test
tsmr Jul 27, 2026
a8181fe
Merge branch 'pluginsGLPI:main' into InjectGlpiAsset
tsmr Aug 17, 2026
99bbe17
Update src/Glpi/Asset/AssetInjection.php
tsmr Aug 17, 2026
bf37ab3
Update src/Glpi/Asset/AssetInjection.php
tsmr Aug 17, 2026
b3ffc43
Update src/Glpi/Asset/AssetInjection.php
tsmr Aug 17, 2026
f4cb5f8
Update src/Glpi/Asset/AssetInjection.php
tsmr Aug 17, 2026
d8c459c
Update setup.php
tsmr Aug 19, 2026
336c563
Update setup.php
tsmr Aug 19, 2026
452f6ed
Update src/Glpi/Asset/AssetInjection.php
tsmr Aug 19, 2026
d531a7f
Update setup.php
tsmr Aug 19, 2026
8d5fc51
Clean files
tsmr Aug 19, 2026
f26f408
Fix install
tsmr Aug 19, 2026
99a1718
Add fixes
tsmr Aug 19, 2026
bab3a11
Fix Rector
tsmr Aug 19, 2026
71dbc6f
Update src/Glpi/Asset/AssetInjection.php
tsmr Sep 18, 2026
7824b37
Merge branch 'pluginsGLPI:main' into InjectGlpiAsset
tsmr Oct 23, 2026
a90111a
Merge branch 'main' into InjectGlpiAsset
tsmr Oct 23, 2026
d5bf7b4
Update PR for CI
tsmr Oct 23, 2026
24f0ddc
Merge branch 'InjectGlpiAsset' of https://github.com/InfotelGLPI/data…
tsmr Oct 23, 2026
c710e1e
Add custom fields
tsmr Oct 23, 2026
d2d16c0
Merge branch 'main' into InjectGlpiAsset
tsmr Oct 23, 2026
aa063e5
Update setup.php
tsmr Oct 23, 2026
638590f
Update CHANGELOG.md
tsmr Oct 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Added

- Add Transifex translations link to README
- Permit to Inject GlpiAsset

## [2.16.0] - 2026-10-05

Expand Down
2 changes: 0 additions & 2 deletions front/info.form.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
* -------------------------------------------------------------------------
*/

Session::checkLoginUser();

/* Update mappings */
if (isset($_POST["update"])) {
$model = new PluginDatainjectionModel();
Expand Down
2 changes: 0 additions & 2 deletions front/model.form.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
* -------------------------------------------------------------------------
*/

Session::checkLoginUser();

$_GET["id"] ??= "";

$_GET["withtemplate"] ??= "";
Expand Down
1 change: 0 additions & 1 deletion front/model.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
* -------------------------------------------------------------------------
*/

Session::checkLoginUser();

Html::header(
PluginDatainjectionModel::getTypeName(),
Expand Down
2 changes: 0 additions & 2 deletions front/popup.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
* -------------------------------------------------------------------------
*/

Session::checkLoginUser();

switch ($_GET["popup"]) {
case "preview":
$models_id = (int) ($_GET['models_id'] ?? 0);
Expand Down
41 changes: 36 additions & 5 deletions inc/commoninjectionlib.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@
* @link https://github.com/pluginsGLPI/datainjection
* -------------------------------------------------------------------------
*/

use Glpi\Asset\Asset;
use Glpi\DBAL\QueryExpression;
use Glpi\DBAL\QuerySubQuery;
use Glpi\Exception\Http\HttpException;
use Glpi\Features\AssignableItem;
use GlpiPlugin\Datainjection\Glpi\Asset\AssetInjection;

use function Safe\preg_match;
use function Safe\preg_replace;
Expand Down Expand Up @@ -356,6 +357,15 @@ public static function getItemtypeByInjection($injectionClassName)
public static function getItemtypeByInjectionClass($injectionClass)
{

if ($injectionClass instanceof AssetInjection) {
// Custom assets all share the "glpi_assets_assets" table, whose canonical
// itemtype is the *abstract* Glpi\Asset\Asset. Resolving through the table
// (getItemTypeForTable) is therefore unreliable and can return that abstract
// class, which is not instantiable. The injection class already knows its
// concrete custom-asset itemtype, so use it directly.
return $injectionClass::getVirtualType();
}

return Toolbox::ucfirst(getItemTypeForTable($injectionClass->getTable()));
}

Expand All @@ -365,7 +375,10 @@ public static function getItemtypeByInjectionClass($injectionClass)
*
* @param string $itemtype the itemtype
*
* @return PluginDatainjectionInjectionInterface the injection class instance
* Every injection class both implements the interface and extends CommonDBTM,
* so the returned instance exposes the CommonDBTM API (getTable(), ...) too.
*
* @return PluginDatainjectionInjectionInterface&CommonDBTM the injection class instance
*/
public static function getInjectionClassInstance($itemtype)
{
Expand All @@ -377,7 +390,15 @@ public static function getInjectionClassInstance($itemtype)
$injectionClass = ucfirst($itemtype) . 'Injection';
}

if (!is_a($injectionClass, PluginDatainjectionInjectionInterface::class, true)) {
if (!class_exists($injectionClass)) {
plugin_datainjection_creationInjectableAssets();
}


if (
!is_a($injectionClass, PluginDatainjectionInjectionInterface::class, true)
|| !is_a($injectionClass, CommonDBTM::class, true)
) {
throw new HttpException(500, 'Class ' . $injectionClass . ' is not a valid class');
}

Expand Down Expand Up @@ -626,7 +647,8 @@ private function getFieldValue(

case 'dropdown':
case 'relation':
$tmptype = getItemTypeForTable($searchOption['table']);
// Custom dropdowns share one table: their itemtype cannot be resolved from it
$tmptype = $searchOption['dropdown_itemtype'] ?? getItemTypeForTable($searchOption['table']);
if (!is_a($tmptype, CommonDBTM::class, true)) {
return;
}
Expand Down Expand Up @@ -2145,6 +2167,10 @@ private function dataAlreadyInDB($injectionClass, $itemtype)
}
}

if ($injectionClass instanceof Asset && method_exists($injectionClass, 'getAssetDefinitionID')) {
$where['assets_assetdefinitions_id'] = $injectionClass->getAssetDefinitionID();
}

//Add additional parameters specific to this itemtype (or function checkPresent exists)
if (method_exists($injectionClass, 'checkPresent')) {
$extra = $injectionClass->checkPresent($this->values, $options);
Expand Down Expand Up @@ -2447,8 +2473,13 @@ public static function addToSearchOptions(
);

$main_itemtype = self::getItemtypeByInjectionClass($injectionClass);
$main_table = getTableForItemType($main_itemtype);
foreach ($type_searchOptions as &$value) {
$value_itemtype = getItemTypeForTable($value['table']);
$value_itemtype = $value['table'] === $main_table
// Custom assets share a table resolved to the abstract Glpi\Asset\Asset,
// whose getTypeName() needs a concrete definition
? $main_itemtype
: getItemTypeForTable($value['table']);
$value_itemtype_name_singular = $value_itemtype::getTypeName(1);
$value_itemtype_name_plural = $value_itemtype::getTypeName(Session::getPluralNumber());
if (
Expand Down
2 changes: 1 addition & 1 deletion inc/info.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ public static function showAdditionalInformation(
}

Dropdown::show(
getItemTypeForTable($option['table']),
$option['dropdown_itemtype'] ?? getItemTypeForTable($option['table']),
['name' => $name,
'value' => $value,
],
Expand Down
8 changes: 7 additions & 1 deletion inc/injectiontype.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* -------------------------------------------------------------------------
*/
use Glpi\Exception\Http\HttpException;
use GlpiPlugin\Datainjection\Glpi\Asset\AssetInjection;

use function Safe\json_decode;
use function Safe\json_encode;
Expand Down Expand Up @@ -80,6 +81,11 @@ public static function getItemtypes($only_primary = false)
}

$name .= call_user_func([$type, 'getTypeName']);

if ($instance instanceof AssetInjection) {
$typename = $instance->getVirtualType();
}

$values[$typename] = $name;
}
}
Expand Down Expand Up @@ -396,7 +402,7 @@ public static function getUsedMappingsOrInfos($options = [])
foreach ($options as $option) {
if (
isset($option['table'])
&& ($option['table'] == getItemTypeForTable($data['itemtype']))
&& ($option['table'] == $injectionClass->getTable())
&& ($option['linkfield'] == $data['value'])
&& ($option['displaytype'] != 'multiline_text')
&& ($mapping_or_info['value'] != $data['value'])
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ parameters:
- ajax
- front
- inc
- src
- hook.php
- setup.php
scanDirectories:
Expand Down
120 changes: 118 additions & 2 deletions setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,13 @@
* -------------------------------------------------------------------------
*/

use Glpi\Asset\AssetDefinition;
use Glpi\Asset\AssetDefinitionManager;
use GlpiPlugin\Datainjection\Glpi\Asset\Capacity\IsInjectableCapacity;

use function Safe\define;
use function Safe\mkdir;
use function Safe\preg_match;

define('PLUGIN_DATAINJECTION_VERSION', '2.16.0');

Expand All @@ -48,6 +53,10 @@ function plugin_init_datainjection()
/** @var array $CFG_GLPI */
/** @var array $INJECTABLE_TYPES */
global $PLUGIN_HOOKS, $CFG_GLPI, $INJECTABLE_TYPES;
$CFG_GLPI['injectable_types'] ??= [];

$asset_definition_manager = AssetDefinitionManager::getInstance();
$asset_definition_manager->registerCapacity(new IsInjectableCapacity());

$PLUGIN_HOOKS['csrf_compliant']['datainjection'] = true;
$PLUGIN_HOOKS['migratetypes']['datainjection'] = 'plugin_datainjection_migratetypes_datainjection';
Expand Down Expand Up @@ -85,6 +94,7 @@ function plugin_init_datainjection()
$PLUGIN_HOOKS['add_javascript']['datainjection'] = 'js/datainjection.js';

$INJECTABLE_TYPES = [];

}
}

Expand Down Expand Up @@ -114,8 +124,8 @@ function plugin_version_datainjection()
function getTypesToInject(): void
{
/** @var array $INJECTABLE_TYPES */
/** @var array $PLUGIN_HOOKS */
global $INJECTABLE_TYPES,$PLUGIN_HOOKS;
/** @var array $CFG_GLPI */
global $INJECTABLE_TYPES,$CFG_GLPI;

if (count($INJECTABLE_TYPES)) {
// already populated
Expand Down Expand Up @@ -218,6 +228,112 @@ function getTypesToInject(): void
];
//Add plugins
Plugin::doHook('plugin_datainjection_populate');

// Register injectable assets dynamically
plugin_datainjection_registerInjectableAssets();

plugin_datainjection_creationInjectableAssets();
}


/**
* Register injection classes for each injectable asset definition
*/
function plugin_datainjection_registerInjectableAssets(): void
{
/** @var array $INJECTABLE_TYPES */
/** @var array $CFG_GLPI */
global $INJECTABLE_TYPES, $CFG_GLPI;

if (!isset($CFG_GLPI['injectable_types']) || empty($CFG_GLPI['injectable_types'])) {
return;
}

// For each injectable asset definition, create and register a distinct class
foreach ($CFG_GLPI['injectable_types'] as $definition_id => $itemtype) {
// Get the asset definition to extract the system name

$definition = AssetDefinition::getById($definition_id);
if ($definition === false || $definition === null) {
continue;
}

if ($definition->getAssetClassName() === $itemtype) {
Comment thread
tsmr marked this conversation as resolved.
// Use the system name to create a nice class name
$system_name = ucfirst($definition->fields['system_name']);
$injection_class = 'PluginDatainjection' . $system_name . 'AssetInjection';
// Only create if not already registered
$INJECTABLE_TYPES[$injection_class] ??= 'datainjection';
}
}
}

/**
* Register injection classes for each injectable asset definition
*/
function plugin_datainjection_creationInjectableAssets(): void
{
/** @var array $CFG_GLPI */
global $CFG_GLPI;

if (!isset($CFG_GLPI['injectable_types']) || empty($CFG_GLPI['injectable_types'])) {
return;
}


// For each injectable asset definition, create and register a distinct class
foreach ($CFG_GLPI['injectable_types'] as $definition_id => $itemtype) {
$definition = AssetDefinition::getById($definition_id);
if ($definition === false) {
continue;
}

// Get the asset definition to extract the system name
if ($definition->getAssetClassName() === $itemtype) {
Comment thread
tsmr marked this conversation as resolved.
// Use the system name to create a nice class name
$system_name = ucfirst($definition->fields['system_name']);//strtolower()
$injection_class = 'PluginDatainjection' . $system_name . 'AssetInjection';

plugin_datainjection_createAssetInjectionClass($injection_class, $definition_id);
}
}
}

/**
* Dynamically create an asset injection class
*/
function plugin_datainjection_createAssetInjectionClass(string $class_name, int $definition_id): void
{

// Check if class already exists
if (class_exists($class_name)) {
return;
}

// Create the class dynamically (not final, so it can be extended)
$code = <<<PHP

use GlpiPlugin\\Datainjection\\Glpi\\Asset\\AssetInjection;

final class $class_name extends AssetInjection implements PluginDatainjectionInjectionInterface
{
// Redeclared: a static property of the parent class would be shared by every definition
protected static string \$definition_system_name = '';
protected static int \$fixed_asset_definition_id = $definition_id;

public static function getAssetDefinitionID(): int
{
return self::\$fixed_asset_definition_id;
}
}
PHP;

if (preg_match('/^[A-Za-z][A-Za-z0-9_]*$/', $class_name) === 0) {
return;
}

eval($code);
Comment thread
tsmr marked this conversation as resolved.

}


Expand Down
Loading
Loading