diff --git a/CHANGELOG.md b/CHANGELOG.md index 233952fe40..9b01d2050d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [unreleased] +### Added +- Add an `Orderable` capacity for GLPI 11 custom asset definitions. + ### Fixed - Fix generate associated item massive action diff --git a/inc/orderablecapacity.class.php b/inc/orderablecapacity.class.php new file mode 100644 index 0000000000..4cadf05037 --- /dev/null +++ b/inc/orderablecapacity.class.php @@ -0,0 +1,104 @@ +. + * ------------------------------------------------------------------------- + * @copyright Copyright (C) 2009-2023 by Order plugin team. + * @license GPLv3 https://www.gnu.org/licenses/gpl-3.0.html + * @link https://github.com/pluginsGLPI/order + * ------------------------------------------------------------------------- + */ + +use Glpi\Asset\Capacity\AbstractCapacity; +use Glpi\Asset\CapacityConfig; + +/** + * Capacity that flags a GLPI 11 custom asset definition as orderable + * through the Order plugin. When enabled on an asset definition (Setup -> + * Asset definitions -> {your asset} -> Capacities), the corresponding + * generated asset class is appended to $ORDER_TYPES and becomes selectable + * as an Item type when creating a Product reference. + */ +class PluginOrderOrderableCapacity extends AbstractCapacity +{ + public function getLabel(): string + { + return __('Orderable', 'order'); + } + + public function getIcon(): string + { + return 'ti ti-shopping-cart'; + } + + public function getDescription(): string + { + return __( + 'Allow this asset to be referenced as a Product reference and ' + . 'generated from the Generate item massive action.', + 'order', + ); + } + + public function getCapacityUsageDescription(string $classname): string + { + $count = 0; + if (class_exists('PluginOrderReference')) { + $count = countElementsInTable( + PluginOrderReference::getTable(), + ['itemtype' => $classname], + ); + } + + return sprintf( + _n('Used by %d order reference', 'Used by %d order references', $count, 'order'), + $count, + ); + } + + /** + * Clean up plugin data linked to the asset class when the capacity is + * disabled on its definition: remove order line items first (parent + * Product references refuse deletion via pre_deleteItem() while still + * referenced by orders_items), then remove the references themselves. + * Free-form references are intentionally left untouched, as they are + * standalone records that do not reference any itemtype. + */ + public function onCapacityDisabled(string $classname, CapacityConfig $config): void + { + if (class_exists('PluginOrderOrder_Item')) { + (new PluginOrderOrder_Item())->deleteByCriteria( + ['itemtype' => $classname], + force: true, + history: false, + ); + } + + if (class_exists('PluginOrderReference')) { + (new PluginOrderReference())->deleteByCriteria( + ['itemtype' => $classname], + force: true, + history: false, + ); + } + } +} diff --git a/setup.php b/setup.php index 7cd7cfd6b0..a918351bd4 100644 --- a/setup.php +++ b/setup.php @@ -28,6 +28,8 @@ * ------------------------------------------------------------------------- */ +use Glpi\Asset\AssetDefinitionManager; + use function Safe\define; define('PLUGIN_ORDER_VERSION', '2.12.6'); @@ -125,6 +127,30 @@ function plugin_init_order() 'Pdu', ]; + + // Register the Orderable capacity for GLPI 11 custom assets and append + // any custom asset class that has it enabled to $ORDER_TYPES, provided + // the current user is allowed to view it. + if (class_exists(AssetDefinitionManager::class)) { + $asset_manager = AssetDefinitionManager::getInstance(); + $orderable_capacity = new PluginOrderOrderableCapacity(); + $asset_manager->registerCapacity($orderable_capacity); + $asset_manager->bootDefinitions(); + foreach ($asset_manager->getDefinitions(true) as $definition) { + if (!$definition->hasCapacityEnabled($orderable_capacity)) { + continue; + } + + $custom_asset_class = $definition->getAssetClassName(); + if ( + !in_array($custom_asset_class, $ORDER_TYPES, true) + && $custom_asset_class::canView() + ) { + $ORDER_TYPES[] = $custom_asset_class; + } + } + } + $CFG_GLPI['plugin_order_types'] = $ORDER_TYPES; $PLUGIN_HOOKS['pre_item_purge']['order'] = [