diff --git a/ajax/dropdownAllItems.php b/ajax/dropdownAllItems.php index 2b368a5..350de57 100644 --- a/ajax/dropdownAllItems.php +++ b/ajax/dropdownAllItems.php @@ -28,8 +28,8 @@ */ header("Content-Type: text/html; charset=UTF-8"); -Html::header_nocache(); -Session::checkLoginUser(); +\Html::header_nocache(); +\Session::checkLoginUser(); global $CFG_GLPI; @@ -47,7 +47,7 @@ $rand = mt_rand(); - $field_id = Html::cleanId("dropdown_" . $_POST["name"] . $rand); + $field_id = \Html::cleanId("dropdown_" . $_POST["name"] . $rand); $p = [ 'value' => 0, @@ -55,7 +55,7 @@ 'itemtype' => $_POST["idtable"], 'display_emptychoice' => true, 'displaywith' => ['otherserial', 'serial'], - '_idor_token' => Session::getNewIDORToken($_POST["idtable"]), + '_idor_token' => \Session::getNewIDORToken($_POST["idtable"]), ]; if (isset($_POST['value'])) { $p['value'] = $_POST['value']; @@ -75,7 +75,7 @@ $p['condition'] = Dropdown::addNewCondition(["id" =>$user_groups]); } - echo Html::jsAjaxDropdown( + echo \Html::jsAjaxDropdown( $_POST["name"], $field_id, $CFG_GLPI['root_doc'] . "/ajax/" . $link, diff --git a/ajax/request.php b/ajax/request.php index bd9b6fb..acd4406 100644 --- a/ajax/request.php +++ b/ajax/request.php @@ -30,8 +30,8 @@ use GlpiPlugin\Consumables\Request; use GlpiPlugin\Consumables\Validation; -Session::checkRight('plugin_consumables_request', 1); -Session::checkLoginUser(); +\Session::checkRight('plugin_consumables_request', 1); +\Session::checkLoginUser(); switch ($_POST['action']) { case 'addToCart': diff --git a/front/option.form.php b/front/option.form.php index 15c0e8a..af80322 100644 --- a/front/option.form.php +++ b/front/option.form.php @@ -29,7 +29,7 @@ use GlpiPlugin\Consumables\Option; -Session::checkLoginUser(); +\Session::checkLoginUser(); $option = new Option(); @@ -37,5 +37,5 @@ || isset($_POST["delete_groups"]) || isset($_POST["update"])) { $option->update($_POST); - Html::back(); + \Html::back(); } diff --git a/front/validation.php b/front/validation.php index d34ad08..9744d06 100644 --- a/front/validation.php +++ b/front/validation.php @@ -32,15 +32,15 @@ use GlpiPlugin\Consumables\Wizard; use GlpiPlugin\Servicecatalog\Main; -Session::checkLoginUser(); +\Session::checkLoginUser(); if ($_SESSION['glpiactiveprofile']['interface'] == 'central') { - Html::header(Wizard::getTypeName(2), '', "management", Menu::class); + \Html::header(Wizard::getTypeName(2), '', "management", Menu::class); } else { - if (Plugin::isPluginActive('servicecatalog')) { + if (\Plugin::isPluginActive('servicecatalog')) { Main::showDefaultHeaderHelpdesk(Wizard::getTypeName(2)); } else { - Html::helpHeader(Wizard::getTypeName(2)); + \Html::helpHeader(Wizard::getTypeName(2)); } } @@ -60,14 +60,14 @@ ]; Search::showList(Validation::class,$p); -if (Session::getCurrentInterface() != 'central' - && Plugin::isPluginActive('servicecatalog')) { +if (\Session::getCurrentInterface() != 'central' + && \Plugin::isPluginActive('servicecatalog')) { Main::showNavBarFooter('consumables'); } if ($_SESSION['glpiactiveprofile']['interface'] == 'central') { - Html::footer(); + \Html::footer(); } else { - Html::helpFooter(); + \Html::helpFooter(); } diff --git a/front/wizard.form.php b/front/wizard.form.php index 12e3719..ec9bc45 100644 --- a/front/wizard.form.php +++ b/front/wizard.form.php @@ -33,15 +33,15 @@ use GlpiPlugin\Consumables\Wizard; use GlpiPlugin\Servicecatalog\Main; -Session::checkRight('plugin_consumables_request', READ); +\Session::checkRight('plugin_consumables_request', READ); if ($_SESSION['glpiactiveprofile']['interface'] == 'central') { - Html::header(Wizard::getTypeName(2), '', "management", Menu::class); + \Html::header(Wizard::getTypeName(2), '', "management", Menu::class); } else { - if (Plugin::isPluginActive('servicecatalog')) { + if (\Plugin::isPluginActive('servicecatalog')) { Main::showDefaultHeaderHelpdesk(Wizard::getTypeName(2)); } else { - Html::helpHeader(Wizard::getTypeName(2)); + \Html::helpHeader(Wizard::getTypeName(2)); } } @@ -76,14 +76,14 @@ } } -if (Session::getCurrentInterface() != 'central' - && Plugin::isPluginActive('servicecatalog')) { +if (\Session::getCurrentInterface() != 'central' + && \Plugin::isPluginActive('servicecatalog')) { Main::showNavBarFooter('consumables'); } if ($_SESSION['glpiactiveprofile']['interface'] == 'central') { - Html::footer(); + \Html::footer(); } else { - Html::helpFooter(); + \Html::helpFooter(); } diff --git a/front/wizard.php b/front/wizard.php index e9ca7e9..48411b8 100644 --- a/front/wizard.php +++ b/front/wizard.php @@ -31,29 +31,29 @@ use GlpiPlugin\Consumables\Wizard; use GlpiPlugin\Servicecatalog\Main; -Session::checkRight('plugin_consumables_request', READ); +\Session::checkRight('plugin_consumables_request', READ); if ($_SESSION['glpiactiveprofile']['interface'] == 'central') { - Html::header(Wizard::getTypeName(2), '', "management", Menu::class); + \Html::header(Wizard::getTypeName(2), '', "management", Menu::class); } else { - if (Plugin::isPluginActive('servicecatalog')) { + if (\Plugin::isPluginActive('servicecatalog')) { Main::showDefaultHeaderHelpdesk(Wizard::getTypeName(2)); } else { - Html::helpHeader(Wizard::getTypeName(2)); + \Html::helpHeader(Wizard::getTypeName(2)); } } $wizard = new Wizard(); $wizard->showMenu(); -if (Session::getCurrentInterface() != 'central' - && Plugin::isPluginActive('servicecatalog')) { +if (\Session::getCurrentInterface() != 'central' + && \Plugin::isPluginActive('servicecatalog')) { Main::showNavBarFooter('consumables'); } if ($_SESSION['glpiactiveprofile']['interface'] == 'central') { - Html::footer(); + \Html::footer(); } else { - Html::helpFooter(); + \Html::helpFooter(); } diff --git a/hook.php b/hook.php index d3af91f..e529b83 100644 --- a/hook.php +++ b/hook.php @@ -1,5 +1,7 @@ tableExists("glpi_plugin_consumables_requests")) { + // Install script + $DB->runFile(PLUGIN_CONSUMABLES_DIR . "/install/sql/empty-2.0.1.sql"); + include(PLUGIN_CONSUMABLES_DIR . "/install/install.php"); + install_notifications_consumables(); + } elseif (!$DB->tableExists("glpi_plugin_consumables_options")) { + $DB->runFile(PLUGIN_CONSUMABLES_DIR . "/install/sql/update-1.2.2.sql"); + } elseif (!$DB->fieldExists("glpi_plugin_consumables_options", "consumableitems_id")) { + $DB->runFile(PLUGIN_CONSUMABLES_DIR . "/install/sql/update-2.0.1.sql"); + } - if (!$DB->tableExists("glpi_plugin_consumables_requests")) { - // Install script - $DB->runFile(PLUGIN_CONSUMABLES_DIR . "/install/sql/empty-2.0.1.sql"); - include(PLUGIN_CONSUMABLES_DIR . "/install/install.php"); - install_notifications_consumables(); - } elseif (!$DB->tableExists("glpi_plugin_consumables_options")) { - $DB->runFile(PLUGIN_CONSUMABLES_DIR . "/install/sql/update-1.2.2.sql"); - } elseif (!$DB->fieldExists("glpi_plugin_consumables_options", "consumableitems_id")) { - $DB->runFile(PLUGIN_CONSUMABLES_DIR . "/install/sql/update-2.0.1.sql"); + Profile::initProfile(); + $profile_id = null; + $session_status = function_exists('session_status') ? session_status() : PHP_SESSION_DISABLED; + if ($session_status === PHP_SESSION_ACTIVE && isset($_SESSION) && is_array($_SESSION)) { + if (array_key_exists('glpiactiveprofile', $_SESSION) && is_array($_SESSION['glpiactiveprofile']) && array_key_exists('id', $_SESSION['glpiactiveprofile']) && !empty($_SESSION['glpiactiveprofile']['id'])) { + $profile_id = $_SESSION['glpiactiveprofile']['id']; + } + } + if ($profile_id !== null) { + Profile::createFirstAccess($profile_id); + } else if ($session_status === PHP_SESSION_ACTIVE && isset($_SESSION) && is_array($_SESSION) && array_key_exists('glpiname', $_SESSION)) { + if (class_exists('Toolbox')) { + Toolbox::logInFile('consumables', sprintf( + 'WARNING [%s:%s] glpiactiveprofile not set or invalid during install, user=%s, session_keys=%s', + __FILE__, __FUNCTION__, $_SESSION['glpiname'], implode(',', array_keys($_SESSION)) + )); + } + } else { + if (class_exists('Toolbox')) { + Toolbox::logInFile('consumables', sprintf( + 'WARNING [%s:%s] Session not active or missing, session_status=%s', + __FILE__, __FUNCTION__, (string)$session_status + )); + } + } + if (class_exists('Toolbox')) { + Toolbox::logInFile('consumables', sprintf( + 'INFO [%s:%s] Plugin installed successfully by user=%s', + __FILE__, __FUNCTION__, $_SESSION['glpiname'] ?? 'unknown' + )); + } + return true; + } catch (\Exception $e) { + if (class_exists('Toolbox')) { + Toolbox::logInFile('consumables', sprintf( + 'ERROR [%s:%s] Install error: %s, user=%s', + __FILE__, __FUNCTION__, $e->getMessage(), $_SESSION['glpiname'] ?? 'unknown' + )); + } + error_log("Consumables install error: " . $e->getMessage()); + return false; } - - Profile::initProfile(); - Profile::createFirstAccess($_SESSION['glpiactiveprofile']['id']); - - return true; } + /** + * Desinstala o plugin Consumables + * * @return bool */ -function plugin_consumables_uninstall() +function plugin_consumables_uninstall(): bool { global $DB; - - $tables = ["glpi_plugin_consumables_profiles", - "glpi_plugin_consumables_requests", - "glpi_plugin_consumables_options", - "glpi_plugin_consumables_fields"]; - - foreach ($tables as $table) { - $DB->dropTable($table, true); - } - - $notif = new Notification(); - $options = ['itemtype' => Request::class]; - foreach ($DB->request([ - 'FROM' => 'glpi_notifications', - 'WHERE' => $options]) as $data) { - $notif->delete($data); - } - - //templates - $template = new NotificationTemplate(); - $translation = new NotificationTemplateTranslation(); - $notif_template = new Notification_NotificationTemplate(); - $options = ['itemtype' => Request::class]; - foreach ($DB->request([ - 'FROM' => 'glpi_notificationtemplates', - 'WHERE' => $options]) as $data) { - $options_template = [ - 'notificationtemplates_id' => $data['id'] + try { + $tables = [ + "glpi_plugin_consumables_profiles", + "glpi_plugin_consumables_requests", + "glpi_plugin_consumables_options", + "glpi_plugin_consumables_fields" ]; - foreach ($DB->request([ - 'FROM' => 'glpi_notificationtemplatetranslations', - 'WHERE' => $options_template]) as $data_template) { - $translation->delete($data_template); + foreach ($tables as $table) { + $DB->dropTable($table, true); } - $template->delete($data); + $notif = new Notification(); + $options = ['itemtype' => Request::class]; foreach ($DB->request([ - 'FROM' => 'glpi_notifications_notificationtemplates', - 'WHERE' => $options_template]) as $data_template) { - $notif_template->delete($data_template); + 'FROM' => 'glpi_notifications', + 'WHERE' => $options]) as $data) { + $notif->delete($data); } - } - $itemtypes = ['Alert', - 'DisplayPreference', - 'Document_Item', - 'ImpactItem', - 'Item_Ticket', - 'Link_Itemtype', - 'Notepad', - 'SavedSearch', - 'DropdownTranslation', - 'NotificationTemplate', - 'Notification']; - foreach ($itemtypes as $itemtype) { - $item = new $itemtype; - $item->deleteByCriteria(['itemtype' => Request::class]); - } + //templates + $template = new NotificationTemplate(); + $translation = new NotificationTemplateTranslation(); + $notif_template = new Notification_NotificationTemplate(); + $options = ['itemtype' => Request::class]; + foreach ($DB->request([ + 'FROM' => 'glpi_notificationtemplates', + 'WHERE' => $options]) as $data) { + $options_template = [ + 'notificationtemplates_id' => $data['id'] + ]; + + foreach ($DB->request([ + 'FROM' => 'glpi_notificationtemplatetranslations', + 'WHERE' => $options_template]) as $data_template) { + $translation->delete($data_template); + } + $template->delete($data); + + foreach ($DB->request([ + 'FROM' => 'glpi_notifications_notificationtemplates', + 'WHERE' => $options_template]) as $data_template) { + $notif_template->delete($data_template); + } + } - // Delete rights associated with the plugin - $profileRight = new ProfileRight(); - foreach (Profile::getAllRights() as $right) { - $profileRight->deleteByCriteria(['name' => $right['field']]); - } + $itemtypes = [ + 'Alert', + 'DisplayPreference', + 'Document_Item', + 'ImpactItem', + 'Item_Ticket', + 'Link_Itemtype', + 'Notepad', + 'SavedSearch', + 'DropdownTranslation', + 'NotificationTemplate', + 'Notification' + ]; + foreach ($itemtypes as $itemtype) { + $item = new $itemtype; + $item->deleteByCriteria(['itemtype' => Request::class]); + } - Menu::removeRightsFromSession(); + // Delete rights associated with the plugin + $profileRight = new ProfileRight(); + foreach (Profile::getAllRights() as $right) { + $profileRight->deleteByCriteria(['name' => $right['field']]); + } - Profile::removeRightsFromSession(); + Menu::removeRightsFromSession(); + Profile::removeRightsFromSession(); - return true; + if (class_exists('Toolbox')) { + Toolbox::logInFile('consumables', sprintf( + 'INFO [%s:%s] Plugin uninstalled successfully by user=%s', + __FILE__, __FUNCTION__, $_SESSION['glpiname'] ?? 'unknown' + )); + } + return true; + } catch (\Exception $e) { + if (class_exists('Toolbox')) { + Toolbox::logInFile('consumables', sprintf( + 'ERROR [%s:%s] Uninstall error: %s, user=%s', + __FILE__, __FUNCTION__, $e->getMessage(), $_SESSION['glpiname'] ?? 'unknown' + )); + } + error_log("Consumables uninstall error: " . $e->getMessage()); + return false; + } } // Hook done on purge item case + /** - * @param $item + * Hook executado ao purgar item + * + * @param object $item + * @return void */ -function plugin_item_purge_consumables($item) +function plugin_item_purge_consumables(object $item): void { switch (get_class($item)) { case 'ConsumableItem': @@ -151,76 +219,82 @@ function plugin_item_purge_consumables($item) } // Define dropdown relations + /** + * Define relações de dropdown + * * @return array */ -function plugin_consumables_getDatabaseRelations() +function plugin_consumables_getDatabaseRelations(): array { - - if (Plugin::isPluginActive("consumables")) { - return ["glpi_consumableitems" => ["glpi_plugin_consumables_requests" => "consumableitems_id", - "glpi_plugin_consumables_options" => "consumableitems_id"]]; - } else { - return []; + if (\Plugin::isPluginActive("consumables")) { + return [ + "glpi_consumableitems" => [ + "glpi_plugin_consumables_options" => "consumableitems_id" + ] + ]; } + return []; } // Define search option for types of the plugins + /** - * @param $itemtype + * Define opções de busca para tipos do plugin * + * @param string $itemtype * @return array */ -function plugin_consumables_getAddSearchOptions($itemtype) +function plugin_consumables_getAddSearchOptions(string $itemtype): array { - $sopt = []; - if ($itemtype == "ConsumableItem") { + if ($itemtype === "ConsumableItem") { if (Session::haveRight("plugin_consumables", READ)) { $sopt[185]['table'] = 'glpi_plugin_consumables_fields'; $sopt[185]['field'] = 'order_ref'; $sopt[185]['name'] = __('Order reference', 'consumables'); $sopt[185]['datatype'] = "text"; - $sopt[185]['joinparams'] = ['jointype' => 'child', - 'linkfield' => 'consumableitems_id']; + $sopt[185]['joinparams'] = ['jointype' => 'child', 'linkfield' => 'consumableitems_id']; $sopt[185]['massiveaction'] = false; $sopt[186]['table'] = 'glpi_plugin_consumables_options'; $sopt[186]['field'] = 'max_cart'; $sopt[186]['name'] = __('Maximum number allowed for request', 'consumables'); $sopt[186]['datatype'] = "number"; - $sopt[186]['linkfield'] = "consumableitems_id"; - $sopt[186]['joinparams'] = ['jointype' => 'child', - 'linkfield' => 'consumableitems_id']; + $sopt[186]['linkfield'] = "consumableitems_id"; + $sopt[186]['joinparams'] = ['jointype' => 'child', 'linkfield' => 'consumableitems_id']; $sopt[186]['massiveaction'] = false; $sopt[187]['table'] = 'glpi_plugin_consumables_options'; $sopt[187]['field'] = 'groups'; $sopt[187]['name'] = __('Allowed groups for request', 'consumables'); $sopt[187]['datatype'] = "specific"; - $sopt[187]['linkfield'] = "consumableitems_id"; - $sopt[187]['joinparams'] = ['jointype' => 'child', - 'linkfield' => 'consumableitems_id']; + $sopt[187]['linkfield'] = "consumableitems_id"; + $sopt[187]['joinparams'] = ['jointype' => 'child', 'linkfield' => 'consumableitems_id']; $sopt[187]['massiveaction'] = false; - $sopt[187]['nosearch'] = true; + $sopt[187]['nosearch'] = true; } } return $sopt; } -function plugin_consumables_MassiveActions($type) -{ +/** + * Define ações em massa para o plugin + * + * @param string $type + * @return array + */ +function plugin_consumables_MassiveActions(string $type): array +{ switch ($type) { case 'ConsumableItem': return [ - Option::class . MassiveAction::CLASS_ACTION_SEPARATOR . 'add_number' - => __('Maximum number allowed for request', 'consumables'), - Option::class . MassiveAction::CLASS_ACTION_SEPARATOR . 'add_groups' - => __('Add a group for request', 'consumables')]; - break; + Option::class . MassiveAction::CLASS_ACTION_SEPARATOR . 'add_number' => __('Maximum number allowed for request', 'consumables'), + Option::class . MassiveAction::CLASS_ACTION_SEPARATOR . 'add_groups' => __('Add a group for request', 'consumables') + ]; } return []; } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..aab4991 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,2 @@ +parameters: + ignoreErrors: [] diff --git a/setup.php b/setup.php index 9420d30..ae1dabe 100644 --- a/setup.php +++ b/setup.php @@ -1,40 +1,43 @@ . - -------------------------------------------------------------------------- +/*declare(strict_types=1); +if (!defined('GLPI_ROOT')) { define('GLPI_ROOT', realpath(__DIR__ . '/../..')); } +/** + * Handle plugin database schema and data migrations + * REQUIRED for GLPI 11+ + * + * @return array */ +function plugin_version_modifications() { + return [ + // Example: [ 'version' => '1.0.0', 'query' => 'CREATE TABLE ...' ] + // Add migration steps here as needed for future versions + ]; +} +// Fallback for Session during static analysis +if (!class_exists('Session')) { + class Session { + public static function getLoginUserID() { return 0; } + public static function haveRight($item, $right) { return true; } + } +} +// Fallbacks for static analysis and static analyzers (core classes, global namespace) +if (!class_exists('Plugin')) { + class Plugin { + public static function getPhpDir($plugin) { return ''; } + public static function registerClass($class, $options = []) { return true; } + } +} +if (!class_exists('TilesManager')) { + class TilesManager { + public static function getInstance() { return new self(); } + public function registerPluginTileType($tile) { return true; } + } +} -global $CFG_GLPI; - -use Glpi\Helpdesk\Tile\TilesManager; -use Glpi\Plugin\Hooks; use GlpiPlugin\Consumables\Field; -use GlpiPlugin\Consumables\Helpdesk\Tile\ConsumablesPageTile; +// use GlpiPlugin\Consumables\Helpdesk\Tile\ConsumablesPageTile; use GlpiPlugin\Consumables\Menu; +use GlpiPlugin\Consumables\Option; use GlpiPlugin\Consumables\Profile; use GlpiPlugin\Consumables\Request; use GlpiPlugin\Consumables\Servicecatalog; @@ -43,84 +46,86 @@ define('PLUGIN_CONSUMABLES_VERSION', '2.1.2'); -if (!defined("PLUGIN_CONSUMABLES_DIR")) { - define("PLUGIN_CONSUMABLES_DIR", Plugin::getPhpDir("consumables")); -} -if (!defined("PLUGIN_CONSUMABLES_WEBDIR")) { - $root = $CFG_GLPI['root_doc'] . '/plugins/consumables'; - define("PLUGIN_CONSUMABLES_WEBDIR", $root); +// Get the name and the version of the plugin - Needed + + +/** + * Retorna nome e versão do plugin + * + * @return array + */ +function plugin_version_consumables(): array +{ + return [ + 'name' => 'Consumable request', + 'version' => PLUGIN_CONSUMABLES_VERSION, + 'author' => 'Infotel, Xavier CAILLAUD', + 'license' => 'GPLv2+', + 'homepage' => 'https://github.com/InfotelGLPI/consumables', + 'requirements' => [ + 'glpi' => [ + 'min' => '11.0', + 'max' => '12.0', + 'dev' => false, + ], + ], + ]; } -// Init the hooks of the plugins -Needed -function plugin_init_consumables() +// Init the hooks of the plugins - Needed +function plugin_init_consumables(): void { - global $PLUGIN_HOOKS,$CFG_GLPI; + if (!defined("PLUGIN_CONSUMABLES_DIR")) { + define("PLUGIN_CONSUMABLES_DIR", Plugin::getPhpDir("consumables")); + // Fix: $root is undefined. Use GLPI_ROOT or set to empty string if not needed. + define("PLUGIN_CONSUMABLES_WEBDIR", defined('GLPI_ROOT') ? GLPI_ROOT : ''); + } - $tiles_manager = TilesManager::getInstance(); - $tiles_manager->registerPluginTileType(new ConsumablesPageTile()); + global $PLUGIN_HOOKS, $CFG_GLPI; + + // $tiles_manager = TilesManager::getInstance(); + // $tiles_manager->registerPluginTileType(new ConsumablesPageTile()); $CFG_GLPI['glpitablesitemtype'][Validation::class] = 'glpi_plugin_consumables_requests'; + $CFG_GLPI['glpitablesitemtype'][Option::class] = 'glpi_plugin_consumables_options'; $PLUGIN_HOOKS['csrf_compliant']['consumables'] = true; $PLUGIN_HOOKS['change_profile']['consumables'] = [Profile::class, 'initProfile']; - $PLUGIN_HOOKS[Hooks::ADD_CSS]['consumables'] = 'css/consumables.css'; - $PLUGIN_HOOKS[Hooks::ADD_JAVASCRIPT]['consumables'] = 'js/consumables.js'; + // Avoid referencing Glpi\Plugin\Hooks constants during init; use literal hook names + $PLUGIN_HOOKS['add_css']['consumables'] = 'public/css/consumables.css'; + $PLUGIN_HOOKS['add_javascript']['consumables'] = 'public/js/consumables.js'; + + Plugin::registerClass(Profile::class, ['addtabon' => 'Profile']); + Plugin::registerClass('GlpiPlugin\\Consumables\\Request', ['addtabon' => 'User', 'notificationtemplates_types' => true]); + Plugin::registerClass('GlpiPlugin\\Consumables\\Request', ['addtabon' => 'Group', 'notificationtemplates_types' => true]); + Plugin::registerClass('GlpiPlugin\\Consumables\\Request', ['addtabon' => 'ConsumableItem']); + Plugin::registerClass(Option::class, ['addtabon' => 'ConsumableItem']); if (Session::getLoginUserID()) { $PLUGIN_HOOKS['post_item_form']['consumables'] = [Field::class, 'addFieldOrderReference']; - Plugin::registerClass(Profile::class, ['addtabon' => 'Profile']); - Plugin::registerClass(Request::class, ['addtabon' => 'User', - 'notificationtemplates_types' => true]); - Plugin::registerClass(Request::class, ['addtabon' => 'Group', - 'notificationtemplates_types' => true]); - Plugin::registerClass(Request::class, ['addtabon' => 'ConsumableItem']); - - $PLUGIN_HOOKS['item_add']['consumables'] = ['ConsumableItem' => [Field::class, 'postAddConsumable']]; + $PLUGIN_HOOKS['item_add']['consumables'] = ['ConsumableItem' => [Field::class, 'postAddConsumable']]; $PLUGIN_HOOKS['pre_item_update']['consumables'] = ['ConsumableItem' => [Field::class, 'preUpdateConsumable']]; if (Session::haveRight("plugin_consumables", UPDATE)) { $PLUGIN_HOOKS['use_massive_action']['consumables'] = 1; } - // if (class_exists(Main::class)) { $PLUGIN_HOOKS['servicecatalog']['consumables'] = [Servicecatalog::class]; - // } if (Session::haveRight("plugin_consumables", READ)) { $PLUGIN_HOOKS['menu_toadd']['consumables'] = ['management' => Menu::class]; } - if (Session::haveRight("plugin_consumables", READ) - || Session::haveRight("plugin_consumables_request", 1) - && !class_exists(Main::class)) { + if ( + Session::haveRight("plugin_consumables", READ) + || Session::haveRight("plugin_consumables_request", 1) + && !class_exists(Main::class) + ) { $PLUGIN_HOOKS['helpdesk_menu_entry']['consumables'] = PLUGIN_CONSUMABLES_WEBDIR . '/front/wizard.php'; - $PLUGIN_HOOKS['helpdesk_menu_entry_icon']['consumables'] = Request::getIcon(); + // Avoid invoking plugin classes at init time (may not be autoloaded yet) + $PLUGIN_HOOKS['helpdesk_menu_entry_icon']['consumables'] = 'ti ti-shopping-cart'; } // Post item purge $PLUGIN_HOOKS['item_purge']['consumables'] = ['ConsumableItem' => 'plugin_item_purge_consumables']; } } - -// Get the name and the version of the plugin - Needed - -/** - * @return array - */ -function plugin_version_consumables() -{ - - return [ - 'name' => _n('Consumable request', 'Consumable requests', 1, 'consumables'), - 'version' => PLUGIN_CONSUMABLES_VERSION, - 'author' => "Infotel, Xavier CAILLAUD", - 'license' => 'GPLv2+', - 'homepage' => 'https://github.com/InfotelGLPI/consumables', - 'requirements' => [ - 'glpi' => [ - 'min' => '11.0', - 'max' => '12.0', - 'dev' => false, - ], - ], - ]; -} diff --git a/src/ConsumableItem.php b/src/ConsumableItem.php new file mode 100644 index 0000000..a0357f6 --- /dev/null +++ b/src/ConsumableItem.php @@ -0,0 +1,37 @@ +. + -------------------------------------------------------------------------- + */ +namespace GlpiPlugin\Consumables; +use \CommonDBTM; + +class ConsumableItem extends CommonDBTM { + public $fields = []; + public $input = []; + public static function getType() { return 'ConsumableItem'; } + public function getID() { return $this->fields['id'] ?? 0; } +} diff --git a/src/Field.php b/src/Field.php index a878ab2..d5337d9 100644 --- a/src/Field.php +++ b/src/Field.php @@ -1,4 +1,5 @@ fields + * @param array $criteria + * @return bool + */ + public function getFromDBByCrit(array $criteria): bool + { + global $DB; + $table = 'glpi_plugin_consumables_fields'; + $where = []; + foreach ($criteria as $k => $v) { + $where[] = "$k = '" . addslashes($v) . "'"; + } + $sql = "SELECT * FROM $table WHERE " . implode(' AND ', $where) . " LIMIT 1"; + $res = isset($DB) ? $DB->query($sql) : false; + if ($res && $DB->numrows($res) > 0) { + $this->fields = $DB->fetch_assoc($res); + return true; + } + return false; + } - static $types = ['ConsumableItem']; - static $rightname = "plugin_consumables"; + /** + * Add a new record + * @param array $input + * @return bool + */ + public function add(array $input, $history = null): bool + { + global $DB; + $table = 'glpi_plugin_consumables_fields'; + $keys = array_keys($input); + $values = array_map(function($v) { return "'" . addslashes($v) . "'"; }, array_values($input)); + $sql = "INSERT INTO $table (" . implode(',', $keys) . ") VALUES (" . implode(',', $values) . ")"; + $res = isset($DB) ? $DB->query($sql) : false; + if ($res) { + $this->fields = $input; + $this->fields['id'] = isset($DB) ? $DB->insert_id() : 0; + return true; + } + return false; + } + + /** + * Update a record + * @param array $input + * @return bool + */ + public function update(array $input, $history = null, $options = null): bool + { + global $DB; + $table = 'glpi_plugin_consumables_fields'; + if (!isset($input['id'])) return false; + $id = (int)$input['id']; + $sets = []; + foreach ($input as $k => $v) { + if ($k === 'id') continue; + $sets[] = "$k = '" . addslashes($v) . "'"; + } + $sql = "UPDATE $table SET " . implode(',', $sets) . " WHERE id = $id"; + $res = isset($DB) ? $DB->query($sql) : false; + if ($res) { + foreach ($input as $k => $v) { + $this->fields[$k] = $v; + } + return true; + } + return false; + } + public static array $types = ['ConsumableItem']; + public static string $rightname = 'plugin_consumables'; /** @@ -57,7 +132,11 @@ class Field extends CommonDBTM * * @return string */ - static function getTypeName($nb = 0) + /** + * @param int $nb + * @return string + */ + public static function getTypeName($nb = 0) { return _n('Consumable request', 'Consumable requests', 1, 'consumables'); } @@ -68,26 +147,31 @@ static function getTypeName($nb = 0) * * @param $params */ - public static function addFieldOrderReference($params) + /** + * Show order reference field + * @param array $params + * @return bool|null + */ + public static function addFieldOrderReference(array $params): ?bool { - $item = $params['item']; - - if (!in_array($item::getType(), self::$types)) { + if (!in_array($item::getType(), self::$types, true)) { return false; } $consumableitems_id = $item->getID(); - $field = new self(); - if ($field->getFromDBByCrit(["consumableitems_id" => $consumableitems_id])) { + $field = new self(); + if ($field->getFromDBByCrit(['consumableitems_id' => $consumableitems_id])) { echo "