Skip to content

Register active custom asset definitions as orderable itemtypes (GLPI 11)#574

Open
bygadd wants to merge 2 commits intopluginsGLPI:mainfrom
bygadd:fix/glpi11-custom-assets-and-generate-item
Open

Register active custom asset definitions as orderable itemtypes (GLPI 11)#574
bygadd wants to merge 2 commits intopluginsGLPI:mainfrom
bygadd:fix/glpi11-custom-assets-and-generate-item

Conversation

@bygadd
Copy link
Copy Markdown

@bygadd bygadd commented Apr 28, 2026

Summary

GLPI 11 introduced native custom assets defined via Setup → Asset definitions. The plugin's hardcoded $ORDER_TYPES array in plugin_init_order() does not include them, so custom asset classes never appear in the Item type dropdown when creating a new Product reference, making it impossible to order anything based on a custom asset definition.

This PR introduces a new Orderable capacity that admins enable per asset definition (Setup → Asset definitions → {asset} → Capacities). Asset classes whose definition has the capacity enabled — and for which the current user has read permission — are appended to $ORDER_TYPES.

Implementation notes

  • New PluginOrderOrderableCapacity class (extends \Glpi\Asset\Capacity\AbstractCapacity) with label, icon, description, and a usage count based on existing PluginOrderReference rows.
  • Capacity is registered against AssetDefinitionManager at plugin_init_order() time, after which active definitions are iterated and filtered.
  • Per-user permission is enforced via $class::canView(), which delegates to the asset's AssignableItem READ check plus the definition's is_active flag.
  • The class_exists() guard on \Glpi\Asset\AssetDefinitionManager makes the block a no-op on GLPI ≤ 10.x, preserving backward compatibility.
  • The existing AssignableItem handling from Fix generateitem massive action #560 already works correctly with custom asset classes once they are registered as orderable itemtypes — no changes to link.class.php are required.

Testing

Tested on GLPI 11.0.6, PHP 8.3, Order plugin 2.12.6 with a custom asset definition ("Електро Материали НН"):

Step Result
Orderable capacity appears in Capacities tab with proper label/icon/description
Capacity disabled → custom asset absent from Product reference Item type dropdown
Capacity enabled → custom asset appears, references can be created
Type and Model dropdowns populate via + 'Type' / + 'Model' class name convention
Order validation flow
Item delivery flow
Generate item massive action (form renders fully, submit works)
Reception flow, generated assets appear in corresponding Assets section
Native itemtypes (Computer, Monitor, Printer, Peripheral) verified unaffected

Checklist

  • I have performed a self-review of my code.
  • I have added tests (when available) that prove my fix is effective or that my feature works.
  • I have updated the CHANGELOG with a short functional description of the fix or new feature.
  • This change requires a documentation update.

@bygadd
Copy link
Copy Markdown
Author

bygadd commented Apr 28, 2026

Updated visual evidence — capacity-based design

Demonstrating the new capacity workflow on stock GLPI 11.0.6 with custom asset "Електро Материали НН".

1. The new Orderable capacity in Setup → Asset definitions → {asset} → Capacities (here shown enabled):

Screenshot 2026-04-28 at 12 37 06

2. Item type dropdown shows the custom asset once the capacity is enabled:

Screenshot 2026-04-28 at 12 38 59

3. Product reference can be created with the custom asset (Test reference, type Крива С, model 16A):

Screenshot 2026-04-28 at 12 40 08

4. Order item flow — adding the new reference to an order:

Screenshot 2026-04-28 at 12 41 16

5. Generate item massive action renders fully and submits:

Screenshot 2026-04-28 at 12 42 08

6. Generated assets in Item delivered tab (Waiting for delivery):

Screenshot 2026-04-28 at 12 41 42

7. After delivery — items reach Taken delivery state with serial numbers, visible in Associated items:

Screenshot 2026-04-28 at 12 43 40

Comment thread setup.php
Comment on lines +128 to +140

// Auto-register all active custom assets defined via Asset definitions (GLPI 11+)
if (class_exists(\Glpi\Asset\AssetDefinitionManager::class)) {
$asset_manager = \Glpi\Asset\AssetDefinitionManager::getInstance();
$asset_manager->bootDefinitions();
foreach ($asset_manager->getDefinitions(true) as $definition) {
$custom_asset_class = $definition->getAssetClassName();
if (!in_array($custom_asset_class, $ORDER_TYPES, true)) {
$ORDER_TYPES[] = $custom_asset_class;
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good start =)

However, the Order plugin should introduce an "Order" capability for the custom Asset, allowing this feature to be enabled or disabled on a per-asset basis.

Additionally, this functionality should verify the read permissions of the currently authenticated user for the specified custom Asset before proceeding.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review @stonebuzz, both points were spot on.

The branch has been updated (force-pushed to keep a single clean commit, 6f94427). Summary of the changes:

1. New Orderable capacityinc/orderablecapacity.class.php introduces PluginOrderOrderableCapacity extending \Glpi\Asset\Capacity\AbstractCapacity. Admins now toggle it per asset definition under Setup → Asset definitions → {asset} → Capacities. Provides label, icon (ti ti-shopping-cart), description, and a usage count based on existing PluginOrderReference rows.

2. setup.php filtering — registers the capacity with AssetDefinitionManager, then iterates active definitions and appends a class to $ORDER_TYPES only when:

  • the Orderable capacity is enabled on that definition, and
  • $class::canView() passes for the current user (which delegates to the asset's AssignableItem READ check + the definition's is_active flag).

End-to-end re-tested on GLPI 11.0.6 / PHP 8.3:

Scenario Result
Capacity appears in the Capacities tab with proper label/icon/description
Capacity disabled → custom asset is absent from Item type dropdown
Capacity enabled → custom asset appears, references can be created
Generate item massive action renders and submits
Items reach Taken delivery state, generated assets visible in Assets section
Native itemtypes (Computer, Monitor, Printer, etc.) unaffected

Also updated the PR description (top of this thread) and the CHANGELOG entry to reflect the new opt-in design.

Let me know if you'd like any adjustments — happy to iterate.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You must declare your capacity in order for it to appear in the list.

This should be done in the setup.php file using:

AssetDefinitionManager::getInstance()->registerCapacity(...)

In addition, when a capacity is disabled, the associated data must be properly cleaned from the database.

In particular, this concerns the glpi_plugins_orderorder_item table, which—if I recall correctly—stores the relationship between an asset and an order.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the follow-up @stonebuzz, the new commit 5fd0975 addresses the data cleanup point.

On registerCapacity() — small clarification: the current branch (6f94427 and now 5fd0975) already declares the capacity through \Glpi\Asset\AssetDefinitionManager::getInstance()->registerCapacity(...) in setup.php, so it appears in the Capacities tab on GLPI 11 asset definitions and the Orderable toggle is admin-controlled. The inline review thread above is anchored to the original ea13dd1 push (the auto-register block) which is no longer in the branch — that may be why it reads as if the registration is missing.

On the cleanup — implemented onCapacityDisabled() on PluginOrderOrderableCapacity. When an admin disables Orderable on a definition, the callback removes:

  • order line items in glpi_plugin_order_orders_items whose itemtype matches the disabled custom asset class;
  • product references in glpi_plugin_order_references whose itemtype matches the disabled custom asset class.

The cascade order matters: PluginOrderReference::pre_deleteItem() rejects deletion while a reference is still in use by orders_items, so child records are deleted before parents. Free-form references (PluginOrderReferenceFree) are intentionally left untouched as they carry no itemtype reference.

End-to-end tested on GLPI 11.0.6 / PHP 8.3 on two installations:

Scenario Result
Disable capacity → references and orders_items for the targeted class are removed
Native itemtypes (Computer, Monitor, Printer, …) are untouched
Other custom assets that still have the capacity enabled are untouched
Re-enabling restores the asset class in the Item type dropdown; new references and order items can be created
The capacity description shows the live "Used by N order references" count, surfaced in the GLPI confirmation dialog before disabling

Specifically on the second installation, disabling the capacity on a small custom asset definition while keeping a much larger one (~12k order line items, ~600 references) enabled left the larger one fully intact — confirming the targeted, per-class scope of the cleanup.

Happy to iterate further if you'd like adjustments.

…custom assets

Following review feedback on pluginsGLPI#574, replace the unconditional
auto-registration of all active custom asset definitions with an explicit,
admin-controlled opt-in via a new Orderable capacity:

- Introduce PluginOrderOrderableCapacity (extends \Glpi\Asset\Capacity\AbstractCapacity).
  Admins enable/disable it per asset definition under
  Setup -> Asset definitions -> {asset} -> Capacities. Provides label, icon,
  description, and a usage count based on existing PluginOrderReference rows.

- In plugin_init_order(), register the capacity with AssetDefinitionManager,
  then iterate active definitions and append the generated asset class to
  $ORDER_TYPES only when:
    1. the Orderable capacity is enabled on that definition, AND
    2. the current user passes $class::canView()
       (which delegates to the asset's AssignableItem READ check + is_active).

- The class_exists() guard preserves backward compatibility on GLPI <= 10.x.

End-to-end tested on GLPI 11.0.6, PHP 8.3, Order plugin 2.12.6:
- Capacity appears in the Capacities tab with proper label/icon/description.
- With capacity disabled: custom asset is absent from the Item type dropdown.
- With capacity enabled: custom asset appears, references can be created,
  Generate item massive action renders and submits, items reach Taken
  delivery state, and generated assets appear in the Assets section.
- Native itemtypes remain unaffected.

Addresses review comments from @stonebuzz on pluginsGLPI#574.
@bygadd bygadd force-pushed the fix/glpi11-custom-assets-and-generate-item branch from ea13dd1 to 6f94427 Compare April 28, 2026 09:48
Comment thread setup.php
Comment on lines +128 to +140

// Auto-register all active custom assets defined via Asset definitions (GLPI 11+)
if (class_exists(\Glpi\Asset\AssetDefinitionManager::class)) {
$asset_manager = \Glpi\Asset\AssetDefinitionManager::getInstance();
$asset_manager->bootDefinitions();
foreach ($asset_manager->getDefinitions(true) as $definition) {
$custom_asset_class = $definition->getAssetClassName();
if (!in_array($custom_asset_class, $ORDER_TYPES, true)) {
$ORDER_TYPES[] = $custom_asset_class;
}
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You must declare your capacity in order for it to appear in the list.

This should be done in the setup.php file using:

AssetDefinitionManager::getInstance()->registerCapacity(...)

In addition, when a capacity is disabled, the associated data must be properly cleaned from the database.

In particular, this concerns the glpi_plugins_orderorder_item table, which—if I recall correctly—stores the relationship between an asset and an order.

Following further review feedback on pluginsGLPI#574, implement the
onCapacityDisabled() callback on PluginOrderOrderableCapacity so that
disabling the Orderable capacity on a custom asset definition removes
the plugin data that becomes meaningless once the asset class is no
longer orderable.

The cascade order matters: PluginOrderReference::pre_deleteItem()
refuses deletion while a reference is still in use by orders_items
rows, so child records (order line items) are removed before parent
records (product references). Both passes target only rows whose
itemtype matches the disabled custom asset class, leaving native
itemtypes and other custom assets untouched.

Free-form references (PluginOrderReferenceFree) are intentionally not
touched, as they are standalone records that do not store any itemtype.

End-to-end tested on GLPI 11.0.6, PHP 8.3 on two independent
installations:

- Disabling the capacity on a definition with linked references and
  order line items removes both, with native itemtypes and other
  custom assets untouched.
- Re-enabling the capacity restores the asset class in the Item type
  dropdown; new references and order items can be created normally.
- The capacity usage description (visible in the Capacities tab and in
  the GLPI confirmation dialog) shows the correct count of order
  references that will be removed if the admin proceeds.

Addresses follow-up review comment from @stonebuzz on pluginsGLPI#574.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants