From f50766874ef9ef23c37ad772fd36509c9a826cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Fri, 21 Apr 2023 16:58:24 +0200 Subject: [PATCH 01/26] Add upgrade guidelines for GLPI 10.1 --- source/index.rst | 1 + source/upgradeguides/glpi-10.1.rst | 55 ++++++++++++++++++++++++++++++ source/upgradeguides/index.rst | 12 +++++++ 3 files changed, 68 insertions(+) create mode 100644 source/upgradeguides/glpi-10.1.rst create mode 100644 source/upgradeguides/index.rst diff --git a/source/index.rst b/source/index.rst index 30bacca..33a8e48 100644 --- a/source/index.rst +++ b/source/index.rst @@ -19,6 +19,7 @@ GLPI Developer Documentation checklists/index plugins/index packaging + upgradeguides If you want to help us improve the current documentation, feel free to open pull requests! You can `see open issues `_ and `join the documentation mailing list `_. diff --git a/source/upgradeguides/glpi-10.1.rst b/source/upgradeguides/glpi-10.1.rst new file mode 100644 index 0000000..7ddabd8 --- /dev/null +++ b/source/upgradeguides/glpi-10.1.rst @@ -0,0 +1,55 @@ +Upgrade to GLPI 10.1 +-------------------- + +Removal of input variables auto-sanitize +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Prior to GLPI 10.1, PHP superglobals ``$_GET``, ``$_POST`` and ``$_REQUEST`` were automatically sanitized. +It means that SQL special characters were escaped (prefixed by a ``\``), and HTML special characters ``<``, ``>`` and ``&`` were encoded into HTML entities. +This caused issues because it was difficult, for some pieces of code, to know if the received variables were "secure" or not. + +In GLPI 10.1, we removed this auto-sanitization, and any data, whether it comes from a form, the database, or the API, will always be in its raw state. + +Protection against SQL injection +++++++++++++++++++++++++++++++++ + +Protection against SQL injection is now automatically done when DB query is crafted. + +All the ``addslashes()`` usages that were used for this purpose have to be removed from your code. + +.. code-block:: diff + + - $item->add(Toolbox::addslashes_deep($properties)); + + $item->add($properties); + +Protection against XSS +++++++++++++++++++++++ + +HTML special characters are no longer encoded automatically. Even existing data will be seamlessly decoded when it will be fetched from database. +Code must be updated to ensure that all dynamic variables are correctly escaped in HTML views. + +Views built with ``Twig`` templates no longer require usage of the ``|verbatim_value`` filter to correctly display HTML special characters. +Also, Twig automatically escapes special characters, which protects against XSS. + +.. code-block:: diff + + -

{{ content|verbatim_value }}

+ +

{{ content }}

+ +Code that outputs HTML code directly must be adapted to use the ``htmlspecialchars()`` function. + +.. code-block:: diff + + - echo '

' . $content . '

'; + + echo '

' . htmlspecialchars($content) . '

'; + +Also, code that ouputs javascript must be adapted to prevent XSS with both HTML special characters and quotes. + +.. code-block:: diff + + echo ' + + '; diff --git a/source/upgradeguides/index.rst b/source/upgradeguides/index.rst new file mode 100644 index 0000000..e5dad36 --- /dev/null +++ b/source/upgradeguides/index.rst @@ -0,0 +1,12 @@ +Upgrade guides +============== + +The upgrade guides are intended to help you adapt your plugins to the changes introduced in the new versions of GLPI. + +.. note:: + + Only the most important changes and those requiring support are documented here. + If you are having trouble migrating your code, feel free to suggest a documentation update. + +.. toctree:: + :maxdepth: 2 From f24fbf8a70578b4ef98da6c954f13324e364ad64 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Thu, 14 Sep 2023 09:43:50 +0200 Subject: [PATCH 02/26] Add required readthedocs configuration file --- .readthedocs.yaml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..eeb06b8 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,27 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.11" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: source/conf.py + +formats: + - htmlzip + - pdf + - epub + +# We recommend specifying your dependencies to enable reproducible builds: +# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: requirements.txt From 646631d1c69a1602679c1e5b0693bb7dac17eebf Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Mon, 22 Jan 2024 10:28:23 -0500 Subject: [PATCH 03/26] High-Level API Internals Documentation (#149) * start documenting HL API * remove x-default-contexts --- source/devapi/hlapi/index.rst | 13 ++ source/devapi/hlapi/schemas.rst | 250 ++++++++++++++++++++++++++++++++ source/devapi/hlapi/search.rst | 34 +++++ 3 files changed, 297 insertions(+) create mode 100644 source/devapi/hlapi/index.rst create mode 100644 source/devapi/hlapi/schemas.rst create mode 100644 source/devapi/hlapi/search.rst diff --git a/source/devapi/hlapi/index.rst b/source/devapi/hlapi/index.rst new file mode 100644 index 0000000..1b30ae1 --- /dev/null +++ b/source/devapi/hlapi/index.rst @@ -0,0 +1,13 @@ +High-Level API +============== + +The High-Level API (HL API) is a new API system provided in GLPI starting with version 10.1.0. +While the user experience is more simplified than the legacy API (the REST API available in previous versions), the implementation is quite a bit more complex. +The following sections explain the various components of the new API. +These sections are sorted by the recommended reading order. It is recommended that you read the High-Level API user documentation first if you have no experience with the API at all. + +.. toctree:: + :maxdepth: 2 + + schemas + search diff --git a/source/devapi/hlapi/schemas.rst b/source/devapi/hlapi/schemas.rst new file mode 100644 index 0000000..ad7b6d6 --- /dev/null +++ b/source/devapi/hlapi/schemas.rst @@ -0,0 +1,250 @@ +Schemas +======= + +Schemas are the definitions of the various item types in GLPI, or facades, for how they are exposed to the API. +In the legacy API, all classes that extend ``CommonDBTM`` were exposed along with all of their search options. +This is not the case with the High-Level API. + +Schema Format +^^^^^^^^^^^^^ + +The schemas loosely follow the `OpenAPI 3 specification `_ to make it easier to implement the Swagger UI documentation tool. +GLPI utilizes multiple custom extension fields (fields starting with 'x-') in schemas to enable advanced behavior. +Schemas are defined in an array with their name as the key and definition as the value. + +There exists the ``\Glpi\API\HL\Doc\Schema`` class which is used to represent a schema definition in some cases, but also provides constants and static methods for working with schema arrays. +This includes constants for the supported property types and formats. + +Let's look at a partial version of the schema definition for a User since it shows most of the possibilities: + +.. code-block:: php + + 'User' => [ + 'x-itemtype' => User::class, + 'type' => Doc\Schema::TYPE_OBJECT, + 'x-rights-conditions' => [ // Object-level extra permissions + 'read' => static function () { + if (!\Session::canViewAllEntities()) { + return [ + 'LEFT JOIN' => [ + 'glpi_profiles_users' => [ + 'ON' => [ + 'glpi_profiles_users' => 'users_id', + 'glpi_users' => 'id' + ] + ] + ], + 'WHERE' => [ + 'glpi_profiles_users.entities_id' => $_SESSION['glpiactiveentities'] + ] + ]; + } + return true; + } + ], + 'properties' => [ + 'id' => [ + 'type' => Doc\Schema::TYPE_INTEGER, + 'format' => Doc\Schema::FORMAT_INTEGER_INT64, + 'description' => 'ID', + 'x-readonly' => true, + ], + 'username' => [ + 'x-field' => 'name', + 'type' => Doc\Schema::TYPE_STRING, + 'description' => 'Username', + ], + 'realname' => [ + 'type' => Doc\Schema::TYPE_STRING, + 'description' => 'Real name', + ], + 'emails' => [ + 'type' => Doc\Schema::TYPE_ARRAY, + 'description' => 'Email addresses', + 'items' => [ + 'type' => Doc\Schema::TYPE_OBJECT, + 'x-full-schema' => 'EmailAddress', + 'x-join' => [ + 'table' => 'glpi_useremails', + 'fkey' => 'id', + 'field' => 'users_id', + 'x-primary-property' => 'id' // Help the search engine understand the 'id' property is this object's primary key since the fkey and field params are reversed for this join. + ], + 'properties' => [ + 'id' => [ + 'type' => Doc\Schema::TYPE_INTEGER, + 'format' => Doc\Schema::FORMAT_INTEGER_INT64, + 'description' => 'ID', + ], + 'email' => [ + 'type' => Doc\Schema::TYPE_STRING, + 'description' => 'Email address', + ], + 'is_default' => [ + 'type' => Doc\Schema::TYPE_BOOLEAN, + 'description' => 'Is default', + ], + 'is_dynamic' => [ + 'type' => Doc\Schema::TYPE_BOOLEAN, + 'description' => 'Is dynamic', + ], + ] + ] + ], + 'password' => [ + 'type' => Doc\Schema::TYPE_STRING, + 'format' => Doc\Schema::FORMAT_STRING_PASSWORD, + 'description' => 'Password', + 'x-writeonly' => true, + ], + 'password2' => [ + 'type' => Doc\Schema::TYPE_STRING, + 'format' => Doc\Schema::FORMAT_STRING_PASSWORD, + 'description' => 'Password confirmation', + 'x-writeonly' => true, + ], + 'picture' => [ + 'type' => Doc\Schema::TYPE_STRING, + 'x-mapped-from' => 'picture', + 'x-mapper' => static function ($v) { + global $CFG_GLPI; + $path = \Toolbox::getPictureUrl($v, false); + if (!empty($path)) { + return $path; + } + return $CFG_GLPI["root_doc"] . '/pics/picture.png'; + } + ] + ] + ] + +The first property in the definition, 'x-itemtype' is used to link the schema with an actual GLPI class. +This is used to determine which table to use to access direct properties and access more data like entity restrictions and extra visiblity restrictions (when implementing the ``ExtraVisibilityCriteria`` class). +This property is required. + +Next, is a 'type' property which is part of the standard OpenAPI specification. In this case, it defines a User as an object. In general, all schemas would be objects. + +Third, is an 'x-rights-conditions' property which defines special visiblity restrictions. This property may be excluded if there are no special restrictions. +Currently, only 'read' restrictions can be defined here. +Each type of restriction must be a callable that returns an array of criteria, or just an array of criteria, in the format used by ``DBmysqlIterator``. +If the criteria is reliant on data from a session or is expensive, it should use a callable so that the criteria is resolved only at the time it is needed. + +Finally, the 'properties' are defined. +Each property has its unique name as the key and the definition as the value in the array. +Property names do not have to match the name of the column in the database. You can specify a different column name using an 'x-field' field; +Each property must have an OpenAPI 'type' defined. They may optionally define a specific 'format'. If no 'format' is specified, the generic format for that type will be used. +For example, a type of ``Doc\Schema::TYPE_STRING`` will default to the ``Doc\Schema::FORMAT_STRING_STRING`` format. +Properties may also optionally define a description for that property. + +In this example, the 'emails' property actually refers to multiple email addresses associated with the user. +The 'type' in this case is ``Doc\Schema::TYPE_ARRAY``. The schema for the individual items in defined inside the 'items' property. +Of course, email addresses are not stored in the same database table as users and are their own item type ``EmailAddress``. +Therefore, 'emails' is considered a joined object property. +In joined objects, we specify which properties will be included in the data but that can be a subset of the properties of the full schema (see :ref:`Partial vs Full Schema `). +The full schema can be specified using the 'x-full-schema' field. +The criteria for the join is specified in the 'x-join' field (more on that in the :ref:`Joins section `). + +Users have two password fields which we would never want to show via the API, but we do want them to exist in the schema to allow setting/resetting a password. +In this case, both 'password' and 'password2' have a 'x-writeonly' field present and set to true. + +The last property shown, 'picture', is an example of a mapped property. +In some cases, the data we want the user to see will differ from the raw value in the database. +In this example, pictures are stored as the path relative to the pictures folder such as '16/2_649182f5c5216.jpg'. +To a user of the API, this is useless. However, we can use that data to convert it to the front-end URL needed to access that picture such as '/front/document.send.php?file=_pictures/16/2_649182f5c5216.jpg'. +To accomplish this, mapped properties have the 'x-mapped-from' and 'x-mapper' fields. +'x-mapped-from' indicates the property we are mapping from. In this case, it maps from itself. +'x-mapper' is a callable that transforms the raw value to the display value. +The mapper used here takes the relative path and converts it to the front-end URL. It then handles returning the default user picture if it cannot get the user's specific picture. + +.. _partial_full_schema: + +Partial vs Full Schema +^^^^^^^^^^^^^^^^^^^^^^ + +A full schema is the defacto representation of an item in the API. +In some cases, we do not want every property for an item to be visible such as dropdown types related to a main item. +In ``Computer`` item we may show the ID and name of the computer's location, but the Location type itself has additional data like geolocation coordinates. +The partial schema contains only the properties needed for the user to know where to look for the full details and some basic information about it. + +.. _joins: + +Joins +^^^^^ + +Schemas may include data from tables other than the table for the main item. +Most of the item, joins are used in 'object' type properties such as when bringing in an ID and name for a dropdown type. +In some cases though, joins may be defined on scalar properties (not array or object). + +The information required to join data from outside of the main item's table is defined inside of an 'x-join' array. +The supported properties of the 'x-join' definition are: +- table: The database table to pull the data from +- fkey: The SQL field in the main table to use to identify which records in the other table are related +- field: The SQL field in the other table to match against the fkey. +- primary-property: Optional property which indicates the primary property of the foreign data. Typically, this is the 'id' field. + By default, the API will assume the field specified in 'field' is the primary property. If it isn't, it is required to specify it here. + In the User schema example, email addresses have a many-to-one relation with users. So, we use the user's ID field and match it against the 'users_id' field of the email addresses. + In that case, the 'field' is 'users_id' but the primary property is 'id', so we need to hint to the API that 'id' is still the primary property. +- ref-join: In some cases, there is no direct connection between the main item's table and the table with the data desired (typically seen with many-to-many relations). + In that case, a reference or in-between join can be specified. The 'ref_join' property follows the same format as 'x-join' except that you cannot have another 'ref_join'. + +Extension Properties +^^^^^^^^^^^^^^^^^^^^ + +Below is a complete list of supported extension fields/properties used in OpenAPI schemas. + +.. list-table:: Extension Properties + :widths: 25 50 25 25 + :header-rows: 1 + + * - Property + - Description + - Applicable Locations + - Visible in Swagger UI + * - x-controller + - Set and used internally by the OpenAPI documentation generator to track which controller defined the schema. + - Main schema + - Debug mode only + * - x-field + - Specifies the column that contains the data for the property if it differs from the property name. + - Schema properties + - Debug mode only + * - x-full-schema + - Indicates which schema is the full representation of the joined property. + This enables the accessing of properties not in the partial schema in certain conditions such as a GraphQL query. + - Schema join properties + - Yes + * - x-itemtype + - Specifies the PHP class related to the schema. + - Main schema + - Debug mode only + * - x-join + - Join definition. See Joins section for more information. + - Schema join properties + - Debug mode only + * - x-mapped-from + - Indicates the property to use with an 'x-mapper' to modify a value before returning it in an API response. + - Schema properties + - Debug mode only + * - x-mapper + - A callable that transforms the raw value specified by 'x-mapped-from' to the display value. + - Schema properties + - Debug mode only + * - x-readonly + - Specifies the property can only be read and not written to. + - Schema properties + - Yes + * - x-rights-conditions + - Array of arrays or callables that returns an array of SQL criteria for special visibility restrictions. Only 'read' restrictions are currently supported. + The type of restriction should be specified as the array key, and the callable or array as the value. + - Schema properties + - Debug mode only + * - x-subtypes + - Indicates array of arrays containing 'schema_name' and 'itemtype' properties. + This is used for unique cases where you want to allow searching across multiple schemas at once such as "All assets". + Typically you would find all shared properties between the different schemas and use that as the properties for this shared schema. + - Main schema + - Debug mode only + * - x-writeonly + - Specifies the property can only be written to and not read. + - Schema properties + - Yes \ No newline at end of file diff --git a/source/devapi/hlapi/search.rst b/source/devapi/hlapi/search.rst new file mode 100644 index 0000000..64f00da --- /dev/null +++ b/source/devapi/hlapi/search.rst @@ -0,0 +1,34 @@ +Search +====== + +As the High-Level API is decoupled from the PHP classes and search options system, a new search engine was developed to handle interacting with the database. +This new search engine exists in the ``\Glpi\Api\HL\Search`` class. +For simplicity, the search engine class also provides static methods to perform item creation, update and deletion in addition to the search/get actions. + +These entrypoint methods are: + +- getOneBySchema +- searchBySchema +- createBySchema +- updateBySchema +- deleteBySchema + +See the PHPDoc for each method for more information. + +While the standard search engine constructs a single database query to retreive item(s), the High-Level API takes multiple distinct steps and multiple queries to fetch and assemble the data given the potential complexity of schemas while keeping the schemas themselves relatively simple. + +The steps are: + +1. Initializing a new search. + This step consists of making a new instance of the ``\Glpi\Api\HL\Search`` class, generating a flattened array of properties (flattens properties where the keys are the full property name in dot notation to make lookups easier) in the schema and identifying joins. +2. Construct a request to get the 'dehydrated' result. + In this context, that means a result without all of the desired data. It only contains the identification data (the main item ID(s) and the IDs of joined records) and the scalar join values. + Each dehydrated result is an array where the keys are the primary ID field and any full join property name. The '.' in the names are replaced with 0x1F characters (Unit separator character) to avoid confusion about what is a table/field identifier. + In the case that a join property is for an array of items, the IDs are separated by a 0x1D character (Group separator character). + If there are no results for a specific join, a null byte character will be used. + The reason a dehydrated result is fetched first is that we don't need to either worry about grouping data or handling the multiple rows returned that relate to a single main item. +3. Hydrate each of the dehydrated results. In separate queries, the search engine will fetch the data for the main item and each join. + Each time a new record is fetched, it is stored in a separate array that acts like a cache to avoid fetching the same record twice. +4. Assemble the hydrated records into the final result(s). The search engine enumerates each property in the dehydrated result starting with the main item's ID and maps the hydrated data into a result that matches the expected schema. +5. Fixup the assembled records. Some post-processing is done after the record is fully assembled to clean some of the artifacts from the assembly process such as removing the keys for array type properties and replacing empty array values for object type properties with null. +6. Returning the result(s). \ No newline at end of file From 81d8b9edb9b430b3b8b135ff3150678e7402abeb Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Tue, 22 Aug 2023 11:05:11 -0400 Subject: [PATCH 04/26] basic vue docs --- source/devapi/index.rst | 1 + source/devapi/javascript.rst | 53 ++++++++++++++++ source/plugins/index.rst | 1 + source/plugins/javascript.rst | 110 ++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+) create mode 100644 source/devapi/javascript.rst create mode 100644 source/plugins/javascript.rst diff --git a/source/devapi/index.rst b/source/devapi/index.rst index aa6ab37..e8d1929 100644 --- a/source/devapi/index.rst +++ b/source/devapi/index.rst @@ -15,4 +15,5 @@ Apart from the current documentation, you can also generate the full PHP documen acl crontasks tools + javascript extra diff --git a/source/devapi/javascript.rst b/source/devapi/javascript.rst new file mode 100644 index 0000000..69aeff0 --- /dev/null +++ b/source/devapi/javascript.rst @@ -0,0 +1,53 @@ +Javascript +========== + +Vue.js +------ + +Starting in GLPI 10.1, we have added support for Vue. +.. note:: + + Only SFCs (Single-file Components) using the Components API is supported. Do not use the Options API. + +To ease integration, there is no Vue app mounted on the page body itself. Instead, each specific feature that uses Vue such as the debug toolbar mounts its own Vue app on a container element. +Components must all be located in the ``js/src/vue`` folder for them to be built. +Components should be grouped into subfolders as a sort of namespace separation. +There are some helpers stored in the ``window.Vue`` global to help manage components and mount apps. + +### Building + +Two npm commands exist which can be used to build or watch (auto-build when the sources change) the Vue components. + +.. code-block:: bash + + npm run build:vue + +.. code-block:: bash + + npm run watch:vue + + +The ``npm run build`` command will also build the Vue components in addition to the regular JS bundles. + +To improve performance, the components are not built into a single file. Instead, webpack chunking is utilized. +This results a single smaller entrypoint ``app.js`` being generated and a separate file for each component. +The components that are automatically built utilize ``defineAsyncComponent`` to enable the loading of those components on demand. + +Further optimizations can be done by directly including a Vue component inside a main component to ensure it is built into the main component's chunk to reduce the number of requests. +This could be useful if the component wouldn't be reused elsewhere. Just note that the child component would also have its own chunk generated since there is no way to exclude it. + +### Mounting + +The Vue `createApp` function can be located at `window.Vue.createApp`. +Each automatically built component is automatically tracked in `window.Vue.components`. + +To create an app and mount a component, you can use the following code: + +.. code-block:: javascript + + const app = window.Vue.createApp(window.Vue.components['Debug/Toolbar'].component); + app.mount('#my-app-wrapper'); + +Replace ``Debug/Toolbar`` with the relative path to your component without the ``.vue`` extension and ``#my-app-wrapper`` with an ID selector for the wrapper element which would need to already existing in the DOM. + +For more information about Vue, please refer to the `official documentation `_. \ No newline at end of file diff --git a/source/plugins/index.rst b/source/plugins/index.rst index 4502662..b115ad6 100644 --- a/source/plugins/index.rst +++ b/source/plugins/index.rst @@ -26,3 +26,4 @@ If you want to see more advanced examples of what it is possible to do with plug tips notifications test + javascript diff --git a/source/plugins/javascript.rst b/source/plugins/javascript.rst new file mode 100644 index 0000000..5a8c3db --- /dev/null +++ b/source/plugins/javascript.rst @@ -0,0 +1,110 @@ +Javascript +========== + +Vue.js +------ + +Please refer to :doc:`the core Vue developer documentation first <../devapi/javascript>`. + +Plugins that wish to use custom Vue components must implement their own webpack config to build the components and add them to the `window.Vue.components` object. + +Sample webpack config (derived from the config used in GLPI itself for Vue): +.. code-block:: javascript + + const webpack = require('webpack'); + const path = require('path'); + const VueLoaderPlugin = require('vue-loader').VueLoaderPlugin; + + const config = { + entry: { + 'vue': './js/src/vue/app.js', + }, + externals: { + // prevent duplicate import of Vue library (already done in ../../public/build/vue/app.js) + vue: 'import vue', + }, + output: { + filename: 'app.js', + chunkFilename: "[name].js", + chunkFormat: 'module', + path: path.resolve(__dirname, 'public/build/vue'), + publicPath: '/public/build/vue/', + asyncChunks: true, + clean: true, + }, + module: { + rules: [ + { + // Vue SFC + test: /\.vue$/, + loader: 'vue-loader' + }, + { + // Build styles + test: /\.css$/, + use: ['style-loader', 'css-loader'], + }, + ] + }, + plugins: [ + new VueLoaderPlugin(), // Vue SFC support + new webpack.ProvidePlugin( + { + process: 'process/browser' + } + ), + new webpack.DefinePlugin({ + __VUE_OPTIONS_API__: false, // We will only use composition API + __VUE_PROD_DEVTOOLS__: false, + }), + ], + resolve: { + fallback: { + 'process/browser': require.resolve('process/browser.js') + }, + }, + mode: 'none', // Force 'none' mode, as optimizations will be done on release process + devtool: 'source-map', // Add sourcemap to files + stats: { + // Limit verbosity to only usefull information + all: false, + errors: true, + errorDetails: true, + warnings: true, + + entrypoints: true, + timings: true, + }, + target: "es2020" + }; + + module.exports = config + +Note the use of the ``externals`` option. This will prevent webpack from including Vue itself when building your components since it is already imported by the bundle in GLPI itself. +This will drastically reduce the size of your imports. + +For your entrypoint, it is mostly the same as the core GLPi one except you should use the ``defineAsyncComponent`` method in ``window.Vue`` instead of importing it from Vue itself. + +Example entrypoint: + +.. code-block:: javascript + + // Require all Vue SFCs in js/src directory + const component_context = import.meta.webpackContext('.', { + regExp: /\.vue$/i, + recursive: true, + mode: 'lazy', + chunkName: '/vue-sfc/[request]' + }); + const components = {}; + component_context.keys().forEach((f) => { + const component_name = f.replace(/^\.\/(.+)\.vue$/, '$1'); + components[component_name] = { + component: window.Vue.defineAsyncComponent(() => component_context(f)), + }; + }); + // Save components in global scope + window.Vue.components = Object.assign(window.Vue.components || {}, components); + +To keep your components from colliding with core components or other plugins, it you should organize them inside the `js/src/Plugin/Yourplugin` folder. +This will ensure plugin components are registered as ``Plugin/Yourplugin/YourComponent``. You can organize components further with additional subfolders. \ No newline at end of file From 8dbee57f20c1420b816ba5bdd04b817d8b6cbd22 Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Tue, 22 Aug 2023 15:08:39 -0400 Subject: [PATCH 05/26] update external requirement --- source/plugins/javascript.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/plugins/javascript.rst b/source/plugins/javascript.rst index 5a8c3db..3bf7a25 100644 --- a/source/plugins/javascript.rst +++ b/source/plugins/javascript.rst @@ -21,7 +21,7 @@ Sample webpack config (derived from the config used in GLPI itself for Vue): }, externals: { // prevent duplicate import of Vue library (already done in ../../public/build/vue/app.js) - vue: 'import vue', + vue: 'window _vue', }, output: { filename: 'app.js', @@ -81,9 +81,10 @@ Sample webpack config (derived from the config used in GLPI itself for Vue): module.exports = config Note the use of the ``externals`` option. This will prevent webpack from including Vue itself when building your components since it is already imported by the bundle in GLPI itself. +The core GLPI bundle sets ``window._vue`` to the vue module and the plugin's externals option will map any imports from 'vue' to that. This will drastically reduce the size of your imports. -For your entrypoint, it is mostly the same as the core GLPi one except you should use the ``defineAsyncComponent`` method in ``window.Vue`` instead of importing it from Vue itself. +For your entrypoint, it is mostly the same as the core GLPI one except you should use the ``defineAsyncComponent`` method in ``window.Vue`` instead of importing it from Vue itself. Example entrypoint: From 0b0df275f9a5d1b2b687bbbeebb5d432673acbb6 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Mon, 15 Apr 2024 16:17:15 +0200 Subject: [PATCH 06/26] Missing in ToC --- source/devapi/index.rst | 1 + source/index.rst | 2 +- source/upgradeguides/index.rst | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/devapi/index.rst b/source/devapi/index.rst index e8d1929..6e4c851 100644 --- a/source/devapi/index.rst +++ b/source/devapi/index.rst @@ -9,6 +9,7 @@ Apart from the current documentation, you can also generate the full PHP documen mainobjects database/index search + hlapi/index massiveactions rules translations diff --git a/source/index.rst b/source/index.rst index 33a8e48..61f10f1 100644 --- a/source/index.rst +++ b/source/index.rst @@ -19,7 +19,7 @@ GLPI Developer Documentation checklists/index plugins/index packaging - upgradeguides + upgradeguides/index If you want to help us improve the current documentation, feel free to open pull requests! You can `see open issues `_ and `join the documentation mailing list `_. diff --git a/source/upgradeguides/index.rst b/source/upgradeguides/index.rst index e5dad36..5d5c526 100644 --- a/source/upgradeguides/index.rst +++ b/source/upgradeguides/index.rst @@ -10,3 +10,5 @@ The upgrade guides are intended to help you adapt your plugins to the changes in .. toctree:: :maxdepth: 2 + + glpi-10.1 From 67f0370196645b56d25061fd4254bc3d884edc0d Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Mon, 15 Apr 2024 16:18:53 +0200 Subject: [PATCH 07/26] Fix syntax --- source/devapi/hlapi/schemas.rst | 13 +++++++------ source/plugins/javascript.rst | 3 ++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/source/devapi/hlapi/schemas.rst b/source/devapi/hlapi/schemas.rst index ad7b6d6..3c4f333 100644 --- a/source/devapi/hlapi/schemas.rst +++ b/source/devapi/hlapi/schemas.rst @@ -177,14 +177,15 @@ In some cases though, joins may be defined on scalar properties (not array or ob The information required to join data from outside of the main item's table is defined inside of an 'x-join' array. The supported properties of the 'x-join' definition are: -- table: The database table to pull the data from -- fkey: The SQL field in the main table to use to identify which records in the other table are related -- field: The SQL field in the other table to match against the fkey. -- primary-property: Optional property which indicates the primary property of the foreign data. Typically, this is the 'id' field. + +* table: The database table to pull the data from +* fkey: The SQL field in the main table to use to identify which records in the other table are related +* field: The SQL field in the other table to match against the fkey. +* primary-property: Optional property which indicates the primary property of the foreign data. Typically, this is the 'id' field. By default, the API will assume the field specified in 'field' is the primary property. If it isn't, it is required to specify it here. In the User schema example, email addresses have a many-to-one relation with users. So, we use the user's ID field and match it against the 'users_id' field of the email addresses. In that case, the 'field' is 'users_id' but the primary property is 'id', so we need to hint to the API that 'id' is still the primary property. -- ref-join: In some cases, there is no direct connection between the main item's table and the table with the data desired (typically seen with many-to-many relations). +* ref-join: In some cases, there is no direct connection between the main item's table and the table with the data desired (typically seen with many-to-many relations). In that case, a reference or in-between join can be specified. The 'ref_join' property follows the same format as 'x-join' except that you cannot have another 'ref_join'. Extension Properties @@ -247,4 +248,4 @@ Below is a complete list of supported extension fields/properties used in OpenAP * - x-writeonly - Specifies the property can only be written to and not read. - Schema properties - - Yes \ No newline at end of file + - Yes diff --git a/source/plugins/javascript.rst b/source/plugins/javascript.rst index 3bf7a25..ee6c78f 100644 --- a/source/plugins/javascript.rst +++ b/source/plugins/javascript.rst @@ -9,6 +9,7 @@ Please refer to :doc:`the core Vue developer documentation first <../devapi/java Plugins that wish to use custom Vue components must implement their own webpack config to build the components and add them to the `window.Vue.components` object. Sample webpack config (derived from the config used in GLPI itself for Vue): + .. code-block:: javascript const webpack = require('webpack'); @@ -108,4 +109,4 @@ Example entrypoint: window.Vue.components = Object.assign(window.Vue.components || {}, components); To keep your components from colliding with core components or other plugins, it you should organize them inside the `js/src/Plugin/Yourplugin` folder. -This will ensure plugin components are registered as ``Plugin/Yourplugin/YourComponent``. You can organize components further with additional subfolders. \ No newline at end of file +This will ensure plugin components are registered as ``Plugin/Yourplugin/YourComponent``. You can organize components further with additional subfolders. From 0c343df96ddae4062cc67f020d5c42e5115749a7 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Tue, 16 Apr 2024 13:43:41 +0200 Subject: [PATCH 08/26] Iterator syntax (among other) * Array syntax is now enforced * A word about criteria unicity * Warning about raw queries --- source/devapi/database/dbiterator.rst | 227 +++++++++++++++----------- source/upgradeguides/glpi-10.1.rst | 20 +++ 2 files changed, 153 insertions(+), 94 deletions(-) diff --git a/source/devapi/database/dbiterator.rst b/source/devapi/database/dbiterator.rst index 787c8cf..21febf3 100644 --- a/source/devapi/database/dbiterator.rst +++ b/source/devapi/database/dbiterator.rst @@ -5,6 +5,7 @@ GLPI framework provides a simple request generator: * without having to write SQL * without having to quote table and field name +* without having to escape values to prevent SQL injections * without having to take care of freeing resources * iterable * countable @@ -32,32 +33,12 @@ Basic usage Arguments ^^^^^^^^^ -The ``request`` method takes two arguments: +The ``request`` method takes as argument an array of criteria with explicit SQL clauses (``FROM``, ``WHERE`` and so on) -* `table name(s)`: a `string` or an `array` of `string` - (optional when given as ``FROM`` option) -* `option(s)`: `array` of options - - -Giving full SQL statement -^^^^^^^^^^^^^^^^^^^^^^^^^ - -If the only option is a full SQL statement, it will be used. -This usage is deprecated, and should be avoid when possible. - -.. note:: - - To make a database query that could not be done using recommanded way (calling SQL functions such as ``NOW()``, ``ADD_DATE()``, ... for example), you can do: - - .. code-block:: php - - request('SELECT id FROM glpi_users WHERE end_date > NOW()'); - -Without option -^^^^^^^^^^^^^^ +FROM clause +^^^^^^^^^^^ -In this case, all the data from the selected table is iterated: +The SQL ``FROM`` clause can be a string or an array of strings: .. code-block:: php @@ -65,35 +46,23 @@ In this case, all the data from the selected table is iterated: $DB->request(['FROM' => 'glpi_computers']); // => SELECT * FROM `glpi_computers` - $DB->request('glpi_computers'); - // => SELECT * FROM `glpi_computers` + $DB->request(['FROM' => ['glpi_computers', 'glpi_monitors']); + // => SELECT * FROM `glpi_computers`, `glpi_monitors` Fields selection ^^^^^^^^^^^^^^^^ You can use either the ``SELECT`` or ``FIELDS`` options, an additional ``DISTINCT`` option might be specified. -.. note:: - - .. versionchanged:: 9.5.0 - - Using ``DISTINCT FIELDS`` or ``SELECT DISTINCT`` options is deprecated. - .. code-block:: php request(['SELECT' => 'id', 'FROM' => 'glpi_computers']); // => SELECT `id` FROM `glpi_computers` - $DB->request('glpi_computers', ['FIELDS' => 'id']); - // => SELECT `id` FROM `glpi_computers` - $DB->request(['SELECT' => 'name', 'DISTINCT' => true, 'FROM' => 'glpi_computers']); // => SELECT DISTINCT `name` FROM `glpi_computers` - $DB->request('glpi_computers', ['FIELDS' => 'name', 'DISTINCT' => true]); - // => SELECT DISTINCT `name` FROM `glpi_computers` - The fields array can also contain per table sub-array: .. code-block:: php @@ -105,42 +74,27 @@ The fields array can also contain per table sub-array: Using JOINs ^^^^^^^^^^^ -You need to use criteria, usually a ``FKEY`` to describe how to join the tables. - -.. note:: - - .. versionadded:: 9.3.1 - - The ``ON`` keyword can aslo be used as an alias of ``FKEY``. - -Multiple tables, native join -++++++++++++++++++++++++++++ - -You need to use criteria, usually a ``FKEY`` (or the ``ON`` equivalent), to describe how to join the tables: - -.. code-block:: php - - request(['FROM' => ['glpi_computers', 'glpi_computerdisks'], - 'FKEY' => ['glpi_computers'=>'id', - 'glpi_computerdisks'=>'computer_id']]); - $DB->request(['glpi_computers', 'glpi_computerdisks'], - ['FKEY' => ['glpi_computers'=>'id', - 'glpi_computerdisks'=>'computer_id']]); - // => SELECT * FROM `glpi_computers`, `glpi_computerdisks` - // WHERE `glpi_computers`.`id` = `glpi_computerdisks`.`computer_id` +You need to use criteria, usually a ``ON`` (or the ``FKEY`` equivalent), to describe how to join the tables. Left join +++++++++ -Using the ``LEFT JOIN`` option, with some criteria, usually a ``FKEY`` (or the ``ON`` equivalent): +Using the ``LEFT JOIN`` option, with some criteria: .. code-block:: php request(['FROM' => 'glpi_computers', - 'LEFT JOIN' => ['glpi_computerdisks' => ['FKEY' => ['glpi_computers' => 'id', - 'glpi_computerdisks' => 'computer_id']]]]); + $DB->request([ + 'FROM' => 'glpi_computers', + 'LEFT JOIN' => [ + 'glpi_computerdisks' => [ + 'ON' => [ + 'glpi_computers' => 'id', + 'glpi_computerdisks' => 'computer_id' + ] + ] + ] + ]); // => SELECT * FROM `glpi_computers` // LEFT JOIN `glpi_computerdisks` // ON (`glpi_computers`.`id` = `glpi_computerdisks`.`computer_id`) @@ -148,14 +102,22 @@ Using the ``LEFT JOIN`` option, with some criteria, usually a ``FKEY`` (or the ` Inner join ++++++++++ -Using the ``INNER JOIN`` option, with some criteria, usually a ``FKEY`` (or the ``ON`` equivalent): +Using the ``INNER JOIN`` option, with some criteria: .. code-block:: php request(['FROM' => 'glpi_computers', - 'INNER JOIN' => ['glpi_computerdisks' => ['FKEY' => ['glpi_computers' => 'id', - 'glpi_computerdisks' => 'computer_id']]]]); + $DB->request([ + 'FROM' => 'glpi_computers', + 'INNER JOIN' => [ + 'glpi_computerdisks' => [ + 'ON' => [ + 'glpi_computers' => 'id', + 'glpi_computerdisks' => 'computer_id' + ] + ] + ] + ]); // => SELECT * FROM `glpi_computers` // INNER JOIN `glpi_computerdisks` // ON (`glpi_computers`.`id` = `glpi_computerdisks`.`computer_id`) @@ -163,14 +125,22 @@ Using the ``INNER JOIN`` option, with some criteria, usually a ``FKEY`` (or the Right join ++++++++++ -Using the ``RIGHT JOIN`` option, with some criteria, usually a ``FKEY`` (or the ``ON`` equivalent): +Using the ``RIGHT JOIN`` option, with some criteria: .. code-block:: php request(['FROM' => 'glpi_computers', - 'RIGHT JOIN' => ['glpi_computerdisks' => ['FKEY' => ['glpi_computers' => 'id', - 'glpi_computerdisks' => 'computer_id']]]]); + $DB->request([ + 'FROM' => 'glpi_computers', + 'RIGHT JOIN' => [ + 'glpi_computerdisks' => [ + 'ON' => [ + 'glpi_computers' => 'id', + 'glpi_computerdisks' => 'computer_id' + ] + ] + ] + ]); // => SELECT * FROM `glpi_computers` // RIGHT JOIN `glpi_computerdisks` // ON (`glpi_computers`.`id` = `glpi_computerdisks`.`computer_id`) @@ -189,7 +159,7 @@ It is also possible to add an extra criterion for any `JOIN` clause. You have to 'FROM' => 'glpi_computers', 'INNER JOIN' => [ 'glpi_computerdisks' => [ - 'FKEY' => [ + 'ON' => [ 'glpi_computers' => 'id', 'glpi_computerdisks' => 'computer_id', ['OR' => ['glpi_computers.field' => ['>', 42]]] @@ -275,9 +245,6 @@ Using the ``GROUPBY`` option, which contains a field name or an array of field n $DB->request(['FROM' => 'glpi_computers', 'GROUPBY' => 'name']); // => SELECT * FROM `glpi_computers` GROUP BY `name` - $DB->request('glpi_computers', ['GROUPBY' => ['name', 'states_id']]); - // => SELECT * FROM `glpi_computers` GROUP BY `name`, `states_id` - Order ^^^^^ @@ -289,9 +256,6 @@ Using the ``ORDER`` option, with value a field or an array of fields. Field name $DB->request(['FROM' => 'glpi_computers', 'ORDER' => 'name']); // => SELECT * FROM `glpi_computers` ORDER BY `name` - $DB->request('glpi_computers', ['ORDER' => ['date_mod DESC', 'name ASC']]); - // => SELECT * FROM `glpi_computers` ORDER BY `date_mod` DESC, `name` ASC - Request pager ^^^^^^^^^^^^^ @@ -324,11 +288,10 @@ A field name and its wanted value: $DB->request(['FROM' => 'glpi_computers', 'WHERE' => ['is_deleted' => 0]]); // => SELECT * FROM `glpi_computers` WHERE `is_deleted` = 0 - $DB->request('glpi_computers', ['is_deleted' => 0, - 'name' => 'foo']); + $DB->request(['FROM' => 'glpi_computers', 'WHERE' => ['is_deleted' => 0, 'name' => 'foo']]); // => SELECT * FROM `glpi_computers` WHERE `is_deleted` = 0 AND `name` = 'foo' - $DB->request('glpi_computers', ['users_id' => [1,5,7]]); + $DB->request('FROM' => 'glpi_computers', 'WHERE' => ['users_id' => [1,5,7]]]); // => SELECT * FROM `glpi_computers` WHERE `users_id` IN (1, 5, 7) Logical ``OR``, ``AND``, ``NOT`` @@ -339,11 +302,25 @@ Using the ``OR``, ``AND``, or ``NOT`` option with an array of criteria: .. code-block:: php request('glpi_computers', ['OR' => ['is_deleted' => 0, - 'name' => 'foo']]); + $DB->request([ + 'FROM' => 'glpi_computers', + 'WHERE' => [ + 'OR' => [ + 'is_deleted' => 0, + 'name' => 'foo' + ] + ] + ]); // => SELECT * FROM `glpi_computers` WHERE (`is_deleted` = 0 OR `name` = 'foo')" - $DB->request('glpi_computers', ['NOT' => ['id' => [1,2,7]]]); + $DB->request([ + 'FROM' => 'glpi_computers', + 'WHERE' => [ + 'NOT' => [ + 'id' => [1, 2, 7] + ] + ] + ]); // => SELECT * FROM `glpi_computers` WHERE NOT (`id` IN (1, 2, 7)) @@ -352,12 +329,57 @@ Using a more complex expression with ``AND`` and ``OR``: .. code-block:: php request('glpi_computers', ['is_deleted' => 0, - ['OR' => ['name' => 'foo', 'otherserial' => 'otherunique']], - ['OR' => ['locations_id' => 1, 'serial' => 'unique']] + $DB->request([ + 'FROM' => 'glpi_computers', + 'WHERE' => [ + 'is_deleted' => 0, + ['OR' => ['name' => 'foo', 'otherserial' => 'otherunique']], + ['OR' => ['locations_id' => 1, 'serial' => 'unique']] + ] ]); // => SELECT * FROM `glpi_computers` WHERE `is_deleted` = '0' AND ((`name` = 'foo' OR `otherserial` = 'otherunique')) AND ((`locations_id` = '1' OR `serial` = 'unique')) +Criteria unicity +++++++++++++++++ + + +Indexed array entries must be unique; otherwise PHP will only take the last one. The following example is incorrect: + +.. code-block:: php + + request([ + 'FROM' => 'glpi_computers', + 'WHERE' => [ + [ + 'OR' => [ + 'name' => 'a name', + 'name' => 'another name' + ] + ], + ] + ]); + // => SELECT * FROM `glpi_computers` WHERE `name` = 'another name' + +The right way would be to enclose each condition in another array, like: + +.. code-block:: php + + request([ + 'FROM' => 'glpi_computers', + 'WHERE' => [ + [ + 'OR' => [ + ['name' => 'a name'], + ['name' => 'another name'] + ] + ], + ] + ]); + // => SELECT * FROM `glpi_computers` WHERE (`name = 'a name' OR `name` = 'another name') + + Operators +++++++++ @@ -366,10 +388,15 @@ Default operator is ``=``, but other operators can be used, by giving an array c .. code-block:: php request('glpi_computers', ['date_mod' => ['>' , '2016-10-01']]); + $DB->request([ + 'FROM' => 'glpi_computers', + 'WHERE' => [ + 'date_mod' => ['>' , '2016-10-01'] + ] + ]); // => SELECT * FROM `glpi_computers` WHERE `date_mod` > '2016-10-01' - $DB->request('glpi_computers', ['name' => ['LIKE' , 'pc00%']]); + $DB->request(['FROM' => 'glpi_computers', 'WHERE' => ['name' => ['LIKE' , 'pc00%']]]); // => SELECT * FROM `glpi_computers` WHERE `name` LIKE 'pc00%' Known operators are ``=``, ``!=``, ``<``, ``<=``, ``>``, ``>=``, ``LIKE``, ``REGEXP``, ``NOT LIKE``, ``NOT REGEX``, ``&`` (BITWISE AND), and ``|`` (BITWISE OR). @@ -382,7 +409,7 @@ You can use SQL aliases (SQL ``AS`` keyword). To achieve that, just write the al .. code-block:: php request('glpi_computers AS c'); + $DB->request(['FROM' => 'glpi_computers AS c']); // => SELECT * FROM `glpi_computers` AS `c` $DB->request(['SELECT' => 'field AS f', 'FROM' => 'glpi_computers AS c']); @@ -515,7 +542,7 @@ You can use a QueryExpression object in the FIELDS statement: 'FROM' => 'glpi_computers', 'LEFT JOIN' => [ 'glpi_domains' => [ - 'FKEY' => [ + 'ON' => [ 'glpi_computers' => 'domains_id', 'glpi_domains' => 'id', ] @@ -533,3 +560,15 @@ You can use a QueryExpression object in the FROM statement: 'FROM' => new QueryExpression('(SELECT * FROM glpi_computers) as computers'), ]); // => SELECT * FROM (SELECT * FROM glpi_computers) as computers + +.. warning:: + + If you really cannot use any of the above, you still can make raw SQL queries: + + .. code-block:: php + + doQuery('SHOW COLUMNS FROM ' . $DB::quoteName('glpi_computers')); + + **You have to ensure the query is proprely escaped!** + diff --git a/source/upgradeguides/glpi-10.1.rst b/source/upgradeguides/glpi-10.1.rst index 7ddabd8..548916b 100644 --- a/source/upgradeguides/glpi-10.1.rst +++ b/source/upgradeguides/glpi-10.1.rst @@ -53,3 +53,23 @@ Also, code that ouputs javascript must be adapted to prevent XSS with both HTML + $(body).append(json_encode('

' . htmlspecialchars($content) . '

')); '; + +Query builder usage ++++++++++++++++++++ + +Since it has been implemented, internal query builder (named `DBMysqlIterator`) do accept several syntaxes; that make things complex: + +1. conditions (including table name as `FROM` array key) as first (and only) parameter. +2. table name as first parameter and condition as second parameter, +3. raw SQL queries, + +The most used and easiest to maintain was the first. The second has been deprecated and the thrird has been prohibited or security reasons. + +I you were using the second syntax, you will need to replace as follows: + +.. code-block:: diff + + - $iterator = $DB->request('mytable', ['field' => 'condition']); + + $iterator = $DB->request(['FROM' => 'mytable', 'WHERE' => ['field' => 'condition']]); + +Using raw SQL queries must be replaced with query builder call, among other to prevent syntax issues, and SQL injections; please refer to :doc:devapi/database/dbiterator. From d4cb9b32b2f7d417c17bc41e080ebc2093fb18a0 Mon Sep 17 00:00:00 2001 From: Stanislas Date: Tue, 17 Sep 2024 09:55:26 +0200 Subject: [PATCH 09/26] add doc for new hook pre/post_itil_info_section --- source/plugins/hooks.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/source/plugins/hooks.rst b/source/plugins/hooks.rst index 13d94c7..a8738d2 100644 --- a/source/plugins/hooks.rst +++ b/source/plugins/hooks.rst @@ -124,7 +124,7 @@ These hooks will work just as the :ref:`hooks with item as parameter ``. + + +``post_itil_info_section`` + .. versionadded:: 11 + + After displaying ITIL object sections (ticket, Change, Problem) Waits for a ``
``. + ``pre_item_form`` .. versionadded:: 9.1.2 From 8c6024a29c8b88b9a381a2a67c853fabe2d1597e Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Thu, 1 Aug 2024 15:18:39 -0400 Subject: [PATCH 10/26] add hlapi versioning info --- source/devapi/hlapi/index.rst | 1 + source/devapi/hlapi/schemas.rst | 13 +++++++++++++ source/devapi/hlapi/versioning.rst | 30 ++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 source/devapi/hlapi/versioning.rst diff --git a/source/devapi/hlapi/index.rst b/source/devapi/hlapi/index.rst index 1b30ae1..69fbfcb 100644 --- a/source/devapi/hlapi/index.rst +++ b/source/devapi/hlapi/index.rst @@ -11,3 +11,4 @@ These sections are sorted by the recommended reading order. It is recommended th schemas search + versioning diff --git a/source/devapi/hlapi/schemas.rst b/source/devapi/hlapi/schemas.rst index 3c4f333..36e4566 100644 --- a/source/devapi/hlapi/schemas.rst +++ b/source/devapi/hlapi/schemas.rst @@ -20,6 +20,7 @@ Let's look at a partial version of the schema definition for a User since it sho .. code-block:: php 'User' => [ + 'x-version-introduced' => '2.0.0', 'x-itemtype' => User::class, 'type' => Doc\Schema::TYPE_OBJECT, 'x-rights-conditions' => [ // Object-level extra permissions @@ -214,6 +215,18 @@ Below is a complete list of supported extension fields/properties used in OpenAP This enables the accessing of properties not in the partial schema in certain conditions such as a GraphQL query. - Schema join properties - Yes + * - x-version-introduced + - Indicates which API version the schema or property first becomes available in. This is required for all schemas. Any individual properties without this will use the introduction version from the schema. + - Main schema and schema properties + - Yes + * - x-version-deprecated + - Indicates which API version the schema or property becomes deprecated in. Any individual properties without this will use the deprecated version from the schema if specified. + - Main schema and schema properties + - Yes + * - x-version-removed + - Indicates which API version the schema or property becomes removed in. Any individual properties without this will use the removed version from the schema if specified. + - Main schema and schema properties + - Yes * - x-itemtype - Specifies the PHP class related to the schema. - Main schema diff --git a/source/devapi/hlapi/versioning.rst b/source/devapi/hlapi/versioning.rst new file mode 100644 index 0000000..64962dd --- /dev/null +++ b/source/devapi/hlapi/versioning.rst @@ -0,0 +1,30 @@ +Versioning +========== + +The High-Level API will actively filter the routes and schema definitions based on the API version requested by the user (or default to the latest API version). +The version being used is stored by the router in a `GLPI-API-Version` header in the request after being normalized based on version pinning rules (See the getting started documentation for the High-Level API). +Controllers that extend `Glpi\Api\HL\Controller\AbstractController` can pass the request to the `getAPIVersion` helper function to get the API version. + + +Route Versions +^^^^^^^^^^^^^^ + +All routes must have a `Glpi\Api\HL\RouteVersion` attribute present. +This attribute allows specifying an introduction, deprecated, and removal version. +The introduction version is required. + +When the router attempts to match a request to a route, it will take the versions specified on each route into account. +So if a user requests API version 3, routes introduced in v4 will not be considered. +Additionally, routes removed in v3 will also not be considered. +Deprecation versions do not affect the route matching logic. + +Schema Versions +^^^^^^^^^^^^^^^ + +All schemas must have a `x-version-introduced` property present. +They may also have `x-version-deprecated` and `x-version-removed` properties if applicable. +Individual properties within schemas may declare these version properties as well, but will use the versions from the schema itself if not. + +When schemas are requested from each controller, they will be filtered based on the API version requested by the user (or default to the latest API version). +If the versions on a schema make it inapplicable to the requested version, it is not returned at all from the controller. +If the schema itself is applicable, each property is evaluated and inapplicable properties are removed. \ No newline at end of file From 5b0794790ba69e10e6ac54ad448638fbcf91d46e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Wed, 25 Sep 2024 12:37:35 +0200 Subject: [PATCH 11/26] Add routing changes section to the GLPI 11.0 upgrade guidelines --- .../{glpi-10.1.rst => glpi-11.0.rst} | 45 ++++++++++++++++--- source/upgradeguides/index.rst | 2 +- 2 files changed, 40 insertions(+), 7 deletions(-) rename source/upgradeguides/{glpi-10.1.rst => glpi-11.0.rst} (60%) diff --git a/source/upgradeguides/glpi-10.1.rst b/source/upgradeguides/glpi-11.0.rst similarity index 60% rename from source/upgradeguides/glpi-10.1.rst rename to source/upgradeguides/glpi-11.0.rst index 548916b..42bb1bb 100644 --- a/source/upgradeguides/glpi-10.1.rst +++ b/source/upgradeguides/glpi-11.0.rst @@ -1,14 +1,14 @@ -Upgrade to GLPI 10.1 +Upgrade to GLPI 11.0 -------------------- Removal of input variables auto-sanitize ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Prior to GLPI 10.1, PHP superglobals ``$_GET``, ``$_POST`` and ``$_REQUEST`` were automatically sanitized. +Prior to GLPI 11.0, PHP superglobals ``$_GET``, ``$_POST`` and ``$_REQUEST`` were automatically sanitized. It means that SQL special characters were escaped (prefixed by a ``\``), and HTML special characters ``<``, ``>`` and ``&`` were encoded into HTML entities. This caused issues because it was difficult, for some pieces of code, to know if the received variables were "secure" or not. -In GLPI 10.1, we removed this auto-sanitization, and any data, whether it comes from a form, the database, or the API, will always be in its raw state. +In GLPI 11.0, we removed this auto-sanitization, and any data, whether it comes from a form, the database, or the API, will always be in its raw state. Protection against SQL injection ++++++++++++++++++++++++++++++++ @@ -57,15 +57,15 @@ Also, code that ouputs javascript must be adapted to prevent XSS with both HTML Query builder usage +++++++++++++++++++ -Since it has been implemented, internal query builder (named `DBMysqlIterator`) do accept several syntaxes; that make things complex: +Since it has been implemented, internal query builder (named ``DBMysqlIterator``) do accept several syntaxes; that make things complex: -1. conditions (including table name as `FROM` array key) as first (and only) parameter. +1. conditions (including table name as ``FROM`` array key) as first (and only) parameter. 2. table name as first parameter and condition as second parameter, 3. raw SQL queries, The most used and easiest to maintain was the first. The second has been deprecated and the thrird has been prohibited or security reasons. -I you were using the second syntax, you will need to replace as follows: +If you were using the second syntax, you will need to replace as follows: .. code-block:: diff @@ -73,3 +73,36 @@ I you were using the second syntax, you will need to replace as follows: + $iterator = $DB->request(['FROM' => 'mytable', 'WHERE' => ['field' => 'condition']]); Using raw SQL queries must be replaced with query builder call, among other to prevent syntax issues, and SQL injections; please refer to :doc:devapi/database/dbiterator. + +Changes related to URLs routing +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Crafting plugins URLs ++++++++++++++++++++++ + +In GLPI 11.0, we changed the way to handle URLs to plugin resources so that they no longer need to reflect the location of the plugin on the file system. +For instance, the same URL could be used to access a plugin file whether it was installed manually in the ``/plugins`` directory or via the marketplace. + +The ``Plugin::getWebDir()`` PHP method has been deprecated. + +.. code-block:: diff + + - $path = Plugin::getWebDir('myplugin', false) . '/front/myscript.php'; + + $path = '/plugins/myplugin/front/myscript.php'; + + - $path = Plugin::getWebDir('myplugin', true) . '/front/myscript.php'; + + $path = $CFG_GLPI['root_doc'] . '/plugins/myplugin/front/myscript.php'; + +The ``GLPI_PLUGINS_PATH`` javascript variable has been deprecated. + +.. code-block:: diff + + - var url = CFG_GLPI.root_doc + '/' + GLPI_PLUGINS_PATH.myplugin + '/ajax/script.php'; + + var url = CFG_GLPI.root_doc + '/plugins/myplugin/ajax/script.php'; + +The ``get_plugin_web_dir`` Twig function has been deprecated. + +.. code-block:: diff + + -
+ + diff --git a/source/upgradeguides/index.rst b/source/upgradeguides/index.rst index 5d5c526..cafed5a 100644 --- a/source/upgradeguides/index.rst +++ b/source/upgradeguides/index.rst @@ -11,4 +11,4 @@ The upgrade guides are intended to help you adapt your plugins to the changes in .. toctree:: :maxdepth: 2 - glpi-10.1 + glpi-11.0 From 291aa87c604e14c6442b8c5314447351c132f466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Wed, 25 Sep 2024 15:44:49 +0200 Subject: [PATCH 12/26] A mention about support of /markeplace URLs --- source/upgradeguides/glpi-11.0.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/upgradeguides/glpi-11.0.rst b/source/upgradeguides/glpi-11.0.rst index 42bb1bb..4477e98 100644 --- a/source/upgradeguides/glpi-11.0.rst +++ b/source/upgradeguides/glpi-11.0.rst @@ -83,6 +83,9 @@ Crafting plugins URLs In GLPI 11.0, we changed the way to handle URLs to plugin resources so that they no longer need to reflect the location of the plugin on the file system. For instance, the same URL could be used to access a plugin file whether it was installed manually in the ``/plugins`` directory or via the marketplace. +To maintain backwards compatibility with previous behavior, we will continue to support URLs using the ``/marketplace`` path prefix. +However, their use is deprecated and may be removed in a future version of GLPI. + The ``Plugin::getWebDir()`` PHP method has been deprecated. .. code-block:: diff From 8a7672161935cfbce9dfe6ad82b69a92180b4573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Anne?= Date: Mon, 28 Oct 2024 13:59:55 +0100 Subject: [PATCH 13/26] Add more upgrade instructions for GLPI 11.0 (#157) * Add more upgrade instructions for GLPI 11.0 * Apply suggestions from code review Co-authored-by: Curtis Conard --------- Co-authored-by: Curtis Conard --- source/upgradeguides/glpi-11.0.rst | 76 ++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-) diff --git a/source/upgradeguides/glpi-11.0.rst b/source/upgradeguides/glpi-11.0.rst index 4477e98..893fc4c 100644 --- a/source/upgradeguides/glpi-11.0.rst +++ b/source/upgradeguides/glpi-11.0.rst @@ -74,13 +74,83 @@ If you were using the second syntax, you will need to replace as follows: Using raw SQL queries must be replaced with query builder call, among other to prevent syntax issues, and SQL injections; please refer to :doc:devapi/database/dbiterator. -Changes related to URLs routing -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Changes related to web requests handling +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In GLPI 11.0, all the web requests are now handled by a unique entry point, the ``/public/index.php`` script. +This allowed us to centralize a large number of things, including GLPI's initialization mechanics and error management. + +Removal of the ``/inc/includes.php`` script ++++++++++++++++++++++++++++++++++++++++++++ + +All the logic that was executed by the inclusion of the ``/inc/includes.php`` script is now made automatically. +Therefore, it is no longer necessary to include it, even if it is still present to ease the migration to GLPI 11.0. + +.. code-block:: diff + + - include("../../../inc/includes.php"); + +Legacy scripts access policy +++++++++++++++++++++++++++++ + +By default, the access to any PHP script will be allowed only to authenticated users. +If you need to change this default policy for some of your PHP scripts, you will need to do this in your plugin ``init`` function, +using the ``Glpi\Http\Firewall::addPluginFallbackStrategy()`` method. + +.. code-block:: php + + getFromDB($_GET['id']) === false) { + - http_response_code(404); + - exit(); + + throw new \Glpi\Exception\Http\NotFoundHttpException(); + } + +In case the ``exit()``/``die()`` language construct was used to just ignore the following line of code in the script, you can replace it with a ``return`` instruction. + +.. code-block:: diff + + if ($action === 'foo') { + // specific action + echo "foo action executed"; + - exit(); + + return; + } + + MypluginItem::displayFullPageForItem($_GET['id']); Crafting plugins URLs +++++++++++++++++++++ -In GLPI 11.0, we changed the way to handle URLs to plugin resources so that they no longer need to reflect the location of the plugin on the file system. +We changed the way to handle URLs to plugin resources so that they no longer need to reflect the location of the plugin on the file system. For instance, the same URL could be used to access a plugin file whether it was installed manually in the ``/plugins`` directory or via the marketplace. To maintain backwards compatibility with previous behavior, we will continue to support URLs using the ``/marketplace`` path prefix. From 54d25be5d949d168d0aad4fc5d99e3d2c91e6800 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Wed, 6 Nov 2024 10:16:37 +0100 Subject: [PATCH 14/26] Add documentation on controllers --- source/devapi/controllers.rst | 326 ++++++++++++++++++++++++++++++++++ source/devapi/index.rst | 1 + 2 files changed, 327 insertions(+) create mode 100644 source/devapi/controllers.rst diff --git a/source/devapi/controllers.rst b/source/devapi/controllers.rst new file mode 100644 index 0000000..0da25f8 --- /dev/null +++ b/source/devapi/controllers.rst @@ -0,0 +1,326 @@ +Controllers +----------- + +You need a `Controller` any time you want an URL access. + +.. note:: + + `Controllers` is the "modern" way that replaces all files previousely present in ``front/`` and ``ajax/`` directories. + +.. warning:: + + Currently, not all existing front or ajax files has been migrated to `Controllers`, mainly because of specific stuff or no time to work on that yet. + + Any new feature added to GLPI >= 11 **must** use `Controllers`. + +Creating a controller +^^^^^^^^^^^^^^^^^^^^^ + +Minimal requirements to have a working controller: + +* The controller file must be placed in the src/Glpi/Controller/** folder. +* The name of the controller must end with Controller. +* The controller must extends the ``Glpi\Controller\AbstractController`` class. +* The controller must define a route using the Route attribute. +* The controller must return some kind of response. + +Example: + +.. code-block:: php + + # src/Controller/Form/TagsListController.php + query->getString('filter'); + + return new JsonResponse($tag_manager->getTags($filter)); + } + } + +Routing +^^^^^^^ + +Routing is done with the ``Symfony\Component\Routing\Attribute\Route`` attribute. Read more from `Symfony Routing documentation `_. + +Basic route ++++++++++++ + +.. code-block:: php + + #[Symfony\Component\Routing\Attribute\Route("/my/route/url", name: "glpi_my_route_name")] + +Dynamic route parameter ++++++++++++++++++++++++ + +.. code-block:: php + + #[Symfony\Component\Routing\Attribute\Route("/Ticket/{$id}", name: "glpi_ticket")] + +Restricting a route to a specific HTTP method ++++++++++++++++++++++++++++++++++++++++++++++ + +.. code-block:: php + + #[Symfony\Component\Routing\Attribute\Route("/Tickets", name: "glpi_tickets", methods: "GET")] + +Known limitation for ajax routes +++++++++++++++++++++++++++++++++ + +If an ajax route will be accessed by multiple POST requests without a page reload then you will run into CRSF issues. + +This is because GLPI’s solution for this is to check a special CRSF token that is valid for multiples requests, but this special token is only checked if your url start with ``/ajax``. + +You will thus need to prefix your route by ``/ajax`` until we find a better way to handle this. + +Reading query parameters +^^^^^^^^^^^^^^^^^^^^^^^^ + +These parameters are found in the $request object: + +* ``$request->query`` for ``$_GET`` +* ``$request->request`` for ``$_POST`` +* ``$request->files`` for ``$_FILES`` + +Read more from `Symfony Request documentation `_ + +Reading a string parameter from $_GET ++++++++++++++++++++++++++++++++++++++ + +.. code-block:: php + + query->getString('filter'); + } + +Reading an integer parameter from $_POST +++++++++++++++++++++++++++++++++++++++++ + +.. code-block:: php + + request->getInt('my_int'); + } + +Reading an array of values from $_POST +++++++++++++++++++++++++++++++++++++++ + +.. code-block:: php + + request->all()["ids"] ?? []; + } + +Reading a file +++++++++++++++ + +.. code-block:: php + + files->get('my_file_input_name'); + $content = $file->getContent(); + } + +Single vs multi action controllers +++++++++++++++++++++++++++++++++++ + +The examples in this documentation use the magic ``__invoke`` method to force the controller to have only one action (see https://symfony.com/doc/current/controller/service.html#invokable-controllers). + +In general, this is recommended way to proceed but we do not force it and you are allowed to use multi actions controllers if you need them. + +Handling errors (missing rights, bad request, …) +++++++++++++++++++++++++++++++++++++++++++++++++ + +A controller may throw some exceptions if it receive an invalid request. + +You can use any exception that extends ``Symfony\Component\HttpKernel\Exception``, see below examples. + +Missing rights +++++++++++++++ + +.. code-block:: php + + request->getInt('id'); + if ($id == 0) { + throw new Symfony\Component\HttpKernel\Exception\BadRequestHttpException(); + } + } + +Firewall +^^^^^^^^ + +By default, the GLPI firewall will not allow unauthenticated user to access your routes. You can change the firewall strategy with the ``Glpi\Security\Attribute\SecurityStrategy`` attribute. + +.. code-block:: php + + 'John', 'age' => 67]); + +Sending a file from memory +++++++++++++++++++++++++++ + +.. code-block:: php + + headers->set('Content-Disposition', $disposition); + $response->headers->set('Content-Type', 'text/plain'); + return $response + +Sending a file from disk +++++++++++++++++++++++++ + +.. code-block:: php + + render('/path/to/my/template.html.twig', [ + 'parameter_1' => 'value_1', + 'parameter_2' => 'value_2', + ]); + +Redirection ++++++++++++ + +.. code-block:: php + + Date: Wed, 6 Nov 2024 14:12:10 +0100 Subject: [PATCH 15/26] Update controllers docs --- source/devapi/controllers.rst | 99 +++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 23 deletions(-) diff --git a/source/devapi/controllers.rst b/source/devapi/controllers.rst index 0da25f8..1fd1491 100644 --- a/source/devapi/controllers.rst +++ b/source/devapi/controllers.rst @@ -5,21 +5,21 @@ You need a `Controller` any time you want an URL access. .. note:: - `Controllers` is the "modern" way that replaces all files previousely present in ``front/`` and ``ajax/`` directories. + `Controllers` are the modern way that replace all files previousely present in ``front/`` and ``ajax/`` directories. .. warning:: - Currently, not all existing front or ajax files has been migrated to `Controllers`, mainly because of specific stuff or no time to work on that yet. + Currently, not all existing ``front/`` or ``ajax/`` files have been migrated to `Controllers`, mainly because of specific behaviors or lack of time to work on migrating them. - Any new feature added to GLPI >= 11 **must** use `Controllers`. + Any new feature added to GLPI >=11 **must** use `Controllers`. Creating a controller ^^^^^^^^^^^^^^^^^^^^^ Minimal requirements to have a working controller: -* The controller file must be placed in the src/Glpi/Controller/** folder. -* The name of the controller must end with Controller. +* The controller file must be placed in the ``src/Glpi/Controller/`` folder. +* The name of the controller must end with ``Controller``. * The controller must extends the ``Glpi\Controller\AbstractController`` class. * The controller must define a route using the Route attribute. * The controller must return some kind of response. @@ -76,7 +76,7 @@ Dynamic route parameter .. code-block:: php - #[Symfony\Component\Routing\Attribute\Route("/Ticket/{$id}", name: "glpi_ticket")] + #[Symfony\Component\Routing\Attribute\Route("/Ticket/{id}", name: "glpi_ticket")] Restricting a route to a specific HTTP method +++++++++++++++++++++++++++++++++++++++++++++ @@ -97,7 +97,7 @@ You will thus need to prefix your route by ``/ajax`` until we find a better way Reading query parameters ^^^^^^^^^^^^^^^^^^^^^^^^ -These parameters are found in the $request object: +These parameters are found in the ``$request`` object: * ``$request->query`` for ``$_GET`` * ``$request->request`` for ``$_POST`` @@ -135,7 +135,7 @@ Reading an array of values from $_POST request->all()["ids"] ?? []; + $ids = $request->request->get("ids", []); } Reading a file @@ -156,14 +156,16 @@ Single vs multi action controllers The examples in this documentation use the magic ``__invoke`` method to force the controller to have only one action (see https://symfony.com/doc/current/controller/service.html#invokable-controllers). -In general, this is recommended way to proceed but we do not force it and you are allowed to use multi actions controllers if you need them. +In general, this is a recommended way to proceed but we do not force it and you are allowed to use multi actions controllers if you need them, by adding another public method and configuring it with the ``#[Route(...)]`` attribute. Handling errors (missing rights, bad request, …) ++++++++++++++++++++++++++++++++++++++++++++++++ -A controller may throw some exceptions if it receive an invalid request. +A controller may throw some exceptions if it receive an invalid request. Exceptions will automatically converted to error pages. -You can use any exception that extends ``Symfony\Component\HttpKernel\Exception``, see below examples. +If you need exceptions with specific HTTP codes (like 4xx or 5xx codes), you can use any exception that extends ``Symfony\Component\HttpKernel\Exception\HttpException``. + +GLPI also provide some custom Http exceptions in the ``Glpi\Exception\Http\`` namespace. Missing rights ++++++++++++++ @@ -174,7 +176,20 @@ Missing rights public function __invoke(Symfony\Component\HttpFoundation\Request $request): Response { if (!Form::canUpdate()) { - throw new Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException(); + throw new \Glpi\Exception\Http\AccessDeniedHttpException(); + } + } + +Invalid header +++++++++++++++ + +.. code-block:: php + + headers->get('Content-Type') !== 'application/json') { + throw new \Symfony\Component\HttpKernel\Exception\UnsupportedMediaTypeHttpException(); } } @@ -188,7 +203,7 @@ Invalid input { $id = $request->request->getInt('id'); if ($id == 0) { - throw new Symfony\Component\HttpKernel\Exception\BadRequestHttpException(); + throw new \Glpi\Exception\Http\BadRequestHttpException(); } } @@ -208,7 +223,7 @@ Possible responses You may use different responses classes depending on what your controller is doing (sending json content, outputting a file, …). -There is also a render helper method that helps you return a rendered twig content as a response. +There is also a render helper method that helps you return a rendered Twig template as a Response object. Sending JSON ++++++++++++ @@ -232,7 +247,7 @@ Sending a file from memory $filename, ); - $response = new Symfony\Component\HttpFoundation;\Response($file_content); + $response = new Symfony\Component\HttpFoundation\Response($file_content); $response->headers->set('Content-Disposition', $disposition); $response->headers->set('Content-Type', 'text/plain'); return $response @@ -243,8 +258,8 @@ Sending a file from disk .. code-block:: php render('/path/to/my/template.html.twig', [ + return $this->render('path/to/my/template.html.twig', [ 'parameter_1' => 'value_1', 'parameter_2' => 'value_2', ]); @@ -271,7 +286,7 @@ General best practices Use thin controllers ++++++++++++++++++++ -Controller should be *thin*, which mean they should contains the minimal code needed to *glue* together the pieces of GLPI needed to handle the request. +Controller should be *thin*, which mean they should contain the minimal code needed to *glue* together the pieces of GLPI needed to handle the request. A good controller does only the following actions: @@ -279,7 +294,7 @@ A good controller does only the following actions: * Validate the request * Extract what it needs from the request * Call some methods from a dedicated service class that can process the data (using DI in the future, not possible at this time) -* Return a response +* Return a ``Response`` object Most of the time, this will take between 5 and 15 instructions, resulting in a small method. @@ -297,9 +312,9 @@ Unless you are making a generic controller that is explicitly made to be extende Always restrict the HTTP method +++++++++++++++++++++++++++++++ -If your controller is only meant to be used with a specific HTTP method (e.g. `POST`), it is best to define it. +If your controller is only meant to be used with a specific HTTP method (e.g. `POST`), it is best to define it in the ``Route`` attribute. -It helps others developers to understand how this route must be used and help debugging when miss-using the route. +It helps others developers understand how this route must be used and help debugging when misusing the route. .. code-block:: php @@ -323,4 +338,42 @@ URL generation Ideally, URLs should not be hard-coded but should instead be generated using their route names. -This is not yet possible in many places so we have to rely on hard-coded urls at this time. +In your Controllers, you can inject the Symfony router in the constructor in order to generate URLs based on route names: + +.. code-block:: php + + router->generate('my_route'); + + // ... + } + } + +You can also do it in Twig templates, using the ``url()`` or ``path()`` functions: + +.. code-block:: twig + + {{ path('my_route') }} {# Shows the url like "/my_route" #} + {{ url('my_route') }} {# Shows the url like "http://localhost/my_route" #} + +Check out the Symfony documentation for more details about these functions: + +* ``url()`` https://symfony.com/doc/current/reference/twig_reference.html#url +* ``path()`` https://symfony.com/doc/current/reference/twig_reference.html#path From 3b9ba5c36977a28828af885953005d809755e5d0 Mon Sep 17 00:00:00 2001 From: "Romain B." <8530352+Rom1-B@users.noreply.github.com> Date: Tue, 14 Jan 2025 13:36:41 +0100 Subject: [PATCH 16/26] Add migration guide related resource access restrictions --- source/upgradeguides/glpi-11.0.rst | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/source/upgradeguides/glpi-11.0.rst b/source/upgradeguides/glpi-11.0.rst index 893fc4c..aa45d75 100644 --- a/source/upgradeguides/glpi-11.0.rst +++ b/source/upgradeguides/glpi-11.0.rst @@ -90,12 +90,24 @@ Therefore, it is no longer necessary to include it, even if it is still present - include("../../../inc/includes.php"); +Resource access restrictions +++++++++++++++++++++++++++++ + +In GLPI 11.0, we restrict the resources that can be accessed through a web request. + +We still support access to the PHP scripts located in the ``/ajax``, ``/front`` and ``/report`` directories. +Their URL remains unchanged, for instance, the URL of the ``/front/index.php`` script of your plugin remains ``/plugins/myplugin/front/index.php``. + +The static assets must be moved in the ``/public`` directory to be accessible. +Their URL must not contain the ``/public`` path. +For instance, the URL of the ``/public/css/styles.css`` stylesheet of your plugin will be ``/plugins/myplugin/css/styles.css``. + Legacy scripts access policy ++++++++++++++++++++++++++++ By default, the access to any PHP script will be allowed only to authenticated users. If you need to change this default policy for some of your PHP scripts, you will need to do this in your plugin ``init`` function, -using the ``Glpi\Http\Firewall::addPluginFallbackStrategy()`` method. +using the ``Glpi\Http\Firewall::addPluginStrategyForLegacyScripts()`` method. .. code-block:: php @@ -104,8 +116,8 @@ using the ``Glpi\Http\Firewall::addPluginFallbackStrategy()`` method. use Glpi\Http\Firewall; function plugin_init_myplugin() { - Firewall::addPluginFallbackStrategy('myplugin', '#^/front/api.php/#', Firewall::STRATEGY_NO_CHECK); - Firewall::addPluginFallbackStrategy('myplugin', '#^/front/dashboard.php$#', Firewall::STRATEGY_CENTRAL_ACCESS); + Firewall::addPluginStrategyForLegacyScripts('myplugin', '#^/front/api.php/#', Firewall::STRATEGY_NO_CHECK); + Firewall::addPluginStrategyForLegacyScripts('myplugin', '#^/front/dashboard.php$#', Firewall::STRATEGY_CENTRAL_ACCESS); } The following strategies are available: From 5de32058150c8f40fc4437b1fdf9df05eb8d9cbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Legastelois?= Date: Fri, 16 Feb 2024 11:01:05 +0100 Subject: [PATCH 17/26] fix: apigen url --- source/devapi/index.rst | 2 +- source/devapi/tools.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/devapi/index.rst b/source/devapi/index.rst index 1b67ab8..eda8b97 100644 --- a/source/devapi/index.rst +++ b/source/devapi/index.rst @@ -1,7 +1,7 @@ Developer API ============= -Apart from the current documentation, you can also generate the full PHP documentation of GLPI (built with `apigen `_) using the ``tools/genapidoc.sh`` script. +Apart from the current documentation, you can also generate the full PHP documentation of GLPI (built with `apigen `_) using the ``tools/genapidoc.sh`` script. .. toctree:: :maxdepth: 2 diff --git a/source/devapi/tools.rst b/source/devapi/tools.rst index ed34ddf..436b5db 100644 --- a/source/devapi/tools.rst +++ b/source/devapi/tools.rst @@ -14,7 +14,7 @@ The locale directory contains several scripts used to maintain :doc:`translation genapidoc.sh ------------ -Generate GLPI phpdoc using `apigen `_. ``apigen`` command must be available in your path. +Generate GLPI phpdoc using `apigen `_. ``apigen`` command must be available in your path. Generated documentation will be available in the ``api`` directory. From cbb99c74f9b108d5ef231eb57ef97732a096da0c Mon Sep 17 00:00:00 2001 From: tomolimo Date: Wed, 27 Mar 2024 12:07:53 +0100 Subject: [PATCH 18/26] Update hooks.rst Added 'to be' where needed --- source/plugins/hooks.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/plugins/hooks.rst b/source/plugins/hooks.rst index a8738d2..f054ade 100644 --- a/source/plugins/hooks.rst +++ b/source/plugins/hooks.rst @@ -477,7 +477,7 @@ Hooks that permits to add display on items. ``timeline_actions`` .. versionadded:: 9.4.1 - .. versionchanged:: 10.0.0 The timeline action buttons were moved to the timeline footer. Some previous actions may no longer be compatible with the new timeline and will need adjusted. + .. versionchanged:: 10.0.0 The timeline action buttons were moved to the timeline footer. Some previous actions may no longer be compatible with the new timeline and will need to be adjusted. Display new actions in the ITIL object's timeline From 498e0e7ca077de6f6f7a882741485401c567fd95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Langlois=20Ga=C3=ABtan?= <64356364+MyvTsv@users.noreply.github.com> Date: Fri, 20 Dec 2024 14:11:22 +0100 Subject: [PATCH 19/26] Add 4 anonymous hooks doc : add_javascript_anonymous_page, add_javascript_module_anonymous_page, add_css_anonymous_page, add_header_tag_anonymous_page (#160) * add doc * fix comment --- source/plugins/hooks.rst | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/source/plugins/hooks.rst b/source/plugins/hooks.rst index f054ade..6bf398a 100644 --- a/source/plugins/hooks.rst +++ b/source/plugins/hooks.rst @@ -176,6 +176,39 @@ Hooks that cannot be classified in above categories :) The name of the minified ``plugin.css`` file must be ``plugin.min.css`` +``add_javascript_anonymous_page`` + Add javascript in **all anonymous** pages headers + + .. versionadded:: 10.0.18 + + Minified javascript files are checked automatically. You will just have to provide a minified file along with the original to get it used! + + The name of the minified ``plugin_anonymous.js`` file must be ``plugin_anonymous.min.js`` + +``add_javascript_module_anonymous_page`` + Add javascript module in **all anonymous** pages headers + + .. versionadded:: 10.0.18 + + Minified javascript files are checked automatically. You will just have to provide a minified file along with the original to get it used! + + The name of the minified ``mymodule_anonymous.js`` file must be ``mymodule_anonymous.min.js`` + + +``add_css_anonymous_page`` + Add CSS stylesheet on **all anonymous** pages headers + + .. versionadded:: 10.0.18 + + Minified CSS files are checked automatically. You will just have to provide a minified file along with the original to get it used! + + The name of the minified ``plugin_anonymous.css`` file must be ``plugin_anonymous.min.css`` + +``add_header_tag_anonymous_page`` + Add header tags in **all anonymous** pages headers + + .. versionadded:: 10.0.18 + ``display_central`` Displays something on central page From 21099a09fc25fd8ee396e61c322f68d0e4944323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Monterisi?= Date: Tue, 14 Jan 2025 16:16:33 +0100 Subject: [PATCH 20/26] fix misc (#163) * -B option doesn't exist anymore * langage specified to avoid warning. * fix path to glpi logo --------- Co-authored-by: Sebastien Monterisi --- Makefile | 3 +-- source/conf.py | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 4c6c0c6..7c1d4aa 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,6 @@ I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source #Watcher ALLSPHINXLIVEOPTS = $(ALLSPHINXOPTS) -q \ - -B \ --delay 1 \ --ignore "*.swp" \ --ignore "*.pdf" \ @@ -73,7 +72,7 @@ html: @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." livehtml: - $(SPHINXAUTOBUILD) -b html $(ALLSPHINXLIVEOPTS) $(BUILDDIR)/html + $(SPHINXAUTOBUILD) -b html $(ALLSPHINXLIVEOPTS) $(BUILDDIR)/html --host 0.0.0.0 --port 8007 @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." diff --git a/source/conf.py b/source/conf.py index 7068173..87555db 100644 --- a/source/conf.py +++ b/source/conf.py @@ -86,7 +86,7 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'En' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: @@ -166,7 +166,7 @@ # html_logo = None #Will be marked as missing during the build, but is provided from theme. -html_logo = 'static/images/glpi.png' +html_logo = '_static/images/glpi.png' # The name of an image file (relative to this directory) to use as a favicon of # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 From 750e6d28151a1795a5690d6dd6b62139279fed8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Monterisi?= Date: Tue, 14 Jan 2025 17:16:29 +0100 Subject: [PATCH 21/26] update tests documentation (#162) * Update sourcecode testing section * Update linting section * nfo about launching tests "as in ci" + note about phpunit * Update source/sourcecode.rst Co-authored-by: Johan Cwiklinski --------- Co-authored-by: Sebastien Monterisi Co-authored-by: Johan Cwiklinski --- source/codingstandards.rst | 34 +++++----------------------------- source/sourcecode.rst | 6 ++++-- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/source/codingstandards.rst b/source/codingstandards.rst index 06fe6f4..b4c4824 100644 --- a/source/codingstandards.rst +++ b/source/codingstandards.rst @@ -245,33 +245,9 @@ Examples: Checking standards ------------------ -In order to check standards are respected, we provide a defaut configuration for `PHP CodeSniffer `_ rules. From the GLPI directory, just run: +Linting (checking and fixing coding standards) is a good way to ensure code quality and consistency of the code base. +This is done using [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer), [PHPStan](https://phpstan.org/), [ESLint](https://eslint.org/), [Stylelint](https://stylelint.io/) and [TwigCS](https://github.com/friendsoftwig/twigcs). -.. code-block:: - - phpcs . - -If the above command does not provide any output, then, all is OK :) - -An example error output would looks like: - -.. code-block:: bash - - phpcs . - - FILE: /var/www/webapps/glpi/tests/HtmlTest.php - ---------------------------------------------------------------------- - FOUND 3 ERRORS AFFECTING 3 LINES - ---------------------------------------------------------------------- - 40 | ERROR | [x] Line indented incorrectly; expected 4 spaces, found - | | 3 - 59 | ERROR | [x] Line indented incorrectly; expected 4 spaces, found - | | 3 - 64 | ERROR | [x] Line indented incorrectly; expected 4 spaces, found - | | 3 - -To automatically fix most of the issues, use `phpcbf`, it will per default rely on default configuration: - -.. code-block:: - - phpcbf . +This can run the tasks using Docker, on your local host use `./tests/run_tests.sh lint` to proceed to all linting tasks, or use a scoped task, `./tests/run_tests.sh lint_php` to proceed to PHP linting only for example. +All possible lintings are listed in the `./tests/run_tests.sh` script. +For faster action you can run the scripts on your local machine or Docker development container using `node_modules/.bin/eslint . && echo "ESLint found no errors"` for example. You can find all the commands in [`.github/actions` directory](https://github.com/glpi-project/glpi/tree/main/.github/actions). diff --git a/source/sourcecode.rst b/source/sourcecode.rst index 4e0b908..86e33cd 100644 --- a/source/sourcecode.rst +++ b/source/sourcecode.rst @@ -37,7 +37,9 @@ Those branches are created when a new major or intermediate version is released. Testing ------- -There are more and more unit tests in GLPI; we use the `atoum unit tests framework `_. +Testing is a very important part of the development process. +The reference for tests is the `GitHub CI `_. +The easier way to proceed with testing is to use the provided test script `run_tests.sh `_ which uses Docker and bootstrap everything needed. Every proposal **must** contains unit tests; for new features as well as bugfixes. For the bugfixes; this is not a strict requirement if this is part of code that is not tested at all yet. See the :ref:`unit testing section ` at the bottom of the page. @@ -260,7 +262,7 @@ Unit testing (and functional testing) A note for the purists... In GLPI, there are both unit and functional tests; without real distinction ;-) -We use the `atoum unit tests framework `_ for PHP tests; see `GLPI website if you wonder why `_. +We use `PHPUnit `_ for tests. `atoum`'s documentation in available at: http://docs.atoum.org For JavaScript tests, GLPI uses the Jest testing framework. From b90577a99d44c797bc8d067716b5c9cd3362f627 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Thu, 30 Jan 2025 10:47:28 +0100 Subject: [PATCH 22/26] Fix some warnings --- source/devapi/extra.rst | 2 +- source/plugins/objects.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/source/devapi/extra.rst b/source/devapi/extra.rst index 6dfdab4..2b419b2 100644 --- a/source/devapi/extra.rst +++ b/source/devapi/extra.rst @@ -4,7 +4,7 @@ Extra The extra ``config/local_define.php`` file will be loaded if present. It permit you to change some GLPI framework configurations. Change loging level -^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^ Logging level is declared with the ``GLPI_LOG_LVL`` constant; and rely on `available Monolog levels `_. The default log level will change if debug mode is enabled on GUI or not. To change logging level to ``ERROR``, add the following to your ``local_define.php`` file: diff --git a/source/plugins/objects.rst b/source/plugins/objects.rst index 8ee1481..f1ea1a2 100644 --- a/source/plugins/objects.rst +++ b/source/plugins/objects.rst @@ -8,6 +8,7 @@ Define an object Objects definitions will be stored into the ``inc/`` directory of your plugin. File name will be the name of your class, lowercased; the class name will be the concatenation of your plugin name and your class name. + For example, if you want to create the ``MyObject`` in ``MyExamplePlugin``; you will create the ``inc/myobject.class.php`` file; and the class name will be ``MyExamplePluginMyObject``. Your object will extends one of the :doc:`common core types <../devapi/mainobjects>` (``CommonDBTM`` in our example). From 3145830a80a8919df44f27cdbb5aefe7187d8c1f Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Thu, 30 Jan 2025 14:38:49 +0100 Subject: [PATCH 23/26] It's no longer possible to remove CSRF check in v11 --- source/devapi/extra.rst | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/source/devapi/extra.rst b/source/devapi/extra.rst index 2b419b2..dc8a2ab 100644 --- a/source/devapi/extra.rst +++ b/source/devapi/extra.rst @@ -28,19 +28,3 @@ You can define a unique email recipient for all emails that will be sent from GL Date: Wed, 5 Feb 2025 10:43:44 +0100 Subject: [PATCH 24/26] Fix tests documentation (#168) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix tests documentation * Update source/sourcecode.rst --------- Co-authored-by: Cédric Anne --- source/sourcecode.rst | 63 +++++++++++-------------------------------- 1 file changed, 15 insertions(+), 48 deletions(-) diff --git a/source/sourcecode.rst b/source/sourcecode.rst index 86e33cd..ef88745 100644 --- a/source/sourcecode.rst +++ b/source/sourcecode.rst @@ -262,31 +262,10 @@ Unit testing (and functional testing) A note for the purists... In GLPI, there are both unit and functional tests; without real distinction ;-) -We use `PHPUnit `_ for tests. -`atoum`'s documentation in available at: http://docs.atoum.org +We use `PHPUnit `_ for PHP tests. For JavaScript tests, GLPI uses the Jest testing framework. -It's documentation can be found at: https://devdocs.io/jest/. - -.. warning:: - - With `atoum`, test class **must** refer to an existing class of the project! - This means that your test class must have the same name and relative namespace as an existing class.] - -Tests isolation -^^^^^^^^^^^^^^^ - -PHP tests must be run in an isolated environment. By default, `atoum` use a concurrent mode; that launches tests in a multi-threaded environment. While it is possible to bypass this; this should not be done See http://docs.atoum.org/en/latest/engine.html. - -For technical reasons (mainly because of the huge session usage), GLPI PHP unit tests are actually limited to one only thread while running the whole suite; but while developing, the behavior should only be changed if this is really needed. - -For JavaScript tests, Jest is able to run multiple tests in parallel as long as they are in different *spec* files since they don't interact with database data or a server. -This behavior is the default. - -Type hitting -^^^^^^^^^^^^ - -Unlike PHPUnit, `atoum` is very strict on type hitting. This really makes sense; but often in GLPI types are not what we should expect (for example, we often get a string and not an integer from counting methods). +Its documentation can be found at: https://devdocs.io/jest/. Database ^^^^^^^^ @@ -323,44 +302,32 @@ When you use a property that has not been declared, you will have errors that ma Launch tests ^^^^^^^^^^^^ -You can install `atoum` from composer (just run ``composer install`` from GLPI directory) or even system wide. +All required :ref:`third party libraries are installed at once <3rd_party_libs>`, including testing framework. -There are two directories for tests: +There are several directories for tests: -* ``tests/units`` for main core tests; -* ``tests/api`` for API tests. +* ``phpunit/functionnal`` for main core unit/functional tests; +* ``phpunit/LDAP`` - requires a LDAP server; +* ``phpunit/web`` - requires a web server; +* ``phpunit/imap`` - requires mail server; -You can choose to run tests on a whole directory, or on any file (+ on a specific method). You have to specify a bootstrap file each time: +You can choose to run tests on a whole directory, or on any file (+ on a specific method). Refer to PHPUnit documentation for more information. .. code-block:: bash - $ atoum -bf tests/bootstrap.php -mcn 1 -d tests/units/ + $ ./vendor/bin/phpunit phpunit/functional/ [...] - $ atoum -bf tests/bootstrap.php -f tests/units/Html.php + $ ./vendor/bin/phpunit phpunit/functional/ComputerTest.php [...] - $ atoum -bf tests/bootstrap.php -f tests/functionnal/Ticket.php -m tests\units\Ticket::testTechAcls + $ $ ./vendor/bin/phpunit phpunit/functional/ComputerTest.php --filter testSomething -If you want to run the API tests suite, you need to run a development server: +If you want to run the web tests suite, you need to run a web server, and give tests its URL when running. Here is an example using PHP native webserver: .. code-block:: bash - php -S localhost:8088 tests/router.php &>/dev/null & - - -Running `atoum` without any arguments will show you the possible options. Most important are: - -* ``-bf`` to set bootstrap file, -* ``-d`` to run tests located in a whole directory, -* ``-f`` to run tests on a standalone file, -* ``-m`` to run tests on a specific method (-f must also be defined), -* ``--debug`` to get extra informations when something goes wrong, -* ``-mcn`` limit number of concurrent runs. This is unfortunately mandatory running the whole test suite right now :/, -* ``-ncc`` do not generate code coverage, -* ``--php`` to change PHP executable to use, -* ``-l`` loop mode. - -Note that if you do not use the `-ncc` switch; coverage will be generated in the `tests/code-coverage/` directory. + $ php -S localhost:8088 tests/router.php &>/dev/null & + $ GLPI_URI=http://localhost:8088 ./vendor/bin/phpunit phpunit/web/ To run the JavaScript unit tests, simply run `npm test` in a terminal from the root of the GLPI folder. Currently, there is only a single "project" set up for Jest so this command will run all tests. \ No newline at end of file From 319ab4484a12dd9064b5e1c208d4fbda3ee4ef32 Mon Sep 17 00:00:00 2001 From: Alexandre Delaunay Date: Fri, 7 Feb 2025 09:12:37 +0100 Subject: [PATCH 25/26] tutorial for developping a plugin (#166) * tutorial for developping a plugin * update doc * Fix syntax * clean php snippets * clean use * clean use * Few fixes * Fix doc links * Translate titles * Rework main title * Translation * Dead ref * Translate * Remove metabase part * Translate * Fix internal links * Apply suggestions from code review Co-authored-by: Curtis Conard * Work on translations * Maybe should not we use logDebug. * Translation, minor fix * Fix syntax * Translate * Translate * Translate * No direct querying * End translation * Typo * Typos, misssed translations * Apply suggestions from code review Thanks Curtis! Co-authored-by: Curtis Conard * Update source/plugins/tutorial.rst Co-authored-by: Curtis Conard * A word about npm. Precision: composer and npm are not mandatory * Apply suggestions from code review Co-authored-by: Curtis Conard * Add download_url and a note on plugin submission URL * Apply suggestions from code review Co-authored-by: Alexandre Delaunay * Replace old links --------- Co-authored-by: Johan Cwiklinski Co-authored-by: Curtis Conard --- source/_static/images/API.png | Bin 0 -> 84501 bytes source/_static/images/Notification.png | Bin 0 -> 28762 bytes source/_static/images/NotificationTarget.png | Bin 0 -> 8956 bytes .../_static/images/NotificationTemplate.png | Bin 0 -> 22181 bytes .../NotificationTemplateTranslation.png | Bin 0 -> 86929 bytes source/_static/images/api_external_token.png | Bin 0 -> 8951 bytes source/_static/images/breadcrumbs.png | Bin 0 -> 13283 bytes source/_static/images/crontask.png | Bin 0 -> 52779 bytes source/_static/images/install_plugin.png | Bin 0 -> 6730 bytes source/_static/images/search.png | Bin 0 -> 15510 bytes source/devapi/database/dbmodel.rst | 2 + source/plugins/hooks.rst | 6 + source/plugins/index.rst | 1 + source/plugins/tutorial.rst | 2783 +++++++++++++++++ 14 files changed, 2792 insertions(+) create mode 100644 source/_static/images/API.png create mode 100644 source/_static/images/Notification.png create mode 100644 source/_static/images/NotificationTarget.png create mode 100644 source/_static/images/NotificationTemplate.png create mode 100644 source/_static/images/NotificationTemplateTranslation.png create mode 100644 source/_static/images/api_external_token.png create mode 100644 source/_static/images/breadcrumbs.png create mode 100644 source/_static/images/crontask.png create mode 100644 source/_static/images/install_plugin.png create mode 100644 source/_static/images/search.png create mode 100644 source/plugins/tutorial.rst diff --git a/source/_static/images/API.png b/source/_static/images/API.png new file mode 100644 index 0000000000000000000000000000000000000000..a66712334da4646bf9c556abe3a0a828a303d423 GIT binary patch literal 84501 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 literal 0 HcmV?d00001 diff --git a/source/_static/images/Notification.png b/source/_static/images/Notification.png new file mode 100644 index 0000000000000000000000000000000000000000..b541ba0c5e174bdec11dd45a0b0cbbfff9739271 GIT binary patch literal 28762 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 literal 0 HcmV?d00001 diff --git a/source/_static/images/NotificationTarget.png b/source/_static/images/NotificationTarget.png new file mode 100644 index 0000000000000000000000000000000000000000..b3a3174db8ae51b2d532c5b8370e07e140914982 GIT binary patch literal 8956 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 literal 0 HcmV?d00001 diff --git a/source/_static/images/NotificationTemplate.png b/source/_static/images/NotificationTemplate.png new file mode 100644 index 0000000000000000000000000000000000000000..fefff675644b7223d1158dc2623355b262f7e835 GIT binary patch literal 22181 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ⅆj#;SCt(7%#2_Icgxj; zqHagZ5P}&$5d8ha8fQl=Fam8)}uE&)e%(Jh`T0sNu z?L)}m0bNFlpmg0r@7t@qioySokZjFvk%}g_Qmd1V12?r^rN77cu57K+U-1Dce;NNS zw)Ry0bk+XnaFPItOiqIRwdZ|IM6T|Ed{{nwrzVSyk$PG0@L;}nv~@e@{}3E0lChee>~)L0yD0GCSL#t0j}B|ZTj<;aK0<*Ri(TNuN`crs)3vH z*-*YKQ0G7OPXX^5C>6jx#-#J}wrOmd;Qtbm0mpT@=T~_3>^8fkeEK|yHpqfLTkLt` zT`$U{e1et75Gpq(B!8=T5gy<=(Hgdkl|FEj&fd}j+|2DyzeDBoJH;el>~G2p02f3? zs(>pTxi??2a{(AG!c|=FE(ts|!1Fm9#pQTWmux45h;cbc;JT}|tDvcf?g zT7Nyc>K~l$f|g)`#=*ZAw}Bww{2Couptpb0H-Tim10Q(|^fk2b|92KAI@X9=`RVhh zQx^ufHB>8%y6^(gu8-art1l7v2g(HAfIe3KXWpg%C^fot|NM=o(54Rbmi!j|sWEDS zA%LFk&b@zGM)2PsUw!G|orDRlfEE!?;xE6VC)?;td4aSMZ{+@30ZnBxhF$y}3oT<|3rE`>QhKij8kyeko zNN;pyK0i+rEp!^=tt+dD7{TdE9BYuGLU!L1e_lUzS8>`IlesI8#(JjB(4`dQYp>6C z&KJPwIOw46@7Tucy9GbX{Rja!3F~TlXrFnlAA+S|Zz~5rL>x#k(QxxQMirQ^$CQnd zE6CBg&5RtOEc{%|t2cigOpgpzsk}>$9a`T2Xqs6nf(=<=e6^~h?G%#Op@~+?{%`ae z%h1=lO>06vf=5dq3#SE5JuYV~Pr=zuj<;)5(_eXB){zp=BUVUBHSleM4wXzVP!_AU zvTUgJ^;LmO(MZSZ5sl?4s6`;JWMk|rnGnj3cr2^H>Nbmrk{A|jzAuE&NPd1>`>b50tG?& z)u#<&2q6sxXoYkPy%Rq5v?J8FVt zII|rD8*HLoF+S5P?GeXC8&^2lA%$oc`q}E`xx7rHk1c~^W`D9JO>Q)kjVHDxX2@r$AwdA7frSU=jK=tA;{JjR>ZE!yw}^{ zeQ+u*L4d5%_v9{Cvl1?*$?n`JeAu7?tM@E~ulcVf=nLDdnZRB@f4HLBAG{FL0*j|_ z2a1Wn^M};} zQCUD~wL{H)mv>j#G93hWqmP$I#7o*H2l-wE>m-y2^|3=Id#C^CRd$(jHPBn5YUc1( zds8;)GPf_pLYX;oET9!;K97n$xZ|1dgWKse<=^;Z>?>7mch^Qt4p2AHKc ziO17T%DY&cNh`U|3E>lm@{%iB%Bnzm`fcl%I zBmovkMON|Y{DIphOf-@u4BJ~g+l(VS(~oR;NLFbU_Tavn_4LEDWDnn0bZ^9Rv!RjT zCvDCGKj9kKci+K#Vas;kKxE+1Od9D3QZv8w<oYB%AgwQNKvoQbhN*fA%dH zvCbpZ9P~9O1DQUJ%!~$yD-$neyK8GP{ntCcJ+UYF{PQD==P)EJ2bsBAvY$>9xOs*A z5KUQl;*%b9L^NNohutFoKpotDrSy$bvrJIct6NRel2=x?9CtxqlU;DtUXljld~Rjt*AjVK57(V^;62eGCuPuUUT;hFbXkZA7gS@N|8ZX` zvn-o4G@bYj2-HCS@lLLtDCi~V8yNbHG}%Mv7x_9pipG?vN@Vmf5#t;94|i2;Hg$1j z0T={sPV3Un&0b;`pIabFKYjs+Sw?A9967!KTBV08lh3Z`&~IFtx1pN?kU5GJA$)Oa z&K!_QGZ&WbyUz2xQ#N~7a=12o?m~gk_mL;AbmU23rh*`>UVHj>PoCuLR_ZYsSeD$& zG%w$$ubHf=ve5f04s*a`X{7MY$MFw1vku;0zj2&hRlfzMRm#iH=OwPu7h}K1eK+=; zm!)6tTh>=_#QxcQ0O+Fv>2Dq>sYLMo&-Zh3-grKJC)&B?t{@6}<{g0b>+v_z-{6DH z=q%}{umW0_*j?)TBetfefySwx0985Emx?98vd~;)Sz#U6)tik2X)d)ve4{$yuQm{ zw+1#Bes1|dgjjXU`Sx%!&GX!cbpNg@k&of%1on!v%|d`*%ZAJo*~#tY^qal@q?&S8 zxx%~1n4H@B#L;mLdsh?Hv=f9m%7EOf{L2khLGzRbPYROec7R<`?Mu+a5xVMA)@ zeC)|tf08qN6yxz-@Vk%OEw1kN#}a$qn=?=EW=(1Hp0_q|+ZfTm)9}jcTo-O}r%r0l zi{VNlAWjzhHnLk2fVx_|mM9ZdXSN3s1fdFJN^;r$)}rng*(V!J_t1@2_BCqX>lWzc zuI%Hyfw$#VNJ*T{g?4u{loj}|!2dw^h6Q@Xxc_`af7AG8{eSvL4}5IZNx$wh+xv%_ zi8yx-HMg8fjvNYqC!x2ug%~)XWd!%5C6#xP>E3wG4R)?Cc?Ng{~W; zVNY>hE&EyqxV-SMM}>HJ8=-r=XFs%P(Jek<))$$?{BIALhLwNQMBKM7G$()J zC$HdNx<^^jK)x7HDZR)pY$|L z5R)@z<)czbb^9^GKS%wM-(%3{b2whzx-<_9FjL57?LfI@)AM9}42@fcB$1~eDWZ;G zoxlPis`QvgsuI2(hRind{N^{zHn?DClx<$hldaR3!zZyuz!PM?3+$hFJh(ZlX%X}q zSx#4>!*>NW*YZc(?rz?>Z(PT#(*U`tMCCKJ$l~wR`T{Jgt7hYU~ zd#N~^JzBD&VfCqJTSmm7TG6_Nq@vBE=C(;H;1tEgHo+dJo)HRA)hM~5HhYj(*+fDy zZGVoVXA-UI9?{%46Md;>bSr49#yEE|B z57n9QW9br|YecCZ{`$c2#esqgHj+o((Sb)|T2 zmooMA-k9YAtzEX2!3Ka~lgqxd>eX@kb}KfaktQd$=!s+wvNcS~Gqx3c3!bagfoCY2 z=Mstl44eLx*$4c_bU3m$tFxM?mJGN+V2OMM`wY)8X7)4yS!4XW8i9|NdTM+wPSPVZ zOFX#MiMG#Le4HXmZ1QC`-IP{jn#7q>B^nfftEiek$4??psawfaj|E;qGo6#->zH4E zt5?AFP8#7eB;nE^k=xj?uu#_ef`r zFR3_%b8R_N6{OHtrB?TPWXFZa5FqiI=TZTHE9kZ=`;b<6JZtU0E-4T?gPiArR=75_ zsqUKqJhb**r>k>$yOZu+*@AmAbKI!T>(BIyLhlI*+E=tA3IrH{lGF(-vC#x4E#N<$ zy<~EuY(A^a0iMLeVmOi|1vui0E)BC`aM4b+)iuw1>tEr*!I2zU^enZBHS^xWMNQ6y*g3&j4yL-Af{&>IWD?s zU7mxkrYbZGLQDYGjmq&d@1-+_B^Fjl^Nn=4qTat1I2a!=tyUW#F(-V7uoG4k$KA|>YkV#v?Kfk6AcRPf*vQ1x23=R)W`M;n~%wi*U$UTx2Z~wgHBdJ%rzP< zb5O@sZc<-XZm`LVBsG(LK&=P&pwEhzUF8LO&tJb;lw~>76gy~Rt@6rg^8JbcO}2ZD z|1Ky?;VT|iw%ykOE@bD-GMrAeF^M5oQ?#ZoN!zb2Hj}#Av0i^0#Go&=a#=Jdc zwyA!$T6wtU0UJELUtmLbSJb;u(@Ak|_2rACM2Ztsv!5O{rZxnm#wknd&>F5$YyjiIGax0{DXx*s&%(v9`P$^P^7P~Df zn^E{O=PVZ!R??y_2#MsmIA~&WncaRoB5W>pC$f!X;ZZ)zoDuldDh>75v!39C>0cDn zrcZ-bDD$VB6|M48mG0<0$rZX2nc6~ew@b1gMo+?7BWHc`q`EdXNL(6sQ2A-;%x+Nm zczAL}cT(ZX{Zf}|^_RLN55tnF$?n|KVu2-sNdu@IFE{JZh~j{HUZ+#) z8`$5yb5V$iBxD}O{3Y)s`Iv%d0vM;udkdSiTgh4HE7RYmRt7PAB&DtM>>NCf271X3 zldp9!pszfn{Xc*vs^hTNf?+=Yc z60NO_&mM!4i4IfeoZYd1iKZJ~Mlcd(d9}r1bhALF?X>Nl%kKBdJq15e6lwe1HO(LS zLrGI7^7>Tpjg0l>jbMn8{FwG&>@fB8@^~!YyMM5@Cs4e44dV)>#>Qmn_qmibsI%1z zZcfJV_*>hPAL);J@G8^kk&d!)VkMM!e_^j%$n9+UZ!}G5HSp^W4+bAiqh!Wpr?<{J z4|&Efb1^u+f!}{4U3%tx-6#JVO%q&G_l41&BrbR~_*c446XvpMo~pYDq4@6){gU3I z_Jn>bIU{G8rgN~pYnrfMlOYEH>Iq3c%@;Pc{3LAgOP**yjq+5isSuyNZf0Ze6}JO7R?e2Ylm@j?mxA zvQg8C#*XYr=O#=|_A0vzo+|+!;Yix;{40ajZ)twL(l0w`r40tz1m`#m9e#&N*?D)> zjL(pUh-ntR$lwX`aE}_Lo?3R5i2zHd@!WuO9U97S=hK9CZX;fbN+m*WhCV1iO8B%g z#N7DHb7h}1$2>34icdsT>dn=s+0Z+ncS_3RgyEWH>90MXlA8Mw#;>zT0r6Uw^OZG3 z&eCpT@6pWX<4e~&)b)5Aih;LNmrUdRO)m(dSVCZt9nA(9f!1_?y!BfS6gz+xisXfT zHX7S-$kN}^=Sztq=cxM12!iTE^qF5KxewgSGLSuwyY;wTLADT#1>1f3rtiGAgt@=a z7*q6dF^;Ws1-~o?VAIFulaem`{+=Qvmt0%<{dytbUi+#k7(l7VDr0@SLk(s%KW;W^ zY`*3sfuw&4qh5A&4t%kk(a^u%>wi0ZpqRzusf!`IwwuIlL)o;Q&73SsXb}_!9pwtTBGLD}{Eca|*ywtEmNEy&t|EC@?M)g^f7)<+zAZ0&E%J@|p)jB2 zH7coAhXC^wK=Q_zP`i2?r~e~@r%Ww3&SO^Ei3ktc=W7-w^4%(ynGp)y6H&!kXhg}5 z;#roI=zs2YzQ*kZkhmjm*$;MUANK`l%$i|0=(&9XbVAk19MV(l(U)65WhJP zQZ?V4`g7`g2yCk1G?PrYdIh$Q+|yM8{jpn5YiY>nf9etE`!P@SWj74haZ z>1Tf#yz%S*Hze;cA+vL|inqj+eA$xCiv{egoqx!6zG<#QZ$GzK?vSRs*@LVffM3(8 z+11SIQHwnYGUsd7Di=@6c*5N9e5E~hNKnvH~1e_i$TNdMzUQz`fC(|TWtH0Yhci(a{F z*JsC+=k*P5I_N+C4Lm$BMt)GrDofo%YE@?b2vwE^|2&|j!kB0>bW&Y?J8Ia#%%f^K zsItu{t;_rL8^s^%Kk6fsuely|YYP*ax9p(6QmcM2MZYdVf;5^lfjK4H9oIYrq3TIK zh$#oYcGZ6Qgn1E*7%x9&ta>1nLLr@1+eE!u$E_NpH79HRus%MyS@b3yjvY#xFma*p zP8?o!t>eEHRNq-08)C;}9h8<^o|d5N3o1T1b><8q5Cg&mAG_ZD z&&+!mYqMq&w1DcCzY(aV=S(v$Ne>8#>OyDzgMC!W#Z&5ps~)-wjuRfAB8{Tn=r-%Z z0KH4z{ge$8AWyCR{s{+H-DQiY5ExW7yhgm)tp$+q3Z!#YmU%(NYTNH8qm4)TTKc2u zkr>ueo91IQhrq;Js(Eu5_(>Y?`Kkc))=F2}?wg1?r9FPjn>>P_(rs2+Jb%!i~k#6jKq&f>tyww}8vpJH4 zIeISY+Ix0CO4DXfAC+k{!hxyVw~!U5XF(mGa&?$M(R{(|2)gDSWnW`VXZ394qQCg<6uUd1 zEpPKoi?Rf$RNPFtjW$%?9676i^uX%_m+$G`tlme@{FfC7qUJ9I@a!sxhRS;Ar( z{(&BMD|4;xVI30)kSFnu9sX*YLQqhhnG5K%D5A@*N?O8p`)Cpsm~K>Drr&L7eDZ93z~NJRPRqCA_3_3( z+86Y`e@VbDBCdrPziDfiBQyAF%ZZ_()BHn0=mhZS$GKKwlQ%k=|AXSqb{YtkE<_Dj zbWOI`EXTJ0S7mP<7S-B@eGiBdqI5S7-O?@1&=S%qC?Fx-DM*K;Fod*pHw;Q6(#;SG z3`lp^x6r-!^X%t)-#^~<#~d7MV9lDD#eLuBdH$|zDZOZ}-1VGgKTI?dTQHi_K6CVH z%1$VwukVudsT#CzCVNZqf$ep57ju7=4ew^+`G%#;x~KYDgj>9pZ1sfM!5*jK*xkza zfNR+L#{HIak?O+y&^3(1jlSQd&PZui#*Y8wJ|piA!y&?PviR+}z;*@a-Mjg3qjWQ( zBUz^WyEfG-Ngi-gN1S@*=cUD`=Ra)JIPiC0kqqQNqHH*rH)+ygB`lt>a&fKACD9Dg8$X?3ZEukle7|TY+zpr+IsirIfF2(;AbNmNlvKKMX!k7rwF;#q1vTi6J#u_ET+B2(1bD9@%MX1r7U zWYcRRg1dRVYC*p|J@tPSpH^!nm9FN<1}u7t$^2k;d$(@Z__0ROps@PWWznEMxXoF4 z-FmWkFYiR8In|WCu*^ut1yv7~Zx5Exv2*r;+-t`cV$&kL|NJ_p?TR>r34|>< zDi9urj~@4mnE64~HJ(IZ3AFnLg#cH`uIRKmH54ZaU&dWwxyW@9xH*7kDjQQ&_OdP= zn6xR(TEEC2)XxV0lHp`gD+{=4-OnX~Q;5nBlK<6^iy+2$@XTy%^b1uF2=v(!Gd&4t zkPZGcwy`zKt0WEa7f?VscV1G$H+hglZtxM%%v2?Qsk-Ml zV1^b!Ji4-VL{48|uc9J%b(DO&Z}$WQHq;%E&h{05VXL3a*`7V?Sh8(CJkHPix-?o*fQ&H?t`pMVk$@Y36N+cUL+LcOW&V&)hhxkSSu36 zaf+4EpkGj0&jR8JrK{%Hc@C?u7L)8ctFRAnviFNS@A+fsP1y-jOMm^F1t^MRv`Q+) zU5x5YNwqsixbQ|saB7F&$&z#drQjGZuAL5oUHXXm;vILZemroLIyjV}AI?GS?JmrjKX8wosN(mGzS`*vOk)@o=o+9)Sl?V1H zIRKRtf^r=sQ4rQLNa@-jNIbscB?cf4Wk_J^B64|OX=&GIQg=3vA~vmwiT)US-WVTp zAaS3sdNRA&AeuMVsO5Buj&BapsU2K&aV?frGngVAH&tQ4PA6}V5HPC(oPT~{7|0Rd zR|G+DGhtJ~tM0P_Wv^`P0`6zIZ_=$lki>Pn)L)swQ6r6%8mW4uB|`j>x^mqe$jTD! zzf@S9qr{GrUT|e?<`wtMzi`_nvJc`?SU%$AKp2`<_>Z|?iZMVEs3pFD(2yXiijf3k zkIW>eB4D^W-JG&Ij0xYVeTv?$q&=n{(quT+2f&hxQ(tWYy6ej?FX$lfEn8V+4PfDZ zxf7BF6YPz%wk`730uAMg-HT(>f7CqRUr-Rht&%v|*M4Msk4w-8?l?;(`f!Tx?H5{= zoG}L;2Hmlq7dDo!cIFJMVh<^`mM+8QT=c#Lt54K6^OcxVF+VLaK zf=OU1A|a=$w1ISyFl$@#J#X!f2FyQec8ypi4vY}bW3kYjETirF4*0i#m0vU~JPMjEY zy|H$c2SH>X#yomMP9KyD`PJ;h(dTEXj4ZAINzFx(H?c1ISpf1!!Rc9chy^=v@(k>w zB7Y@XoVt4b=6eV(s$D(RjeF^P)L^8- z34D?M6Fg)qftm|xZUPi}wIFkmqa1;QkbJ=#ATI|ym%xbVfMbLb(?rJpOKx2-Jjv&t zKq`6M(OW;>EfCHh!gzqm#gV;)^1;5iR)RRBPLE950ss8u6{g4Cmjd`3eS`cERq_WV zaKf9LX7OEq8k%$G&%;i7MSMwVzK3~%W{wvV{p%k0WA~(y7&gMDsf4We_}ql;JgFS2wc1- z#II3ojtHFQE+H+Snk&!6v!r)TeP15A=b*x__m>Pw_Eab;$UoPCn4SspWQs?s&r-n{ zdN(I<8ubpf>O|a$1S6xm1U~3IA|hzFD7`--=&%ECvuF0z8jIMX)yA9{5|94eR5%C( z_>W(c-TV;5my zQ8VvYdeNZk-b$*)2S+6*T-{1~lTcQWZjA(LP;VV8v`d=gkaIgXGW$Zn;+A7!bc(Rl z=PA>%TJeh9=CjI4$S77Z%9SX+X~+k{Ti*)7-fq39*^am}2H^3)1-T*3vx<DuFUY~RiXm-x8Yo{ODw@#Kkc92!|{8^S*AG_^rT?Rrc#PKz(?cL(o zpm%}r*~oE;;Zk^g{KU)yLAyhQ6iGv=Yf=vUX(qp4f#K3Oto|76XLaN@j!YA~8(rJ3 z;B9wD{lXC_!gtE{7)GytD2;+K1LK zge`*|W8N1)WJNmtSFW){q&$~QFti}kWXdUaADF<%aZ{^Q-j5{K`iaZE2iKUh?ey%h zz_4$c?&RCwUKVlNQ+XarhHTmhf&C^|R^iMy(;a7orj8erkdDesg>cqqTdwn(F6CRF z_7BZ_&yxPiNW{3qUT@x>CsQFcs1G=YT+|ZmVs>+L3i>R^PS@%!-X6<=U~|8s(^YSd z4rjQ{z56TBeed+b2YY}q`5m%w{M7f=uA;bGdi)i-EKmHI(f-LISh zymS2sUD)C*m}Vv#BtP8FkNVk&lsMaRrwk1fsc`wQ@<~|v%f4tM^?dWsCS5+tO8rEu z;Thj99BK92FF2@=p8Orkq`ZQqDoASZ-jkG6q)A+kq^LKh7n0o%_Vo%6e&ImUD(OT7V_XoNOdJSotygv(m`%()J!Wl`R?5)KdHm7F&4ZAU5T4d%S z>p!y4#s=uc*3Iz{cP4dKxyH9buUtFBAm# zet%UTZ2P@`pmFSieTi9nhwX8;I(r?C)VbNQT@4`02JH_9R$DQQo1i6t8Z!eDjkkar zvqz1H9PPT+;E{!i2}Uk|9GE?y0b-a*s9iV!kE~>Y&&?376}iA*(W=b)0;bdIW$?U- zYQ#l!dqUAeWJnze2w@^eZDtwqH`0|$2FyzN`xysbZ7-GabT#YVjaG$-%4dqlwn&V? z@C4sTa_?oi<3;kCFGYF)H91wSoYi1fn=bctE@q&Ss@~;V2N53SniD5CW`jvcGLJI< z-QI|CYWMI*LhqVLI64=KKo`a(uhjGe$MqFwM5bPCB2aDzze)SDVXmC9+YtnW(*Nng{K7(ryZ6 z;wv*CW#{8-i5O2KJ|Com9~%fGsYW;Q)Hma>wHgYE>ot=I#CW3Q=0@A{mA%Qycgm5H z__XHUl^LmfS-eNOa`kfb#lz_%%tgmgqu;@6w~SbOVm9Cgtk&6AZFV58*c!>c4Hx`$ z1h5y!#6j~E3xHtBI^-O3?LYtt4mMJ4Ptsfs#(xaA*TWc;qJpSsP zUaDOkLfYn(=l-L3d&H*FKxBci;ai9G*aLkkfAuEs&wF{zJr=UnU7w$?yvZTR1J3oQ zVtr1RkUmF2>(hFtJd^lkKz@}|ZUO<8PKi}rT8*MN!dIfaQ5}@meQgdi7(|Ui*7ndD zz0yqak-Tmn=ga4g3^I@VBi!+YPZ>YHVqo)RTxK5&_s_s`f=eyd{D zAMmt*3F(bU?TX$ml4x&ewtA3#JfRBu~k&SR8{2z}SQzwG!H6C5ehf;IY-_&@QG(_HPthsMA< zF$X7d%iAHBeK@>VsswlPG^HVNl&sELXBk|S z#^dXdQ&UM0H60jznUO|EGgVeY5(F$piMyEE<7S`MT&FOHt)0cq+xHQhO1uEKKotVR z*?Q~%$jFL~fWg$e$*y-ZByM6t21VX_HtCnJFY*U?3_jdSf!Or<^Ui`sCWA&{=hSd8 zgcc>5l6&4 zan>th#mK&(@;m2xYz#|6M0$Q0jZu9d(m6y%AMGb?Hg*yZTrsR$e8;UW!c*HWyosGO z>eA9nph0@0IBe~Wfh6Jf8}?ot$tnw$01MQW**JnA8B8n3y03ry1MLYkA|e^2XCki1 zeXe>>Wr0sLsnus??Ee-p8XBuQiTN7VNL)_mRUQWvgG5w zs2zM&2T15=XkY&&%)PyJw=AvsCu}(szXPXx7gtKS9|G1JP*tLe=rVMnj)fnncN|RgB| zFt>YqU==h%E)%2=hiyf>MCzTf(s0LEFpYdC8aDF5TyZAYG!O;pUYwqkIB-Pg;|BP~ zdlX#lWV+{kH!CSsjP*A_Ykn|){c&q*>IIuFF5R_PTXA^YjgLujT<-DmRYpLed|a;2 zX@}Y(xj961foI_0&@Dd+*uaoa%e} zD!p@H)T_(NxIw9Wtsmr{TfpWh+Y09Fguaa3pa)UQ(<%fOVCAELvevd-M0p)~Ah?OQ zXJZX?Vc*(rf7F^o>})sO4NZmu%==$-*qt8qgz&uWE*uq_r+GOhlwCtGVFagKyR#%5 zH%Q(MldB33Pt=Km2!obNlSNYa9VRy00@8LNuCKa~RhCQBAh-yu4G7&}_&ETIZR|YO z17+QdGGw|NMT-dzs^JL^pg$Tuo+b!8j{bu9Y1JY;4J&Grpdgb8&6oXeuLS78VecILh;c!z7}zoIfT2B@IhL#sI-^_FxxLP3z0 zG6MPc>_{dMNz=tg%L3%^{Ojb*j57IlP6Y_*Wwao;sqmA#rQk9rjsN}UooMK20mI}W zKN|{bt{F+|6NJUXbA~7Q#hHwiyEZr@y%lXEbKIRmX@{_#$e2~I&jDE<x7wV|7{R3fnUO1-wE6gx{tKxILm>KMjPF;ObuBwu}odYf?iu1=50-v#7d&4<2waKmx@Jn|N2TW_%ys=ou+dKbkL7cUZtJ>+2!s{%dJ{$OHY{8kX7NVj^o7uo}$4Id6549OYST; zBmhEJQs%wF2MwNpyxbN+G;@nzGDdMP(L>HXi$XP zbri)L&i=A?)L;2_9=Lh_gKx1D z>Kroa4T0zd166UW8es{=(=OrJdHtp-<9Oqo-U~>QTD`T~-o=&BZv!2e&eTii7iY<_>JOUORY&Qh+No z!$2U#k9HxbN+@i_I`1hs7mgHRC)&`!GF}WC! zq3CK1i7{;35?+UMpW`O|TAf`|J4RCDN~sF~u`#e zIifnLLgeG<0)no~LUrm}MWM*xIFLFw13El&MeaAnxgXb zW ztt&@kj_{R4mhyhekN(>P35WnpkoB6lwZSV?Qg({sU)+mtjLWR1r|6uWoZgM!%s^v5 z)p{8D?mPO_egw=EMvOjJXO-3>xyR68chdHOhn0RBcZ6ux5Y7zTXek2k6cI7hDHnH9 zN1uJiu->-ap7v-41-%El)Eaqry}8V$DAykMEvUh17nuLHT!=*jgyYG;Jt_WjhT#Dy zbqL4~a}H0%=;eG{^C$;xlh5A7)l-A5=>${(aKbA}iXAj(v8dTC>B>4>XAOI(gwI9g#Eajh{8m}ZJgFtcHoIpj% zfe-#MKaPCkh9$@D7l9(IxMp90@x66X7{v)uav5gFniU!xpTxB)N*y5I|jwY~S==5^E4Z)}x)M6CoE)I(PXyx}{-^V_x&rA@8c zw(?rcw%&(({$@T-h~IoAfQo|N=3TIV{N?Go$aqM8mu-u(A4c9u|Nd&0xxp�FJ46 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 KNS8^P1pa^S;L$7q literal 0 HcmV?d00001 diff --git a/source/_static/images/api_external_token.png b/source/_static/images/api_external_token.png new file mode 100644 index 0000000000000000000000000000000000000000..5f3be6da946824d18072307b867ceec2bcce7c2f GIT binary patch literal 8951 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 literal 0 HcmV?d00001 diff --git a/source/_static/images/install_plugin.png b/source/_static/images/install_plugin.png new file mode 100644 index 0000000000000000000000000000000000000000..860152c4859985aff8b3dc5b2d149e7a926a17c4 GIT binary patch literal 6730 zcmdU!Wl$Vjw}uIx1Pu_}A-KCcgS)$Ha2sSGgy0q+KyaBLL4pMahae$10Rjvzfx!ls z!7r!2@0@eb`Fa1{s#RUPs&}v6>s_n6cRwpuO9O!YjO-Z_5)!tulDrNQ5{l&Gm=6>E z@o3Pol!JsshOaCyqX&EfUkdX~y99L~LwHs(+CB^rezz?|(5g$nN9$80Lz_`#DA5jb z)1GZpbk5O(+E)kdam-UMIM14wp3i7Nmf(Hn{=Zr+Dn1SC4^A2^%@@Anz#nu{P!vr0 zKtsckED}SF-uo;GKJaGv;3uvrx~h@j_lzrHm{CwDsB2|*)@U4d6uXVA9gj<|WS#k;ijVi?ANH{Yd1;Bs$<@t%xxHm1i_cL{0nkO>sInaM2J;`* zy^r_Nw31XpLZZ=NSo9x09$h+NhG&Os1_uYr@yoKZAk)$O!ygGA9KR<==5KNlN(EG zOUTQz4r*c~H-!QENzPbL(Ms>77;LE$wf= zRBkdB?l`GXfo&R6(oa&4M2Vuqd+CKs=3aU={e5Abty zqz@T6IS4AbF#cJP+h@c4mRZ=S`9_+~XzvghYfrlmLZh$^NlSnuJ7`7aw!g$E<$7~m^XYydjKZ=M)l zu5T*9#>T0n1Z*BQGuK3UMcEM;VLeSZ)Q+y{hZy-%LZ7o22D)Y?FNiJIw*$9F?`w@_ zU|~IB1sK<%y@t>1AK1ok4~-Pgk8dsK&Tn2mc%H2rk^kVu|0wu`jl8EwI5tUCfkzpr zcV-oZew)VamZ7VA6gZaO_%QKfHj!>3peZ@)Oj$c%)iyv+Rh7wsf8+>@kWH0872L2n z@3*n9>Reg7f1kNcN>T_jN`3PJrn`&@z8BQY(DWi0c8JmVhP`CKnIQDOKW*E=sxYUS zEneKyRg96!5P~imXX=Ocxi(v-MQqJ;|bOfENN&Wa=G3KW%)7sI1O&d{2Y?d_83m*G!L+V`s8uExcr~ z@QdPLIz5N{yvOR3HCRAur6Li@PiHK5jZDE~BbPVqpqC+kuNkC8Swhn{gn!vK@$9p= zes1W^)-GLk`qTBv50gIz`^Of(St;23ffwJLf@2P8e95^gzQYScKx`hm^4M# z`?XazE5-P;zv`G)vs*)=m5O=-Q{B;S;sU#?!GZ$Tm!?&VAJF6H;A?-qTPSw>I==-rbgmIc+1R^e-jJD)(Md16=^RZh$5IL+zc zECuyWKsslv;ju-B6xAqC+?5mXdfX=-F6dspeC{TQEV^7_rAO-i4iZyMaLy#rk^%Io*Eb=(nsp;$+zYqA`YI69EJsEU9xV}Ahm+W&`a3{7R zAqr%aFBt4Z8Gr`VM*pOahlwB>3Qqc?5MZnAdc^irVqY4>=+2=P}lj16+{yiAL`T;w6x5*N${5 z#VBx3QAZpn)LI&B)0ppI1@X%WetD16{1jCep=04fYVQBO$CTc+aC=?}L_}#WFgWKE zOJSIAHq&-zWIx3F_@b^uLr*kB49((rQl#HdAtXfGaPV&WW$v$CITlY4FZnl!I*p8Q z<2@|;CA#?fem;nfjVH)RHiYckTC{vEC@9lxaBdk2ULLZgLTJj4SFhd_n8!8shX+`Q zLDa6(j)!#qNR^57>5D`~FZ8#4?W8Y)-c=c*u&MsoU?NwtE;VOXq$n5${79$YQX)8F zoFG6)p-KlZz^=`%5C>bANx z-48m(Gmk`a#Hm&lg$Avl&p_Ho`NpZZEX+hcY!!@Piz6mnqV8b={`MLZy3M)J|E4dwVN18K_}6V`HTVH;#|y_M~+xY~W`)T14@;<$ArF^fPUsK&h+8eWIsd zcs#`|#L{aq9~!U%0G`=)4Lf!o(H_*6_2)?r4Ko2|8t$pqEgu*xgU@tB4r9lU4arsM zl?=K1?%Bo*?%}Y&+daw7Mq6uZ+|#b4DQxz3zvp2GmVklgBzp4L?sMXaJ098Hw2;6u zS>Y`J#L>YH%)l=7^G&7avF1%l#HFj zMZLB6V9us0r_zVtGX7mq4C2%MyW>6Ia}MiMf8qrQdotUJe!=9bS_(thyC3DC+Ki66l?n=VUYcHT- zl+Xw*KMcJ|Sj_1_qW_*a$xv;yQYYNC8Q2q!8<)hjPuIp5OT~)zY%@-sX7lyhr=Wx# zgl@{D!6mw<9r%;lb9&NVPqaEN^b{fP6%pwlpNlK{J(e=R(^(?8-~k(|uBaQNYQuDw zqlxTf0duxqyMtoJR=71>MgZnR`YbHMdy-7(m+L9s!K}=Zla5^tdUECpQC=IqdLTv3 zK1DQDS|1F5m@S)mo-d(eoD>~0UUXL9gY+rdcRVGEBYFE9p zC(GT9TbmgwI3~+~7Yni<*OBO34~+>lUUJvO4j^E6q{(g)9GQL#n+Uu_7X(>}av*$3^yw@f*lTBvoWzYf7$vyf~kr zY+Dp1FJMJ(^=ELi>u1@4`SiJ*$yO{_=_Y%AW$nxj4^`+9mE_v4)#gw?dsA2-dhiZ) zR*8he@vQfnyd+xmu%U$Z`pU>^Ez_7m68#6AF^6X?j;gw|ud=h8P~FYKUw$naoe<~?7QBBF)?n+rW>>uGwMO?m6EbOP5_Ylee4l(_bL4YR z0XVI$svtk0+mg9)&<)0OVu`O=NqE=l$|@EkUDCZdySZ=tVt58!8AkWPrf6vNCrDeT zliBE1)<@iAsduw#t5i3(?$ez@GdY1@n?9sg@sG2iN=9Cc>qA>X*f0z6o(;e9`Y$i?gs85HnFqXTX0X4^ZnzqrGRx3u6@a# z!R6-@i?R*ojXe()L?Q6Z%=A}4J4%mkq3;}2hRPzQj?U+$U-kKkO(fODvwFFC8DwSF z&C`2{$np!H)Bk3&3Bvqvm|(Dkx`bXN{o!lMK)qUmTB?zFygi0#Hb_%FF4s9#RRJ>! zS4*Ql_?#F1*@mpufPTB~@O6c805$}`MDR3?S8c>B&WK^Ky!4l|Sm!7ag(S6!s2YRY zOS8!}Zqg+&Z$=LCZ+jQEmf~!S1%B!9#AaLwmw^D=B4U@(G`2gDnLE?8BS{uHCII&~ zH4Ml(d>S0u-!R_MV|f@7`EWpP9CklSd=z%hB;Iry9kQmXc?!X}-a{HryS>m1+$SGD zPB*^@9bK%mJ^z8JLkUP#SFn18$$YVo!=^~{fi4qLdx8$t%LR(!I;1Kw$gI7s2Bl~> zl%;9T&v zsn^$}uH>j%+qfl>z#0=}U`lKghX&ak$`5DxCBedID`*;*b8>t{;bROrhENG&4C@^? z^5%z>;H&+l1!%}raA8-@NN0ee{Q;ZrRsYof{jrP&4yW~kqtqBUyt;~IEHcL~ad!cf z8m@WX<5HSi-MKL5x~t*5NB`0*HPni-l2URVc*IT)8dUVdIA$)>0?8=WOH~31Sm<1k zyTEy9&qY1wpHi>~TT+Ix$ML~!%>ft(o;XWWBHn0nZ9!SKLI?FF0?FW2ET))kmi9`q zZO_QTa?wlycs+_m4kV6Gjdz!36VBWWoZ_?@Jo=&E5R!40kF^O?nOR<@D;TY1%44)l z0>E=L@}8*-pzM>2clT1N&p9hcQ=0|4Wzzz(){t9bQ2I%2bu>{LYPKpYz6V>Ll*61h zW&Pl$gU<4K<@tK&DO*E{OjoU&8Ezqabz&{Bt(Rk+feGfpNhd=;Ltn0V6F{229bJzZ zEQ9t)q#pW}lOWC^@-)K!x-nW0^z=cj#nKeDS7d7a#;DHIiQ=MXQPy?iCX-63y!k(FwXTR zjT?t?zV@@}@xWJCs`KV(-R(~t#jkCLO92+H`((O=XvvUe;~37UlKC1_1mlGXXob) zHuiUEbgapYHDwmvDmN1m8j}}t3#FaHEHbF21~dh1YDK==>4Q4E?2|YlW~4R_-e$Ub z``v(KG#)-lJ+Y%YKJi4Km7#2CcrqW+H?_bor}EQ7CO=&NU}Yaac9$4Zw|fI_L?l-N z^YZYb)|MA)5?sFt{1(q`Imz3qw@<^pR>hBwT2S0-BA?G&vvjJUWo%AK_t|LYI zd%u&~gldcM5FZ*^_4j%M_uEF6#&%~Ke*05hE#5fyu8)=#!20>%uY>K#$>-TaJ75AA z?Ot)qJzpCQzMlI#bZ)k1p61RqWZE@F7j4LJ**4dwDO%zpjJ_fQ?&2-syqCPGe^iAlv?^L0Ez=hr!Q6!vr>4G_vq0 zb0mHGwiE9dWRBIuZVP6Tr+fS!wWsBoZ$|i^lvr+IIo)nn!h8@h>=bP;{H72!GWKoB%{R;Qf0fQ9$_f85ky9(ndGH1i`PAt_`c?#;r&Yu`0%p7iNBc`|vWYDT8CA@mke z?2oqZMI(pWy9Hi;9b)MSEHp4OAt@dqB(g@JceR}a1B(%l+5i?H0 zT(5*GZ-xGh`N9W0bUt}JU<(}KK1f32|BTa~!hdzLJ5*qhQ8=uMMP28c)NX&$+qRFf zlg{U==Wce~I^)x^@0Srpx%VUUPjW47i>b6aMRLc`NcaT5Sxwpt5nF~`r7A(83gqbt z?XfL+!awy%ooTI{+E7B7AgW+5ovDB;%+x502IuCZ~F0YDF+%j)OHo~%PElGtSO{KZ`MxI#T* zNyj85W{vN)1!ylA3B^1cc|MUv4zm8q)5AYMl2^xy$W6qfG`ci}g~lwh2RJYJ1?svf z<>DDI=S7wTa8n93Y)mnp&r8Uw3)M9f(>KQ^;V^ysn&b!v<~#bN!-5#sf!;C)X7Fx; zv0@Q1#>8{Nv#%67|HY$U(%*b)=rl<6rug%wkN93ITv0Q{jIF~f!e9B9i%^iIzMByx zo6C7XweL*ouWB4SsNUan)d4JBO)vE6e{G5D-6xxb9zH_Gg;@!+WJ8{zw)LCF8GuIr`ZAh=B#jcpu#E@frT#A%vsjKXyFw f|L+}-d+KH4c!NsfosP#I5t6ckhWr;GuGf(8%n5ZvAUcE11n&$(-z zyY4KQnbp-@T~l4M_p{#}rYJ9gjDU{-006R-q?j@Qz%qc}ZQ-H8_edMxDDdNry`+{C z03c%i{f7e5GjYL#ubrjj#9yz$AS1xw`>mX80RSl=CH6tpec@=?OBZXWo%wY2(9Ct7 zXfEQ1p|ch&9E-#FSKP3`fq@AMScP(Q>v#1m6ONIZ3Q7d>vfgr4_(^@37zQfHkX}Lp zj{Y|Mc*2I_xA7LLpV!laBLcpDVJI#E@WBYEz z2`|vv4kj2)1fDDyttCn<74GjB5%}Ci*@-)x&ea&6!2gu(hmn5GjS=-0%$eP}@NCns z1V3N`?jrwF3Vj+RDfYG3xLS-JJ4`Gu7f zcLazVyMM+jhpE!OjR+;hBAesPSUkGE`v93iQL_*Fw>3kz-hvq;_b!#4+lj|lQ!Bxm{lv{JspfHlif36qdLK06L6kgf7_H1u# zp=(@}i&q|2`Ome#k>d)cj$FOkR&;c&H8#&Y%~*LpQU9lTyCJ5m&HV>gp0>?Gu%}66 z|8_{gMK`3=O)>a{QS3iQmc?+_Ndj+>*Dsy_t@J3w0scRAz;FE9NVL9xuP0-#qxiRT zcO}+@(j0cE;w7oO><~6$3G@biJC|)6=RXVPjO{tEH}Y9X7sivq*K0%6%UHP3u#e(& z{=3rCyNxdjb66ZD4WI-UrXVofDeq7E+iu( zXQqzf^eEd2>l`jhB106-KS94G?E*`X2Oi8{2R(G*e{BO!PG zRTeSjj^Q7Eky0lO{`q4V(Hp20fF^<)xA-0~KELtBnX((lV1 z9Ex599%UtG{jSssF(4vcAea`>N2)2 z6JudHM|?o}&p>z=w|Hc0X=$W|4QOj?OU4t5B`j{7IkRv02paTfXUS8ED}h}egkona zLAZY9nURsPxUdjhP)mQ{%=;EW+|cmbZz*ViT@IDp@bu2xwN)=yF_wY`BTQRI2RsoP z1|}#lP>eiIlit?GMy*7Z8wuv`^xe(gtoOc&+8aWQvatn7Ir6Cl_^;Ne@0i&$7o`#9 z4EQ8otY?P5@|kQ=8ug%cGj~-Yb;H8Jy@}ckIO#dL;o{<2JaVm^r9BsvZbjxG`Mu3sibK_3WX%(T*EDPhR~`|aVhr-z#y z9;a7;7&*FBJcSgB?O0HM1{Z_p<5@q6-{V=G*_SK8`);Am>}1x2!~b`?4XIi{Z{6dW zIG?rqFhejJK6&=gHmWQ~lub?5uT#nPSLG?4&)*Ltw!MrSN{6;;H0i-XEpqyMWyQ8y zGdK(h22~_jy=81?!$W^ALzCW>Hw!yLe3uxVvk7xM{F3;|C0J3!{f}!a_>32iz%@z) zH4IH2+1Np}aS@_O&6~&Dx~#9E!DZAHT&5H!Ns%xREPQlLhTQz%D$c0o``GNWxT6Tn zlOpp~_6)TG}T%fb2NX3*@|yK@mmBIFBBYT}sU`uZ#R zRO$&Y!gXifCtp7uos5xB7w-HF3=I5ZjdgY2FHbiZVPX*V*RNio97FniI}Io>=07($ z?TqqdjsATnj0WG6l9Oq%!rx$0f&=KO=`5|c&NXWud3(731$H8g$E$&WW_x#3?j)5K zVoM`na~9EzXhLHc1JPC$9*Z!Sm7s%|ZYJ>Xge84}3zcWH-Rik)Yb&hAI^_uEv{~?K z`w0bh-}=N=^T(Ehfas$oUB%B0Egz%^B6%uJ@u&^yR>sCw{lK#Ze^J%WR%VLA0Gfk{ zTsVZRY_=tRvFR7a>TTHW7a`&Vw^OEWmL+Kp7D!|5=Yw5yP)s)a7k9z#%1zI~NH`Ur z%b$PieSy$0{$iqsxcJ9&;?^1rhtIku@`H`mmp@j9f%6_29ac+XQ{mVu+CWAz+nj9H zsad}}Rts3W45_yxHeUk1Maqs2jll2nmr;pN>~vQNyqVIfxIU_&n9P zUpjQOwD<%B-CbRE+BSxUe`35+rtup$)3#4C8%%CQhycLgY}7)ZT){axx{gLCrQf$(8!%AIEyoR#ET~$@E&JN*V==$o z>c@8{{x->`(!ej&nK(M{#2sgBJ={Mc0)M&Rg32+^hccGyaWSgKWJ4RhoGm@u*=gI& z(tR(WvtFNUlA%ABXg62O5(oQ-DCrX`ow-+ZQIY-hcHjgLpYk45cK)=Ljjipm#VWj9 zCW}d*BGwlk37kM&ILrHi$_ zl2E6|__gootYxrmeEgPM0^9opw3bVu|4hwYrM>?$sTAv`N`$CXk;k ze&)5aOx)NFNkKpu32T1UkrE%hg+&&8Zxb#qc;U2%W1y-r&7sQ9shS95(I+72XBF9_ ztiJ&*uDXDU8Z3FsJk(F3_t-I-o59XunU)PxIAzv6p{_J(u~kmAkqT{+<4OJz@lPpj z*+ro7;Bav~%=_%>d;C`V;CTP4to^mR5|yB~kaXp|rI%D#%!X z4LkJ^9fLQmrAsU1>MBwkN4$SD4QJ7$-!|JU^%b4jWGVi z&R%ljOjXI}vwm6c>veYqzycG8U{y;;dx%ONmXu>)UM5P30?4vbv@NYWEx80FU`smOcM8#V0ay=4l5; z(_cJWw-*{JJ{EH=3}rH>jdAiq6)Y2o3<|HQNi!A`09a(oZve?eB^C{#R{$CvI|6_f z@tz!5J>s8?jYUh7z3xU8Lh`m^7gyToi$X*|*e@<*zz7S*6~&#Wczg@Y9l3^flR3wK z6(i4;^QGz|L-^9QW)IGHh&mm11RWh6Pc$MTVg|Q^asOgXu*K%5H%i(T78cUd2mlri zjt+hDYZ7l}4vwq+-kq~0rI>qn#EmNT3T;(d-Ff~o>nQ%!b`SD)!7?#v1f7ozzGpl| zf3k3VJMa=s%o#@q(q_$;u-@h*m<+#6%E+uZ$XEuQHD@M;eU6&eOY1cCg`y!GfKo!q zc4NlwKSP$;HsI?BiaZ$?j#uX5;uT|7^FVZ1et-Fc7C+wm@m z1KIC=P@?{sot7Tcgm;&d5zKwJw`>WUgRxZuDyipIGxPh-QdkH;nemd!MLx$LCoQ6i zZ$HM#R?>s0#yAH}a_*%Z6Cck*C7uoRinGGRMP@@}$>0F<{7E(`#tNa=$QQdcJ26u$m zAdwUq3CWF%JJ5RmwkpdSyhLP!0r@CZY&Tz9ci=P(6%0{5?7HH^hOWAjSk-Ff>Ew2} z=^8ykjnA%i9Lh}k!L}`W$Fy}KD?2!?E}d!R#K#a5NDgbzk%|lYs~v#&lV~J4SBFb=!*8b=coM zA+Q6cD(?z$tPeW4b5jYIuBWRJZNeQcaw4ugeE|KGp=HmGHL)PnA3JBBxd*>#wR+s! zZ>5*#H%OZLUh&|UGPPh0p2e&{nbTo}QHO_r{fZXRD<>!C^MxGtLvTpQzB6wwSN@Cr zdur-md(JJ(w)NUXZ{Lb5se+dMvMr82F**ANXu=;axp>ip=TVoMh!ki;X7-$|>b1EA zKx6JR^Vba}tS!f8UB(pVcGHOhDFuP6sRF5lVA9|nkCY*fCIM8l12cLv9-9htkBBet zsYYcsQQu-E&(`vfv2yf>M~uMi@oiY69Pz8_o2&&){KhX#ENFS9k!ebx+L2RB^fb;>SC9`eT-aVQH*q zG^2<}Q|()!)XsKarkiIo3TTh!<0j00c&KY-#y$mWitBx!!KtrqGXoV8!aJk&QrzL8W88w*Cy zsE=%BgNez>$q&b^sH;XX$AiMAqjWmucXtQA&!f{^JQKe$2=e6vh+Q(jJlUJ?>Haf{^=vx(=N+E=7`lRyu}#!%1R0D<>~8eY zpfM;q4IQT0&Dplkt(^Wn{R18Q#z}0kb`NSj2l@v2!(d!P183{<%F4>|#T~fpR6#p{ z79zt6%9loQgi5o$)KtcV0bA~M2+6AVh1}=Q^vTNs7Y|Rijf-23S8VG`CpQ}E>Vl^~ zU{dvV`yFF&j(#Sol%u|e|D=0*EycuaIER0V?} z-6K9BA;0gVdzk6Bc5aYBtl5LR+8V=qksEN0#4oM5x)7RD4v>~EX-aCpa$_~F)`X}d zc2|caSDiD-H$BE7zWo5tRMlTDylYEa+?9To>Jo&BhGtJyP8NjLQVd^P^M#|lK)FOD zSCKXe_+!rcM>F|I^8|w|*f!((+O=_!f!{^BY&!pA)c#jdkT-nh%s9>K zzP`TBNEch?Ic;LIZfK=KL0|E3Y~4v-YG)v5YWT(ai3Y56eGp_AHkOu90Ft;ZExe_r zz~TX6D#DYKZz`GmP%;Z+Jw+T1|TTp%o>&xo++P#CmOpHU^B!ZJk+k z_F8&ALYNCQu)gvwRZWfd!otFmlCTZ#;W7dQczCoBgN>vRw3a6k5fRYJdlR@@KO0CP zm0lz&Dtgkfvd~J4!sGYM55UVLt#SB7cngvY)ws3_kds3@!GP4rVM`V48dciNeP-cQ zCHPztB?I(dKe&EyZ}#J$qZ`%EGwQePUfgBMQ|ZqH6)94K<3=0OM+ysGI=+RqI0It` zYe-2N3=+9U(^TwR5qP8VkAF$tzl6@Bhu~Pl=^Gy&O2a>g!E(ZX*=H9w>_1SHESMSP z!++r4|CE7*3#{`m>^a`$4km?<-e7+BU;fzRuoT<&tOg5f_}`lF4GE!P(d^4|ze>_$ zfS3h@VE;vuib8Grc1}*UniSY!b}qi5lC()*#l%EKVM56NbIV-cz}S$GS8-osrQa)u z-C|3aqpQo*cCR@%IO$i$6zzdLtXVg@`ClT7VNW=_vNFmXsY$O4`zuKrPD&a?fsjKL z@;FIo=uP1FXfx=2`3UB$p7gi<`-9)W2cm_EDVIMj7W`oFIC-)(1uGuS`@(n~6cIpJ1T7e3zyt7MV(Vw_{Q8xvq5ox~ zyHEk4Oj6uYLAMfJzrlK9P0b=Hpi@QhPQ<(pOrKJ9(@VKR?`9TFb{$E2GQRd#cn}uuvZYu*7LjbqFZsMrMAajYz)WAX18Gu9648iu$v#$c*#*$nrq9 zWr^KNwF-1-!o=Kstptb_Og6U0jmU17$>>wzjeH`|@EzS}KQxAQk5`Oa(1hco+Ykkk z7ARX

E4M=jTbgS$yU?eM#ZfaM8*ge&5V5*!kGmI?ew_Y6 z>s_^BUaPW%&%v4dk`G971anYp5p!E%Mp41)$94!DP<7t~o_d~z%pw*~dfZ?`e6{Wf=p`^#HQD*1&Y2!K{GDRBD-3-lE^b0BsWxO}dMZmVjiw$I}d z+lJtP14l-#S6Qy2me$qPtoedwGAaD>T(wGZpZG^{D-Nz%#*xohaWJdk2>TDlJh-~|7VKPAKns?nzyO<7tx195!f!*A*=pHNAAC$G zGAj|R?{|I3B|?}t^Sv*I1T>f@rlyt_X0U~Pv_S*Aan%>J^x{8_#Sd+zTEa)^zANU- zexQFxuUJ7W6AD+>b*wOWD=L+BiW|chhgUep&-2IJbGTyjdt}WAA?VFg1mY+ukB8w{ zLD5Zl(_V_sMea=x*L74&7Nz^t*OTG<6@Cj%TvAz@Q}BSx1LCzh@?O}Sw6Dq6A=+xA zffnof`s!6RRo+aLTp}TpzDvtV;x@a>-3%LKXX_rmEcvo&&n@YpBsvDpj1jAPD~@#W z2yDTdrTEJ)W53MKu_LBG)xIIngv@|jg6{$gaZKn&)6C3FGPaD06PuHqij$K}L}7h> z(gt@-|GPT(SFgcXONc@v9x0ImGJN1~EB47^g$#a=^E;B!j1hB(3V4xs3t#t9;}qN> zmpRtPz~|{uw--vbyV|x1Q9RGPNIedhMh0ZHlTRIQ@3r?39p3#xkA!^QSgdF>aY5W= zBnf3;tYvrw{3(s#?0AhAVG?qzJ4I88lSU$EV8UBH^u2H0h0C$^ZhL$CKtlz0nT334 z;|wGX-@bhdaOQA6P;jsPV-vj*ObPb^jd8U1;_)Zyv(7H6k=FHZKR@dCg+$#w-Q6yo zy61@1noDf(4z0@|Ge!xmZEx43O;SpfW<&+ui@%+)Km_u3ZP2hylol5j_E)7P((Q-8 z4kdLaK!Y8hntB|o>_9+3DldV&l`c~*$rSX_=9~2e=TEULIBT`w-$=^{m6evJ3wWtJ zUj}F2^ang#`bonFrp7VrK{{3v`RxC|K-3?YUe160F7hyyS5TE0(`&bz{e02VmOyB) zc0kNt&f)|##A{5fAIF4+O-N9D!kUI+ZjJB9-yW5b@?|I6el9qSX>sMYr>eocGBUYB zH`z<2Qcqz9WR;{ZLS)UBl$K}j;ZIdk z9f1-;Wrpn>fS?ogPh;}QAPEe7&#OG#s`!Foac69e=~9wS7MKec%}{4Z&jBrKPQUS*db{-fJ0pJW_PwVy0bwTkqAkmz@Yjl+r`vK7 z$wbDlGUEDYMh#pp8yH7G6nuTV5mO8rMTH{<=gLOSaKM~NS%nW+(Lkx(Ns57hQ^%*B zJozO1g*>_KwHNX}332i0h~J?Hk~CUsT0Z+zmc`w8xwD8$p|X?&IH1Y1SdB|QMaKK7 z3-rcb&SLUceQ&b*H}EcfyIfkpNmElZrUeE+r$!xYW4wM%@;mN?e#c}*T1rK(y*C%cZ+n$n3ayP|NH>%o z_vHF%u*|Z|ywdBgy)<&QPk1@talarX8{q&WB=sgo)vSEd?OqZ)q4`8O9>4V2@OI!t zf$`Q!Ip#(N!xDjCRDVv?R;*mmr zG|^Nr{rP;8O{cMw^TAHMOo2pduf9_>TeWK0eG?UrN>EAz2GB@eUR=AExi(Sr=%kaG zb1Uj0eXTPcR#X-mr!XdIcrL%ddL=shE{~<7nu@Anl8tF-eB^HXmVxB(YhZfUmNgei zR+Cw@t3Thxoj1|g^4fyEX|<+z1m>$_IFXJo!NKet9B*dQN z$`d(cfHkdrhgLzqvJs4Xt}G1Jx03gXUuj{Pou8gMynp{*zBnO|8l(gKT=9|=ScQ?l z52mc9M~YsEdu9)H>#yBEk0$##Ia8b_BTVY62v|>9hVHr3n=Ba6%W>@6?$p{r9Qx5W zmhX{ikv$$7dJ_0e7V5l3pL=`=kb#L`nF4%~+JMZ+c>5iJ{`V0dJ}xChz%)kMz3E^v z=dowku^F^k`>B*m>YRRdCOIU*FDHqJiWE`x$P~oaOpNJeTAy#ee#I3)%j!sY;_7!X z!u9gd`Qm<9Es-Q$sJPCXA`vMXOlg<$sK9EEXYEU)V<;=_{@FGj-yceG4|&ZIhz+HB z|0`lJopj3+F{tdpVi^QuWwE2xNNAKAHf>VZEnBs}^Gn zG{1aqqOR|}>+6MpA9a?fV4N;{V8bKZjK~IJ!>iYWjCuN76xHW`ub8mkMOFv&ggG;w ztTO~eDkHwaca~hP1`Q%cESD_S?!Y@hl|;$u;UNN7Crmp1n}^zXGSE|3qsx$wEH@hR1GA%CO&3 zZ@8%Utyi_Y!`ay?nn;4X`xIJF?ljJ4x;eqciC-DYCwq2o_E4gUJXE7jhxc;OmdT^t zQDlF#AbKSX9qat~HzbG;XgaMGJsQ`-QKuV2;s|aaT(RDAH~DV1R<-@=3=26Oc3$L{ zvdSb-=qhcl)1wI46j1CTz0J)Rd6FHU%(t~K=BTS`+NP!7?`)d&ssNuyav$ZqhVZhd ztUN-ur2sIzxSIH41PR*lprw6EYWt#8ur-&Fu}T9mf|AT)p<^Gnlc#%Mj8jA3J`7#Xu%NNRt&ES>7=eJfG~z?a z8)X^%mvjme&2zRBg_Xsry@WS9bT4U;*T=&vhe;XNIcX4s@OVD-F-uj?yx;P|MIlz$A2#A z2vQp6LXXWpGR_OAT3)i0S52JIl3B`^M*}r6((=Bpq+U-$QZGJ5!mC$Zu)B{RHhx}S zHX{4+s3zy7%(iDFIwAnVw!id0P}%Ui3qQws_V%~SLdRWQ6%K^3cfhB0&bHC085s=dicN=zGc6>9X{xG*d1Z0DRd{jLFBpFT4xgixT4larm0g)e>< znN-X^Sf+5rj%8=|N>KJ2s3U1*H$he};bp0lk1yUwyy zTucE**7Z=5eeR0oBUczS1x9lG0FbT#~DE6TO516`)E4GcVVSgRD@^v$FwhC}_ z-}Ve7oSmVnduxzkpoarrK+GE^#(#3mAq!Gml-DwYo99sUp$U&WQd`UY%7#V1O^*mRETzGjeAc2Hspwi@RBLGxw2g)tS z*dCTi6idW=3V4hRXX<@SCx=R1-x^w_;j)#YfC9ev9JZ+v4G`c03xqx%XKY(V* zSu)}2I$INA?)(ww9JTjEbIzLor#jY2z4~T&;%VYIW84DHsa6AN(Sq>HJzjt5r@Sj6cNrd@NZ{2l~vz z!Mm_7#bdR8={~7-|io<^+)@qG5g#z z!@ay?Ls{D&bcGBu%dOs<1wMKvq|neAA<>MPQVP_P-izq^)+1j6nIof6zjBZBZ78({ z!|na8yQPkBK09_VQM40&s~#L~st^#@JY5V6A^M#v7rQv~1QoHmuw^P2o1cUiLF2Lc>&-+A);-;n-7AC`7WIigdFrFjJ zISthVZ!jj+>S?$BX_+bXChjWC8V3(?cSZ8m?8%>TnM)Eo?zM3V@06c&Om`R$W$ znAkbEGZ~>x2u1YXZ>3PlXY+1dd3HWj81GLtrLmc3zN~p)B!P~&>2T@;QUaBPgaYnu z@VGv~8Mz1rxfn=okFMPXh;vqV?72aXxZ~)tL@e?Fj7sk26JL6^6Yenqf|ee=vRY{a2U>#-8Nh&no`0 z^x@564Gc>FP?maAExjpbwZm7rtue}uyKde$X~>e6`n|W0dW{J=j2$po{bwuE^KEM& zKA%la0Dkbf$6iZTcefcmdy{@3NXpDgc`Ggw^M+QL6skZ&wEaW$5WcgI*X^kU&i;WH zk@wr&*|Dq#tmIN+R*V z`KrD@jcSE&7zk!!n!C3mOfe*G|9)88Rnymtr`IC(*=$iA;(GwY2Jjn{6r{BM)lv z?DV*67Tat-cKt$jowmAyL0$Swg6cWy*Lasn*U`wZ!XgR5@czxR+uLzWN@r*Bm2L-k zx8p55lg0ralwIzPi`I@u8|m430vB;Dyv`-l+5B9WH=`Q5@%w*9euXOmO|FZs#ARmhJx z`D_RJf@zZKIRNIH`Ah$EAS}<4#g*>eg}>q6@@ErWZe|rJXY5HIZCG+ccCglz;bNJbrpx*mB(e zXRy})-mq~|=;blu{Ctu)=C!{e(c!H5C?(ZMy3k881q~bkBAHpz@D8LZA)`O_*|P^* zU^H_}SsBJhnShY+5R9$ax{Wnom3Q+{>~%)qS#oio(Djim<$q2Tk)2}(U{~Wh_V^Hm6^Fh>8U*EPonafVIruKwk znct$N_sH~cP_LD4aA;(!-xd3~z{zcE>GAmsAz<%M$zm>1k$b|Xf1lr8bGhbYY;Jn#W<+b`?R@d^&0OCZid5w932Qs(e=Xx3u6UpP_R*KLdy+_f|kuDJt*Sk!mfnb^@0Yue>8Dw!GEkBH+&g&-*$>=m~x=ICjucMrH#Hf>dy*0r3xtwUOwUjd5xuJQk730SBHC9 z7?tuKHnroAd6qYMsmrW*O_yVbe3_8fqq=68C}cRVa$$50_tTqfO|L zLtoyXj#}$4>$>c_8nn3&tSsR3*k&r1Ts}N?v(Q*?_K=;=i$~drw?9e9t_Y0)K&+B8 zeZKX@8~^Nwev{S~u?y!rc_yq=zUQ<9G}V* z;AkSXQBM;&>zCYbO2TUH_RuY_)Ax97s@8w}tg8X)^x0fzuDrdzF2pt;oTT|26-%t; zv|c4N>&Z)G=}*M23`yxKSS{@0Kg|-G4`$7`Kbua3KtBPU8ZxU2 zB$f42w9(U6$gk3&XC93l1hNRlq25|X8efw@SQsM%)AK2fOi?z~KGupY04qE(l{D-o|riXw$%8#@O=|iAapU$0357}W@!htD=ji`KE9X>;# z-gX($!9{lbCs%1cPUVo-2fyvE;~>8M!$_h(pVF((tAYn;@qpk_$+Rqr&{7)`HJDvC zgRvpzUz4iuU;A3!AGWhDt~2bU?0MJBzp>}SC5WxkaD(M< z^>bzx6!YlbmcTfzu#qscl;z0ftwF4ke6LMt^!S`o_iJ4^e-|^ztqU&N@oKm+)A4Ox z2Ee&ZtAS32jyApdXevmJDHVJT?Jq-UUot8$Di+>3<@7{Nc7FR5-TL4*#2B+eauaNB*%u@QCedVKyI z3xy@i%6SkKl^&R7jbqags46{CJ%CtC^Ltd+ihkv?E52R2Fqv}gqXWF+8IKM&&Ss@v zUBYY966%eJke-zoE(eE}Pe-QOg?6oSW*-7B}F4l z^ox}R)W{z7)$+yL^o)KkcT3Q}#qgbh^bDSR;kb~(h&{QoWGrj;#1Q98w{<7SnwZWy zE2-*_QkLJ#bhKk|+FDAoi>a0IEOpZ$Fjgz~Xv zfZq1{3texDB3>hq|`eXs7~8U?L}-RVCf+vk>~uL1rnY{0jP z(C8jYaIduKaNGh{kczvG>)cQbV)sAKKSv7IJvth$Ln}K4VE`JM7~~cSxD7Pk+RMe^ zj7I{W?bU<(2Lcb-Ybv#Q&9y7W&&To?OBpTJ{j2tvN101RPM&v;JDZ282~LPtxw?X& z4F2@=)OVr$=JtX!wEHZ^kMOA?FVM+>9DVKL?kyCQgF{Fti98|4zPg4vQS?Xt4`{F- z>KYa#q7aA`>8GY(eUP5=62ljBp80+O2$X;YGU6=g&gH+)uJIg}Uf@C! zs3KfGJ&C@pHa(F5#lq3~H|YhV=2@+FTmT?8ve?x6@SIn3ec0Tvc9pZo)7;vsW)sH4 zhvC#h#cLi~ePJ$eGjzm$+`% zahGgkGNzVe?Z*3M>yVez+M;Q0X2$hgm1nUJfnX!c&2TkoC;jm+Znd+& zFj7$m0n)YkiUYH8sfgn40hQM?kBpXIa;ko=7Ts>cSZ9T$YVp&sUKto7rH_sYUY zp#ht(>Oq2L^Uj(crJv*u>7N%Gvzt z3i;)6pRPpAid}G~+7$5vS~vQmi64B61Ul@8c#4j%jU*B>Lmkfxpk{`ap8jyXSBAK8 z(J+;t?JPGo_K(i$9q@qZE$G)+38`cd|C^|S9U(4<#P)-`ps47hW?kcsb~l%9BhF4} zB!4;2%NOJ=Y%p7d*J1D8l;P6=k>)A}EV_VE7brOgJ!rk=iNCSf+5&6#{qPgoUSp-p z;5WFTNVozwOeA(Az7C5&aoA7;>Ah!a0$-LmMNzn#k*Lg{eeRhmDpJ%My{4I5#}@qV z5}NlJp~k{fl!x>g8SkeRZpNNF)!x52Z2HWGr>uHeZ*@Wi<7dxTLB1VqqBYaf&@4D_ z1}*16`O6AD%uiR^$fLse&%?dg@s&UNj30B!2huLwo-97!dN=0M-Vgh{zg{h0QBQrM z1Eyh3Mh{xmB}73@YJM&1iAjwC4e$BKYjj{bxWFs}v0*eB+<9(@Du%S%TW=xWfTw4l z%pzj^$IY)P`=w4G@%7z|<7vDVbg8{7k4zlN7AU)DiGy-%jwHO-X9W}Yx+lVHgCbIJ z+Xanb-)m~(=T#g(ratU?UC<3JHl>*@_C@2-CB)g#6M)h6$J62Qd^aS;1VAyZw>BcTZDZAS~c2GTshUTAN zi-td5B?P-n2@3C+`iRlpdZJ-hhfo(OBV$U-%S-JnNDC)Grf9q_DvBF?Ii2(8+P%lP zno$?$@N1jNj3`MMqz|nR=L#Q2Z(8W(_+5>3AE_izRL}N*WBxLqsX5V~w?3?GHGY zo|Dr~VTNizo%!+6DU}dQc<=gs$SWWB+u<~}kOr!Po14(DVqnSxuj?VVI1S$dwb0{f z(5aKPHNoUm`DE1Fu&;vaXwC7;uU@_4m5mfW>Z?oS2SJNS(6fTpJ0p*|fo$qC>Y;4CwYvxn!G8gY=_S4{$ zm5bFrCOB^(>Z|stlOy}{IbbGV%D}G{L>Ex6{N&B#=%HGfKP>(?)hbbWZ{~Zuer2yQ z4TFH^s?W_bmuIAQKABYfjz`9{=iYfQn7sk_%M4Ux=PRj5n@RZnVkjc{SGHn%ECu^l zEP^@2`@d3`FeFgA754RqFm0^z9}P~~N=2fgf^+_{nsQL-uWbW91C-F9on_)m32wwN zO_6xzLS;NGtb+0HYP6uxl|pJ=brxNTd0g+!fzChrsoX`Y)O&DE$N_WAc(ZKihZ?{g zeX{pLKSm-Ink-q;l%hnD`a5{HJS>DSe?#$9Kt;+IP*e4fmS^_v$v38d!?Af`k!Q5` zj4`EuqkVyd96f~E;RMAFJxP!+>Z95d_1fr1{< z3nn&^$H7-3Hz!QS{9APk-vBgpsLM+QU%oB6I$XQ{meK3K>735yKchyPtw)*{*B_ZR3N`YX9U-k}0SAUgJxq^m%|F1OA->0p}0&nN={webP z^Du?prTCAWY}d8>`Tt~zMv8(p{3CGszZs-|hwVRQyYkmBPk5kP?>{ Ks}L~^{C@yUee>f0 literal 0 HcmV?d00001 diff --git a/source/devapi/database/dbmodel.rst b/source/devapi/database/dbmodel.rst index f2c5504..71c154c 100644 --- a/source/devapi/database/dbmodel.rst +++ b/source/devapi/database/dbmodel.rst @@ -51,6 +51,8 @@ PHP class name Table name ``PluginExampleProfile`` ``glpi_plugin_example_profiles`` ======================== ================================ +.. _dbfields: + Fields ++++++ diff --git a/source/plugins/hooks.rst b/source/plugins/hooks.rst index 6bf398a..c3db740 100644 --- a/source/plugins/hooks.rst +++ b/source/plugins/hooks.rst @@ -5,6 +5,8 @@ GLPI provides a certain amount of "hooks". Their goal is for plugins (mainly) to This page describes current existing hooks; but not the way they must be implemented from plugins. Please refer to the plugins development documentation. +.. _standards_hooks: + Standards Hooks ^^^^^^^^^^^^^^^ @@ -403,6 +405,8 @@ Hooks that cannot be classified in above categories :) ``post_plugin_clean`` Called after a plugin is cleaned (removed from the database after the folder is deleted) +.. _business_related_hooks: + Items business related ++++++++++++++++++++++ @@ -463,6 +467,8 @@ Hooks that can do some busines stuff on items. Permit to filter search results. +.. _display_related_hooks: + Items display related +++++++++++++++++++++ diff --git a/source/plugins/index.rst b/source/plugins/index.rst index b115ad6..b912f7a 100644 --- a/source/plugins/index.rst +++ b/source/plugins/index.rst @@ -27,3 +27,4 @@ If you want to see more advanced examples of what it is possible to do with plug notifications test javascript + tutorial diff --git a/source/plugins/tutorial.rst b/source/plugins/tutorial.rst new file mode 100644 index 0000000..565ffe3 --- /dev/null +++ b/source/plugins/tutorial.rst @@ -0,0 +1,2783 @@ +Plugin development tutorial +=========================== + +This tutorial explores the basic concepts of GLPI while building a simple plugin. It has been written to be explained during a training session, but most of this document could be read and used by people wanting to write plugins. Don't hesitate to suggest enhancements or contribute at this address: https://github.com/glpi-project/docdev + +.. warning:: + + ⚠️ Several prerequisites are required in order to follow this tutorial: + + - A base knowledge of GLPI usage + - A correct level in web development: + + - PHP + - HTML + - CSS + - SQL + - JavaScript (JQuery) + - Being familiar with command line usage + + +📝 In this first part, we will create a plugin named "My plugin" (key: ``myplugin``). +We will cover project startup as well as the setup of base elements. + +Prerequisites +-------------- + +Here are all the things you need to start your GLPI plugin project: + +* a functional web server, +* latest `GLPI `_ stable release installed locally +* a text editor or any IDE (like `vscode `_ or `phpstorm `_), +* `git `_ version management software. + +You may also need: + +* `Composer`_ PHP dependency software, to handle PHP libraries specific for your plugin. +* `Npm`_ JavaScript dependency software, to handle JavaScript libraries specific for your plugin. + +Start your project +------------------ + +.. warning:: + + ⚠️ If you have production data in your GLPI instance, make sure you disable all notifications before beginning the development. + This will prevent sending of tests messages to users present in the imported data. + +First of all, a few resources: + +* `Empty`_ plugin and its `documentation `_. This plugin is a kind of skeleton for quick starting a brand new plugin. +* `Example `_ plugin. It aims to do an exhaustive usage of GLPI internal API for plugins. + +My new plugin +^^^^^^^^^^^^^ + +Clone ``empty`` plugin repository in you GLPI ``plugins`` directory: + +:: + + cd /path/to/glpi/plugins + git clone https://github.com/pluginsGLPI/empty.git + +You can use the ``plugin.sh`` script in the ``empty`` directory to create your new plugin. You must pass it the name of your plugin and the first version number. In our example: + +:: + + cd empty + chmod +x plugin.sh + ./plugin.sh myplugin 0.0.1 + +.. note:: + + | ℹ️ Several conditions must be respected choosing a plugin name: no space or special character is allowed. + | This name will be used to declare your plugin directory, as well as methods, constants, database tables and so on. + | ``My-Plugin`` will therefore create the ``MyPlugin`` directory. + | Using capital characters will cause issues for some core functions. + + Keep it simple! + +When running the command, a new directory ``myplugin`` will be created at the same level as the ``empty`` directory (both in ``/path/to/glpi/plugin`` directory) as well as files and methods associated with an empty plugin skeleton. + +.. note:: + + ℹ️ If you cloned the ``empty`` project outside your GLPI instance, you can define a destination directory for your new plugin: + + .. code-block:: shell + + ./plugin.sh myplugin 0.0.1 /path/to/another/glpi/plugins/ + +Retrieving `Composer`_ dependencies +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In a terminal, run the following command: + +:: + + cd /path/to/glpi/plugins/myplugin + composer install + + +Minimal plugin structure +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. raw:: html + +

+   📂 glpi
+     📂 plugins
+       📂 myplugin
+          📁 ajax
+          📁 front
+          📁 src
+          📁 locales
+          📁 tools
+          📁 vendor
+          🗋 composer.json
+          🗋 hook.php
+          🗋 LICENSE
+          🗋 myplugin.xml
+          🗋 myplugin.png
+          🗋 Readme.md
+          🗋 setup.php
+   
+ +* ``📂 front`` directory is used to store our object actions (create, read, update, delete). +* ``📂 ajax`` directory is used for ajax calls. +* Your plugin own classes will be stored in the ``📂 src`` directory. +* `gettext`_ translations will be stored in the ``📂 locales`` directory. +* An optional ``📂 templates`` directory would contain your plugin `Twig `_ template files. +* ``📂 tools`` directory provides some optional scripts from the empty plugin for development and maintenance of your plugin. It is now more common to get those scripts from ``📂 vendor`` and ``📂 node_modules`` directories. +* ``📂 vendor`` directory contains: + + * PHP libraries for your plugin, + * helpful tools provided by ``empty`` model. + +* ``📂 node_modules`` directory contains JavaScript libraries for your plugin. +* ``🗋 composer.json`` files describes PHP dependencies for your project. +* ``🗋 package.json`` file describes JavaScript dependencies for your project. +* ``🗋 myplugin.xml`` file contains data description for :ref:`publishing your plugin `. +* ``🗋 myplugin.png`` image is often included in previous XML file as a representation for `GLPI plugins catalog `_ +* ``🗋 setup.php`` file is meant to :ref:`instantiate your plugin `. +* ``🗋 hook.php`` file :ref:`contains your plugin basic functions ` (install/uninstall, hooks, etc). + +.. _plugin_minimal_setupphp: + +minimal setup.php +^^^^^^^^^^^^^^^^^ + +After running ``plugin.sh`` script, there must be a ``🗋 setup.php`` file in your ``📂 myplugin`` directory. + +It contains the following code: + +**🗋 setup.php** + +.. code-block:: php + :linenos: + + `_ compliant even if for now our plugin does not contain any form. + +**🗋 setup.php** + +.. code-block:: php + :lineno-start: 9 + + 'MonNouveauPlugin', + 'version' => PLUGIN_MYPLUGIN_VERSION, + 'author' => 'Teclib\'', + 'license' => 'MIT', + 'homepage' => '', + 'requirements' => [ + 'glpi' => [ + 'min' => PLUGIN_MYPLUGIN_MIN_GLPI_VERSION, + 'max' => PLUGIN_MYPLUGIN_MAX_GLPI_VERSION, + ] + ]; + } + +This function specifies data that will be displayed in the ``Setup > Plugins`` menu of GLPI as well as some minimal constraints. +We reuse the constant ``PLUGIN_MYPLUGIN_VERSION`` declared above. +You can of course change data according to your needs. + +.. note:: + + ℹ️ **Choosing a license** + + The choice of a license is **important** and has many consequences on the future use of your developments. Depending on your preferences, you can choose a more permissive or restrictive orientation. + Websites that can be of help exists, like https://choosealicense.com/. + + In our example, `MIT `_ license has been choose. + It's a very popular choice which gives user enough liberty using your work. It just asks to keep the notice (license text) and respect the copyright. You can't be dispossessed of your work, paternity must be kept. + +**🗋 setup.php** + +.. code-block:: php + :lineno-start: 32 + + Plugins`` menu. + + +Creating an object +------------------ + +| 📝 In this part, we will add an itemtype to our plugin and make it interact with GLPI. +| This will be a parent object that will regroup several "assets". +| We will name it "Superasset". + +.. _commondntm_usage: + +`CommonDBTM`_ usage and classes creation +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +This super class adds the ability to manage items in the database. +Your working classes (in the ``src`` directory) can inherit from it and are called "itemtype" by convention. + +.. note:: + + ℹ️ **Conventions:** + + * Classes must respect `PSR-12 naming conventions `_. We maintain a :doc:`guide on coding standards <../codingstandards>` + + * :ref:`SQL tables ` related to your classes must respect that naming convention: ``glpi_plugin_pluginkey_names`` + + * a global ``glpi_`` prefix + * a prefix for plugins ``plugin_`` + * plugin key ``myplugin_`` + * itemtype name in plural form ``superassets`` + + * :ref:`Tables columns ` must also follow some conventions: + + * there must be an ``auto-incremented primary`` field named ``id`` + * foreign keys names use that referenced table name without the global ``glpi_`` prefix and with and ``_id`` suffix. example: ``plugin_myotherclasses_id`` references ``glpi_plugin_myotherclasses`` table + + **Warning!** GLPI does not use database foreign keys constraints. Therefore you must not use ``FOREIGN`` or ``CONSTRAINT`` keys. + + * Some extra advice: + + * always end your files with an extra carriage return + * never use the closing PHP tag ``?>`` - see https://www.php.net/manual/en/language.basic-syntax.instruction-separation.php + + Main reason for that is to avoid concatenation errors when using require/include functions, and prevent unexpected outputs. + +We will create our first class in ``🗋 Superasset.php`` file in our plugin ``📂src`` directory: + +.. raw:: html + +
+   📂glpi
+      📂plugins
+         📂myplugin
+            ...
+            📂src
+               🗋 Superasset.php
+            ...
+   
+ +We declare a few parts: + +**🗋 src/Superasset.php** + +.. code-block:: php + :linenos: + + `_ + +.. note:: + + ℹ️ Here are most common `CommonDBTM`_ inherited methods: + + `add(array $input) `_ + : Add an new object in database table. + ``input`` parameter contains table fields. + If add goes well, the object will be populated with provided data. + It returns the id of the new added line, or ``false`` if there were an error. + + .. code-block:: php + :linenos: + + add([ + 'name' => 'My super asset' + ]); + if (!superassets_id) { + //super asset has not been created :'( + } + + `getFromDB(integer $id) `_ + : load an item from database into current object using its id. + Fetched data will be available from ``fields`` object property. + It returns ``false`` if the object does not exists. + + .. code-block:: php + :lineno-start: 11 + + getFromDB($superassets_id)) { + //super $superassets_id has been lodaded. + //you can access its data from $superasset->fields + } + + `update(array $input) `_ + : update fields of ``id`` identified line with ``$input`` parameter. + The ``id`` key must be part of ``$input``. + Returns a boolean. + + .. code-block:: php + :lineno-start: 16 + + update([ + 'id' => $superassets_id, + 'comment' => 'my comments' + ]) + ) { + //super asset comment has been updated in databse. + } + + `delete(array $input, bool $force = false) `_ + : remove ``id`` identified line corresponding. + The ``id`` key must be part of ``$input``. + ``$force`` parameter indicates if the line must be place in trashbin (``false``, and a ``is_deleted`` field must be present in the table) or removed (``true``). + Returns a boolean. + + .. code-block:: php + :lineno-start: 23 + + delete(['id' => $superassets_id])) { + //super asset has been moved to trashbin + } + + if ($superasset->delete(['id' => $superassets_id], true)) { + //super asset is no longer present in database. + //a message will be displayed to user on next displayed page. + } + +Installation +^^^^^^^^^^^^ + +In the ``plugin_myplugin_install`` function of your ``🗋 hook.php`` file, we will manage the creation of the database table corresponding to our itemtype ``Superasset``. + +**🗋 hook.php** + +.. code-block:: php + :linenos: + + tableExists($table)) { + //table creation query + $query = "CREATE TABLE `$table` ( + `id` int unsigned NOT NULL AUTO_INCREMENT, + `is_deleted` TINYINT NOT NULL DEFAULT '0', + `name` VARCHAR(255) NOT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB + DEFAULT CHARSET={$default_charset} + COLLATE={$default_collation}"; + $DB->queryOrDie($query, $DB->error()); + } + + //execute the whole migration + $migration->executeMigration(); + + return true; + } + +In addition, of a primary key, ``VARCHAR`` field to store a name entered by the user and a flag for the the trashbin. + +.. note:: + 📝 You of course can add some other fields with other types (stay reasonable 😉). + +To handle migration from a version to another of our plugin, we will use GLPI `Migration`_ class. + +**🗋 hook.php** + +.. code-block:: php + :linenos: + + tableExists($table)) { + // missing field + $migration->addField( + $table, + 'fieldname', + 'string' + ); + + // missing index + $migration->addKey( + $table, + 'fieldname' + ); + } + + //execute the whole migration + $migration->executeMigration(); + + return true; + } + +.. warning:: + + ℹ️ `Migration`_ class provides several methods that permit to manipulate tables and fields. + All calls will be stored in queue that will be executed when calling ``executeMigration`` method. + + Here are some examples: + + `addField($table, $field, $type, $options) `_ + adds a new field to a table + + `changeField($table, $oldfield, $newfield, $type, $options) `_ + change a field name or type + + `dropField($table, $field) `_ + drops a field + + `dropTable($table) `_ + drops a table + + `renameTable($oldtable, $newtable) `_ + rename a table + + See `Migration`_ documentation for all other possibilities. + + .. raw:: html + +
+ + ``$type`` parameter of different functions is the same as the private `Migration::fieldFormat() method `_ it allows shortcut for most common SQL types (bool, string, integer, date, datetime, text, longtext, autoincrement, char) + + +Uninstallation +^^^^^^^^^^^^^^ + +To uninstall our plugin, we want to clean all related data. + +**🗋 hook.php** + +.. code-block:: php + :linenos: + + tableExists($table)) { + $DB->doQueryOrDie( + "DROP TABLE `$table`", + $DB->error() + ); + } + } + + return true; + } + + +Framework usage +^^^^^^^^^^^^^^^ + +Some useful functions + +.. code-block:: php + + + 📂 glpi + 📂 plugins + 📂 myplugin + ... + 📂 front + 🗋 superasset.php + 🗋 superasset.form.php + ... + + + +.. warning:: + + ℹ️ Into those files, we will import GLPI framework with the following: + + .. code-block:: php + + `. + +**🗋 front/superasset.php** + +.. code-block:: php + :linenos: + + add($_POST); + + if ($_SESSION['glpibackcreated']) { + Html::redirect(Superasset::getFormURL()."?id=".$newID); + } + Html::back(); + + } else if (isset($_POST["delete"])) { + $supperasset->delete($_POST); + $supperasset->redirectToList(); + + } else if (isset($_POST["restore"])) { + $supperasset->restore($_POST); + $supperasset->redirectToList(); + + } else if (isset($_POST["purge"])) { + $supperasset->delete($_POST, 1); + $supperasset->redirectToList(); + + } else if (isset($_POST["update"])) { + $supperasset->update($_POST); + \Html::back(); + + } else { + // fill id, if missing + isset($_GET['id']) + ? $ID = intval($_GET['id']) + : $ID = 0; + + // display form + Html::header( + Superasset::getTypeName(), + $_SERVER['PHP_SELF'], + "plugins", + Superasset::class, + "superasset" + ); + $supperasset->display(['id' => $ID]); + Html::footer(); + } + +All common actions defined here are handled from `CommonDBTM`_ class. +For missing display action, we will create a ``showForm`` method in our ``Superasset`` class. +Note this one already exists in ``CommonDBTM`` and is displayed using a generic Twig template. + +We will use our own template that will extends the generic one (because it only displays common fields). + +**🗋 src/Superasset.php** + +.. code-block:: php + :linenos: + + initForm($ID, $options); + // @myplugin is a shortcut to the **templates** directory of your plugin + TemplateRenderer::getInstance()->display('@myplugin/superasset.form.html.twig', [ + 'item' => $this, + 'params' => $options, + ]); + + return true; + } + } + +**🗋 templates/superasset.form.html.twig** + +.. code-block:: twig + :linenos: + + {% extends "generic_show_form.html.twig" %} + {% import "components/form/fields_macros.html.twig" as fields %} + + {% block more_fields %} + blabla + {% endblock %} + +After that step, a call in our browser to `http://glpi/plugins/myplugin/front/superasset.form.php` should display the creation form. + +.. warning:: + + ℹ️ ``🗋 components/form/fields_macros.html.twig`` file imported in the example includes Twig functions or macros to display common HTML fields like: + + ``{{ fields.textField(name, value, label = '', options = {}) }}`` + : HTML code for a ``text`` input. + + ``{{ fields.hiddenField(name, value, label = '', options = {}) }`` + : HTML code for a ``hidden`` input. + + ``{{ dateField(name, value, label = '', options = {}) }`` + : HTML code for a date picker (using `flatpickr `_) + + ``{{ datetimeField(name, value, label = '', options = {}) }`` + : HTML code for a datetime picker (using `flatpickr `_) + + See ``🗋 templates/components/form/fields_macros.html.twig`` file in source code for more details and capacities. + + +Adding to menu and breadcrumb +----------------------------- + +We would like to access our pages without entering their URL in our browser. + +We'll therefore define our first `Hook` in our plugin ``init``. + +Open ``setup.php`` and edit ``plugin_init_myplugin`` function: + +**🗋 setup.php** + +.. code-block:: php + :linenos: + + Superasset::class + ]; + } + +This `hook` indicates our ``Superasset`` itemtype defines a menu display function. +Edit our class and add related methods: + +**🗋 src/Superasset.php** + +.. code-block:: php + :linenos: + + __("My plugin", 'myplugin'), + 'page' => $search, + + // define sub-options + // we may have multiple pages under the "Plugin > My type" menu + 'options' => [ + 'superasset' => [ + 'title' => $title, + 'page' => $search, + + //define standard icons in sub-menu + 'links' => [ + 'search' => $search, + 'add' => $form + ] + ] + ] + ]; + + return $menu; + } + } + +``getMenuContent`` function may seem redundant at first, but each of the coded entries relates to different parts of the display. +The ``options`` part is used to have a fourth level of breadcrumb and thus have a clickable submenu in your entry page. + +.. image:: /_static/images/breadcrumbs.png + :alt: Breadcrumb + +Each ``page`` key is used to indicate on which URL the current part applies. + +.. note:: + + ℹ️ GLPI menu is loaded in ``$_SESSION['glpimenu']`` on login. + To see your changes, either use the ``DEBUG`` mode, or disconnect and reconnect. + +.. note:: + + ℹ️ It is possible to have only one menu level for the plugin (3 globally), just move the ``links`` part to the first level of the ``$menu`` array. + +.. note:: + + ℹ️ It is also possible to define custom ``links``. + You just need to replace the key (for example, add or search) with an html containing an image tag: + + .. code-block:: php + + 'links' = [ + '' => $url + ] + +Defining tabs +------------- + +GLPI proposes three methods to define tabs: + +`defineTabs(array $options = []) `_: declares classes that provides tabs to current class. + +`getTabNameForItem(CommonGLPI $item, boolean $withtemplate = 0) `_: declares titles displayed for tabs. + +`displayTabContentForItem(CommonGLPI $item, integer $tabnum = 1, boolean $withtemplate = 0) `_: allow displaying tabs contents. + +Standards tabs +^^^^^^^^^^^^^^ + +Some GLPI internal API classes allows you to add a behaviour with minimal code. + +It's true for notes (`Notepad`_) and history (`Log`_). + +Here is an example for both of them: + +**🗋 src/Superasset.php** + +.. code-block:: php + :linenos: + + addDefaultFormTab($tabs) + ->addStandardTab(Notepad::class, $tabs, $options) + ->addStandardTab(Log::class, $tabs, $options); + + return $tabs; + } + } + +Display of an instance of your itemtype from the page ``front/superasset.php?id=1`` should now have 3 tabs: + +* Main tab with your itemtype name +* Notes tab +* History tab + + +Custom tabs +^^^^^^^^^^^ + +On a similar basis, we can target another class of our plugin: + +**🗋 src/Superasset.php** + +.. code-block:: php + :linenos: + + addDefaultFormTab($tabs) + ->addStandardTab(Superasset_Item::class, $tabs, $options); + ->addStandardTab(Notepad::class, $tabs, $options) + ->addStandardTab(Log::class, $tabs, $options); + + return $tabs; + } + +In this new class we will define two other methods to control title and content of the tab: + +**🗋 src/Superasset_Item.php** + +.. code-block:: php + :linenos: + + getType()) { + case Superasset::class: + $nb = countElementsInTable(self::getTable(), + [ + 'plugin_myplugin_superassets_id' => $item->getID() + ] + ); + return self::createTabEntry(self::getTypeName($nb), $nb); + } + return ''; + } + + /** + * Display tabs content + */ + static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) + { + switch ($item->getType()) { + case Superasset::class: + return self::showForSuperasset($item, $withtemplate); + } + + return true; + } + + /** + * Specific function for display only items of Superasset + */ + static function showForSuperasset(Superasset $superasset, $withtemplate = 0) + { + TemplateRenderer::getInstance()->display('@myplugin/superasset_item_.html.twig', [ + 'superasset' => $superasset, + ]); + } + } + +As previously, we will use a Twig template to handle display. + +**🗋 templates/superasset_item.html.twig** + +.. code-block:: twig + :linenos: + + {% import "components/form/fields_macros.html.twig" as fields %} + + example content + +.. note:: + + 📝 **Exercise**: + For the rest of this part, you will need to complete our plugin to allow the installation/uninstallation of the data of this new class ``Superasset_Item``. + + Table should contains following fields: + + * an identifier (id) + * a foreign key to ``plugin_myplugin_superassets`` table + * two fields to link with an itemtype: + + * ``itemtype`` which will store the itemtype class to link to (`Computer`_ for example) + * ``items_id`` the id of the linked asset + + Your plugin must be re-installed or updated for the table creation to be done. + You can force the plugin status to change by incrementing the version number in the ``setup.php`` file. + + For the exercise, we will only display computers (`Computer`_) displayed with the following code: + + .. code-block:: twig + + {{ fields.dropdownField( + 'Computer', + 'items_id', + '', + __('Add a computer') + ) }} + + We will include a mini form to insert related items in our table. Form actions can be handled from ``myplugin/front/supperasset.form.php`` file. + + Note GLPI forms submitted as ``POST`` will be protected with a CRSF token.. + You can include a hidden field to validate the form: + + .. code-block:: twig + + + + We will also display a list of computers already associated below the form. + +.. _using-core-objects: + +Using core objects +^^^^^^^^^^^^^^^^^^ + +We can also allow our class to add tabs on core objects. +We will declare this in a new line in our ``init`` function: + +**🗋 setup.php** + +.. code-block:: php + :linenos: + + Computer::class + ]); + } + +Title and content for this tab are done as previously with: + +* ``CommonDBTM::getTabNameForItem()`` +* ``CommonDBTM::displayTabContentForItem()`` + +.. note:: + + 📝 **Exercise**: + Complete previous methods to display on computers a new tab with associated ``Superasset``. + +Defining Search options +----------------------- + +:ref:`Search options ` is an array of columns for GLPI search engine. They are used to know for each itemtype how the database must be queried, and how data should be displayed. + +In our class, we must declare a ``rawSearchOptions`` method: + +**🗋 src/Superasset.php** + +.. code-block:: php + :linenos: + + 'common', + 'name' => __('Characteristics') + ]; + + $options[] = [ + 'id' => 1, + 'table' => self::getTable(), + 'field' => 'name', + 'name' => __('Name'), + 'datatype' => 'itemlink' + ]; + + $options[] = [ + 'id' => 2, + 'table' => self::getTable(), + 'field' => 'id', + 'name' => __('ID') + ]; + + $options[] = [ + 'id' => 3, + 'table' => Superasset_Item::getTable(), + 'field' => 'id', + 'name' => __('Number of associated assets', 'myplugin'), + 'datatype' => 'count', + 'forcegroupby' => true, + 'usehaving' => true, + 'joinparams' => [ + 'jointype' => 'child', + ] + ]; + + return $options; + } + } + +Following this addition, we should be able to select our new columns from our asset list page: + +.. image:: /_static/images/search.png + :alt: Search form + +Those options will also be present in search criteria list of that page. + +Each ``option`` is identified by an ``id`` key. +This key is used in other parts of GLPI. +It **must be absolutely unique**. +By convention, '1' and '2' are "reserved" for the object name and ID. + +The :ref:`search options documentation ` describes all possible options. + +Using other objects +^^^^^^^^^^^^^^^^^^^ + +It is also possible to improve another itemtype search options. +As an example, we would like to display associated "Superasset" on in the computer list: + +**🗋 hook.php** + +.. code-block:: php + :lineno-start: 50 + + 12345, + 'table' => Superasset::getTable(), + 'field' => 'name', + 'name' => __('Associated Superassets', 'myplugin'), + 'datatype' => 'itemlink', + 'forcegroupby' => true, + 'usehaving' => true, + 'joinparams' => [ + 'beforejoin' => [ + 'table' => Superasset_Item::getTable(), + 'joinparams' => [ + 'jointype' => 'itemtype_item', + ] + ] + ] + ]; + } + + return $sopt; + } + +As previously, you must provide an ``id`` for your new search options that does not override existing ones for ``Computer``. + +You can use a script from the ``tools`` folder of the GLPI git repository (not present in the "release" archives) to help you list the **id** already declared (by the core and plugins present on your computer) for a particular itemtype. + +.. code-block:: shell + + /usr/bin/php /path/to/glpi/tools/getsearchoptions.php --type=Computer + +Search engine display preferences +--------------------------------- + +We just have added new columns to our itemtype list. +Those columns are handled by ``DisplayPreference`` object (``glpi_displaypreferences`` table). +They can be defined as global (set ``0`` for ``users_id`` field) or personal (set ``users_id`` field to the user id). They are sorted (``rank`` field) and target an itemtype plus a ``searchoption`` (``num`` field). + +.. warning:: + + **⚠️ Warning** + Global preferences are applied to all users that don't have any personal preferences set. + +.. note:: + + 📝 **Exercise**: + You will change installation and uninstallation functions of your plugin to add and remove global preferences so objects list display some columns. + +Standard events hooks +--------------------- + +During a GLPI object life cycle, we can intervene via our plugin before and after each event (add, modify, delete). + +For our own objects, following methods can be implemented: + +* `prepareInputForAdd `_ +* `post_addItem `_ +* `prepareInputForUpdate `_ +* `post_updateItem `_ +* `pre_deleteItem `_ +* `post_deleteItem `_ +* `post_purgeItem `_ + +For every event applied on the database, we have a method that is executed before, and another after. + +.. note:: + + 📝 **Exercise**: + Add required methods to ``PluginMypluginSuperasset`` class to check the ``name`` field is properly filled when adding and updating. + + On effective removal, we must ensure linked data from other tables are also removed. + +Plugins can also intercept standard core events to apply changes (or even refuse the event). Here are the names of the `hooks`: + +.. code-block:: php + :linenos: + + ` especially on :ref:`standard events ` part. + +For all those calls, we will get an instance of the current object in parameter of our ``callback`` function. We will be able to access its current fields (``$item->fields``) or those sent by the form (``$item->input``). +As all PHP objects, this instance will be passed by reference. + +We will declare one of those hooks usage in the plugin init function and add a ``callback`` function: + +**🗋 setup.php** + +.. code-block:: php + :linenos: + + 'myplugin_computer_updated' + ]; + + // callback a class method + $PLUGIN_HOOKS['item_add']['myplugin'] = [ + 'Computer' => [ + Superasset::class, 'computerUpdated' + ] + ]; + } + +In both cases (``hook.php`` function or class method), the prototype of the functions will be made on this model: + +.. code-block:: php + :linenos: + + input = []; + + // store a message in session for warn user + Session::addMessageAfterRedirect('Action forbidden because...'); + + return; + } + } + +.. note:: + + 📝 **Exercise**: + Use a `hook` to intercept the purge of a computer and remove associated with a ``Superasset`` lines if any. + +Importing libraries (JavaScript / CSS) +-------------------------------------- + +Plugins can declare import of additional libraries from their ``init`` function. + +**🗋 setup.php** + +.. code-block:: php + :linenos: + + `_: + + * ```` + + #. On ticket edition page, add an icon to self-associate as a requester on the model of the one present for the "assigned to" part. + +Display hooks +------------- + +Since GLPI 9.1.2, it is possible to display data in native objects forms via new hooks. +See :ref:`display related hooks ` in plugins documentation. + +As previous `hooks`, declaration will look like: + +**🗋 setup.php** + +.. code-block:: php + :linenos: + + $this, 'options' => &$options]); + +.. note:: + + 📝 **Exercice**: + Add the number of associated ``Superasset`` in the computer form header. + It should be a link to the :ref:`previous added tab ` to computers. + This link will target the same page, but with the ``forcetab=PluginMypluginSuperasset$1`` parameter. + +Adding a configuration page +--------------------------- + +We will add a tab in GLPI configuration so some parts of our plugin can be optional. + +We previously added a tab to the form for computers using hooks in ``setup.php`` file. We will define two configuration options to enable/disable those tabs. + +GLPI provides a ``glpi_configs`` table to store software configuration. It allows plugins to save their own data without defining additional tables. + +First of all, let's create a new ``Config.php`` class in the ``src/`` folder with the following skeleton: + +**🗋 src/Config.php** + +.. code-block:: php + :linenos: + + getType()) { + case Config::class: + return self::createTabEntry(self::getTypeName()); + } + return ''; + } + + static function displayTabContentForItem( + CommonGLPI $item, + $tabnum = 1, + $withtemplate = 0 + ) { + switch ($item->getType()) { + case Config::class: + return self::showForConfig($item, $withtemplate); + } + + return true; + } + + static function showForConfig( + Config $config, + $withtemplate = 0 + ) { + global $CFG_GLPI; + + if (!self::canView()) { + return false; + } + + $current_config = self::getConfig(); + $canedit = Session::haveRight(self::$rightname, UPDATE); + + TemplateRenderer::getInstance()->display('@myplugin/config.html.twig', [ + 'current_config' => $current_config, + 'can_edit' => $canedit + ]); + } + } + +Once again, we manage display from a dedicated template file: + +**🗋 templates/config.html.twig** + +.. code-block:: twig + :linenos: + + {% import "components/form/fields_macros.html.twig" as fields %} + + {% if can_edit %} + + + + + + {{ fields.dropdownYesNo( + 'myplugin_computer_tab', + current_config['myplugin_computer_tab'], + __("Display tab in computer", 'myplugin') + ) }} + + {{ fields.dropdownYesNo( + 'myplugin_computer_form', + current_config['myplugin_computer_form'], + __("Display information in computer form", 'myplugin') + ) }} + + + + {% endif %} + +This skeleton retrieves the calls to a tab in the ``Setup > General`` menu to display the dedicated form. +It is useless to add a ``front`` file because the GLPI ``Config`` object already offers a form display. + +Note that we display, from the ``myplugin_computer_form`` two yes/no fields named ``myplugin_computer_tab`` and ``myplugin_computer_form``. + +.. note:: + + ✍️ Complete ``setup.php`` file by defining the new tab in the ``Config`` class. + + You also have to add those new configuration entries management to install/uninstall methods. + You can use the following: + + .. code-block:: php + + '##config_default_value##' + ]); + + .. code-block:: php + + deleteByCriteria(['context' => '##context##']); + + Do not forget to replace ``##`` surrounded terms with your own values! + + +Managing rights +--------------- + +To limit access to our plugin features to some of our users, we can use the GLPI `Profile`_ class. + +This will check ``$rightname`` property of class that inherits `CommonDBTM`_ for all standard events. +Those check are done by static ``can*`` functions: + + +* `canCreate `_ for `add `_ +* `canUpdate `_ for `update `_ +* `canDelete `_ for `delete `_ +* `canPurge `_ for `delete `_ when ``$force`` parameter is set to ``true`` + +In order to customize rights, we will redefine those static methods in our classes. + +If we need to check a right manually in our code, the `Session`_ class provides some methods: + +.. code-block:: php + :linenos: + + `_ +* `checkRightsOr `_ + +.. warning:: + + ℹ️ If you need to check a right in an SQL query, use bitwise operators ``&`` and ``|``: + + .. code-block:: php + + request([ + 'SELECT' => 'glpi_profiles_users.users_id', + 'FROM' => 'glpi_profiles_users', + 'INNER JOIN' => [ + 'glpi_profiles' => [ + 'ON' => [ + 'glpi_profiles_users' => 'profiles_id' + 'glpi_profiles' => 'id' + ] + ], + 'glpi_profilerights' => [ + 'ON' => [ + 'glpi_profilerights' => 'profiles_id', + 'glpi_profiles' => 'id' + ] + ] + ], + 'WHERE' => [ + 'glpi_profilerights.name' => 'ticket', + 'glpi_profilerights.rights' => ['&', (READ | CREATE)]; + ] + ]); + + In this code example, the ``READ | CREATE`` make a bit sum, and the ``&`` operator compare the value at logical level with the table. + +Possible values for standard rights can be found in the ``inc/define.php`` file of GLPI: + +.. code-block:: php + :linenos: + + ` ``$rightname = 'computer'`` on which we've automatically rights as ``super-admin``. + We will now create a specific right for the plugin. + +First of all, let's create a new class dedicated to profiles management: + +**🗋 src/Profile.php** + +.. code-block:: php + :linenos: + + getField('id') + ) { + return self::createTabEntry(self::getTypeName()); + } + return ''; + } + + static function displayTabContentForItem( + CommonGLPI $item, + $tabnum = 1, + $withtemplate = 0 + ) { + if ( + $item instanceof Glpi_Profile + && $item->getField('id') + ) { + return self::showForProfile($item->getID()); + } + + return true; + } + + static function getAllRights($all = false) + { + $rights = [ + [ + 'itemtype' => Superasset::class, + 'label' => Superasset::getTypeName(), + 'field' => 'myplugin::superasset' + ] + ]; + + return $rights; + } + + + static function showForProfile($profiles_id = 0) + { + $profile = new Glpi_Profile(); + $profile->getFromDB($profiles_id); + + TemplateRenderer::getInstance()->display('@myplugin/profile.html.twig', [ + 'can_edit' => self::canUpdate(), + 'profile' => $profile + 'rights' => self::getAllRights() + ]); + } + } + +Once again, display will be done from a Twig template: + +**🗋 templates/profile.html.twig** + +.. code-block:: twig + :linenos: + + {% import "components/form/fields_macros.html.twig" as fields %} +
+
+ + + + {% if can_edit %} + + {% endif %} +
+
+ +We declare a new tab on ``Profile`` object from our ``init`` function: + +**🗋 setup.php** + +.. code-block:: php + :linenos: + + Profile::class + ]); + } + +And we tell installer to setup a minimal right for current profile (``super-admin``): + +**🗋 hook.php** + +.. code-block:: php + :linenos: + + Profiles`` menu and can change the ``$rightname`` property of our class to ``myplugin::superasset``. + +Extending standard rights +^^^^^^^^^^^^^^^^^^^^^^^^^ + +If we need specific rights for our plugin, for example the right to perform associations, we must override the ``getRights`` function in the class defining the rights. + +In defined above example of the ``PluginMypluginProfile`` class, we added a ``getAllRights`` method which indicates that the right ``myplugin::superasset`` is defined in the ``PluginMypluginSuperasset`` class. +This one inherits from ``CommonDBTM`` and has a ``getRights`` method that we can override: + +**🗋 src/Superasset.php** + +.. code-block:: php + :linenos: + + `. + +To achieve that in your plugin, you must declare a hook in the ``init`` function: + +**🗋 setup.php** + +.. code-block:: php + :linenos: + + getAction()) { + case 'myaction_key': + echo __("fill the input"); + echo Html::input('myinput'); + echo Html::submit(__('Do it'), ['name' => 'massiveaction']) . ""; + + break; + } + + return parent::showMassiveActionsSubForm($ma); + } + + static function processMassiveActionsForOneItemtype( + MassiveAction $ma, + CommonDBTM $item, + array $ids + ) { + switch ($ma->getAction()) { + case 'myaction_key': + $input = $ma->getInput(); + + foreach ($ids as $id) { + + if ( + $item->getFromDB($id) + && $item->doIt($input) + ) { + $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_OK); + } else { + $ma->itemDone($item->getType(), $id, MassiveAction::ACTION_KO); + $ma->addMessage(__("Something went wrong")); + } + } + return; + } + + parent::processMassiveActionsForOneItemtype($ma, $item, $ids); + } + } + +.. note:: + + 📝 **Exercise**: + With the help of the official documentation on :doc:`massive actions <../devapi/massiveactions>`, complete in your plugin the above methods to allow the linking with a computer from "Super assets" massive actions. + + You can display a list of computers with: + + .. code-block:: php + + Computer::dropdown(); + +It is also possible to add massive actions to GLPI native objects. +To achieve that, you must declare a ``_MassiveActions`` function in the ``hook.php`` file: + +**🗋 hook.php** + +.. code-block:: php + :linenos: + + Notifications`` menu. + On a development environment, you can install `mailhog `_ or `mailcatcher `_ which expose a local SMTP server and allow you to get emails sent by GLPI in a graphical interface. + + Please also note that GLPI queues all notifications rather than sending them directly. The only exception to this is the test email notification. + All "pending" notifications are visible in the ``Administration > Notification queue`` menu. + You can send notifications immediately from this menu or by forcing the ``queuednotification`` automatic action. + +The GLPI notification system allows sending alerts to the actors of a recorded event. +By default, notifications can be sent by email or as browser notifications, but other channels may be available from plugins (or you can add your own one). + +That system is divided in several classes: + +* ``Notification``: the triggering item. It receives common data like name, if it is active, sending mode, event, content (``NotificationTemplate``), etc. + + .. image:: /_static/images/Notification.png + :alt: Add notification form + +* ``NotificationTarget``: defines notification recipients. + It is possible to define recipients based on the triggering item (author, assignee) or static recipients (a specific user, all users of a specific group, etc). + + .. image:: /_static/images/NotificationTarget.png + :alt: Choose actor form + +* ``NotificationTemplate``: notification templates are used to build the content, which can be chosen from Notification form. CSS can be defined in the templates and it receives one or more ``NotificationTemplateTranslation`` instances. + + .. image:: /_static/images/NotificationTemplate.png + :alt: Notification template form + +* ``NotificationTemplateTranslation``: defines the translated template content. If no language is specified, it will be the default translation. If no template translation exists for a user's language, the default translation will be used. + + The content is dynamically generated with tags provided to the user and completed by HTML. + + .. image:: /_static/images/NotificationTemplateTranslation.png + :alt: Template translation form + +All of these notification-related object are natively managed by GLPI core and does not require any development intervention from us. + +We can however trigger a notification execution via the following code: + +.. code-block:: php + + __('My event label', 'myplugin') + ]; + } + + function getDatasForTemplate($event, $options = []) + { + $this->datas['##myplugin.name##'] = __('Name'); + } + } + +We have to declare our ``Superasset`` object can send notifications in our ``init`` function: + +**🗋 setup.php** + +.. code-block:: php + :linenos: + + true + ]); + } + +With this minimal code it's possible to create using the GLPI UI, a new notification targeting our ``Superasset`` itemtype and with the 'My event label' event and then use the ``raiseEvent`` method with these parameters. + +.. note:: + + 📝 **Exercise**: + Along with an effective sending test, you will manage installation and uninstallation of notification and related objects (templates, translations). + + You can see an example (still incomplete) on :doc:`notifications in plugins documentation `. + +Automatic actions +----------------- + +This GLPI feature provides a task scheduler executed silently from user usage (GLPI mode) or by the server in command line (CLI mode) via a call to the ``front/cron.php`` file of GLPI. + +.. image:: /_static/images/crontask.png + :alt: + +To add one or more automatic actions to our class, we will add those methods: + +* ``cronInfo``: possible actions for the class, and associated labels +* ``cron*Action*``: a method for each action defined in ``cronInfo``. Those are called to manage each action. + +**🗋 src/Superasset.php** + +.. code-block:: php + :linenos: + + __('action desc', 'myplugin')]; + } + return []; + } + + static function cronMyaction($task = NULL) + { + // do the action + + return true; + } + } + +To tell GLPI that the automatic action exists, you just have to register it: + +**🗋 hook.php** + +.. code-block:: php + :linenos: + + '', + 'mode' => \CronTask::MODE_EXTERNAL + ] + ); + } + +No need to manage uninstallation (`unregister`) as GLPI will handle that itself when the plugin is uninstalled. + +.. _plugin_publication: + +Publishing your plugin +---------------------- + +When you consider your plugin is ready and covers a real need, you can submit it to the community. + +The `plugins catalog `_ allows GLPI users to discover, download and follow plugins provided by the community as well as first-party plugins provided by Teclib'. + +Just publish your code to an publicly accessible GIT repository (`github `_, `gitlab `_, ...) with an `open source license `_ of your choice and prepare an XML description file of your plugin. +The XML file must follow this structure: + +.. code-block:: xml + :linenos: + + + Displayed name + System name + stable + http://link/to/logo/with/dimensions/40px/40px + + + short description of the plugin, displayed on list, text only + ... + + + short description of the plugin, displayed on detail, Markdown accepted + ... + + + http://link/to/your/page + http://link/to/your/files + http://link/to/your/issues + http://link/to/your/readme + + Your name + + + + 1.0 + 10.0 + http://link/to/your/download/glpi-myplugin-1.0.tar.bz2 + + + + en_GB + ... + + GPL v2+ + + + tag1 + + + tag1 + + + + http://link/to/your/screenshot + http://link/to/your/screenshot + ... + + + +To market this plugin to a wide range of users, you should add a detailed description in several languages and provide screenshots that represent your plugin. + +Finally, submit your XML file on the `dedicated page `_ of the plugins catalog (registration is required). + +.. note:: + + Path to plugin XML file must display the raw XML file itself. For example, the following URL for the `exmple` plugin would be incorrect: + + :: + + https://github.com/pluginsGLPI/example/blob/main/example.xml + + The correct one (use Github UI `raw` button) would be: + + :: + + https://raw.githubusercontent.com/pluginsGLPI/example/refs/heads/main/example.xml + +Teclib' will receive a notification for this submission and after some checks, will activate the publication on the catalog. + +Miscellaneous +------------- + +Querying database +^^^^^^^^^^^^^^^^^ + +Rely on :doc:`DBmysqlIterator <../devapi/database/dbiterator>`. It provides an exhaustive ``query builder``. + +.. code-block:: php + :linenos: + + SELECT * FROM `glpi_computers` + $iterator = $DB->request(['FROM' => 'glpi_computers']); + foreach ($ierator as $row) { + //... work on each row ... + } + + $DB->request([ + 'FROM' => ['glpi_computers', 'glpi_computerdisks'], + 'LEFT JOIN' => [ + 'glpi_computerdisks' => [ + 'ON' => [ + 'glpi_computers' => 'id', + 'glpi_computerdisks' => 'computer_id' + ] + ] + ] + ]); + +Dashboards +^^^^^^^^^^ + +Since GLPI 9.5, dashboards are available from: + +* Central page +* Assets menu +* Assistance menu +* Ticket search results (mini dashboard) + +This feature is split into several concepts - sub classes: + +* a placement grid (``Glpi\Dashboard\Grid``) +* a widget collection (``Glpi\Dashboard\Widget``) to graphically display data +* a data provider collection (``Glpi\Dashboard\Provider``) that queries the database +* rights (``Glpi\Dashboard\Right``) on each dashboard +* filters (``Glpi\Dashboard\Filter``) that can be displayed in a dashboard header and impacting providers. + +With these classes, we can build a dashboard that will display cards on its grid. +A card is a combination of a widget, a data provider, a place on grid and various options (like a background colour for example). + +Completing existing concepts +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +From your plugin, you can complete these concepts with your own data and code. + +**🗋 setup.php** + +.. code-block:: php + :linenos: + + 'getTypes', + ]; + + // add new cards to the dashboard + $PLUGIN_HOOKS[Hooks::DASHBOARD_CARDS]['myplugin'] = [ + Dashboard::class => 'getCards', + ]; + } + +We will create a dedicated class for our dashboards: + +**🗋 src/Dashboard.php** + +.. code-block:: php + :linenos: + + [ + 'label' => __("Plugin Example", 'myplugin'), + 'function' => __class__ . "::cardWidget", + 'image' => "https://via.placeholder.com/100x86?text=example", + ], + 'example_static' => [ + 'label' => __("Plugin Example (static)", 'myplugin'), + 'function' => __class__ . "::cardWidgetWithoutProvider", + 'image' => "https://via.placeholder.com/100x86?text=example+static", + ], + ]; + } + + static function getCards($cards = []) + { + if (is_null($cards)) { + $cards = []; + } + $new_cards = [ + 'plugin_example_card' => [ + 'widgettype' => ["example"], + 'label' => __("Plugin Example card"), + 'provider' => "PluginExampleExample::cardDataProvider", + ], + 'plugin_example_card_without_provider' => [ + 'widgettype' => ["example_static"], + 'label' => __("Plugin Example card without provider"), + ], + 'plugin_example_card_with_core_widget' => [ + 'widgettype' => ["bigNumber"], + 'label' => __("Plugin Example card with core provider"), + 'provider' => "PluginExampleExample::cardBigNumberProvider", + ], + ]; + + return array_merge($cards, $new_cards); + } + + static function cardWidget(array $params = []) + { + $default = [ + 'data' => [], + 'title' => '', + // this property is "pretty" mandatory, + // as it contains the colors selected when adding widget on the grid send + // without it, your card will be transparent + 'color' => '', + ]; + $p = array_merge($default, $params); + + // you need to encapsulate your html in div.card to benefit core style + $html = "
"; + $html.= "

{$p['title']}

"; + $html.= "
    "; + foreach ($p['data'] as $line) { + $html.= "
  • $line
  • "; + } + $html.= "
"; + $html.= "
"; + + return $html; + } + + static function cardWidgetWithoutProvider(array $params = []) + { + $default = [ + // this property is "pretty" mandatory, + // as it contains the colors selected when adding widget on the grid send + // without it, your card will be transparent + 'color' => '', + ]; + $p = array_merge($default, $params); + + // you need to encapsulate your html in div.card to benefit core style + $html = "
+ static html (+optional javascript) as card is not matched with a data provider + +
"; + + return $html; + } + + static function cardBigNumberProvider(array $params = []) + { + $default_params = [ + 'label' => null, + 'icon' => null, + ]; + $params = array_merge($default_params, $params); + + return [ + 'number' => rand(), + 'url' => "https://www.linux.org/", + 'label' => "plugin example - some text", + 'icon' => "fab fa-linux", // font awesome icon + ]; + } + } + +A few explanations on those methods: + +* ``getTypes()``: define available widgets for cards and methods to call for display. +* ``getCards()``: define available cards for dashboards (when added to the grid). As previously explained, each is defined from a label, widget and optional data provider (from core or your plugin) combination +* ``cardWidget()``: use provided parameters to display HTML. You are free to delegate display to a Twig template, and use your favourite JavaScript library. +* ``cardWidgetWithoutProvider()``: almost the same as the ``cardWidget()``, but does not use parameters and just returns a static HTML. +* ``cardBigNumberProvider()``: provider and expected return example when grid will display card. + +Display your own dashboard +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +GLPI dashboards system is modular and you can use it in your own displays. + +.. code-block:: php + :linenos: + + show(); + +By adding a context (``myplugin``), you can filter dashboards available in the dropdown list at the top right of the grid. You will not see GLPI core ones (central, assistance, etc.). + +Translating your plugins +^^^^^^^^^^^^^^^^^^^^^^^^ + +In many places in current document, code exmaples takes care of using `gettext`_ GLPI notations to display strings to users. +Even if your plugin will be private, it is a good practice to keep this `gettext`_ usage. + +See :doc:`developper guide translation documentation <../devapi/translations>` for more explanations and list of PHP functions that can be used. + +* On your local instance, you can use software like `poedit `_ to manage your translations. +* You can also rely on online services like `Transifex `_ or `Weblate `_ (both are free for open source projects). + +If you have used the `Empty`_ plugin skeleton, you will benefit from command line tools to manage your locales: + +.. code-block:: shell + + # extract strings to translate from your source code + # and put them in the locales/myplugin.pot file + vendor/bin/extract-locales + +.. warning:: + + ℹ️ It is possible your translations are not updated after compiling MO files, a restart of your PHP (or web server, depending on your configuration) may be required. + +REST API +-------- + +Since GLPI (since 9.1 release) has an external API in REST format. An XMLRPC format is also still available, but is deprecated. + +.. image:: /_static/images/API.png + :alt: API configuration + +Configuration +^^^^^^^^^^^^^ + +For security reasons, API is disabled bu default. +From the ``Setup > General, API tab`` menu, you can enable it. + +It's available from your instance at: + +* ``http://path/to/glpi/apirest.php`` +* ``http://path/to/glpi/apixmlrpc.php`` + +The first link includes an integrated documentation when you access it from a simple browser (a link is provided as soon as the API is active). + +For the rest of the configuration: + +* login allows to use ``login`` / ``password`` as well as web interface +* token connection use the token displayed in user preferences + + .. image:: /_static/images/api_external_token.png + :alt: external token + +* API clients allow to limit API access from some IP addresses and log if necessary. A client allowing access from any IP is provided by default. + +---- + +You can use the `API usage bootstrap `_. +This one is written in PHP and relies on `Guzzle `_ library to handle HTTP requests. + +By default, it does a connection with login details defined in the ``config.inc.php`` file (that you must create by copying the ``config.inc.example`` file). + +.. warning:: + + ⚠️ Make sure the script is working as expected before continuing. + +API usage +^^^^^^^^^ + +To learn this part, with the help of integrated documentation (or `latest stable GLPI API documentation on github `_), we will do several exercises: + +.. note:: + + 📝 **Exercise**: Test a new connection using GLPI user external token + +.. note:: + + 📝 **Exercise**: Close the session at the end of your script. + +.. note:: + + 📝 **Exercise**: Simulate computer life cycle: + + * add a computer and some volumes (``Item_Disk``), + * edit several fields, + * add commercial and administrative information (``Infocom``), + * display its detail in a PHP page, + * put it in the trashbin, + * and then remove it completely. + +.. note:: + + 📝 **Exercise**: Retrieve computers list and display them an HTML array. The `endpoint` to use us "Search items". + If you want to display columns labels, you will have to use the "List searchOptions" `endpoint`. + +---- + +.. _Empty: https://github.com/pluginsGLPI/empty +.. _Composer: https://getcomposer.org/download/ +.. _Npm: https://www.npmjs.com/ +.. _CommonDBTM: https://github.com/glpi-project/glpi/blob/10.0.15/src/CommonDBTM.php +.. _Computer: https://github.com/glpi-project/glpi/blob/10.0.15/src/Computer.php +.. _Html: https://github.com/glpi-project/glpi/blob/10.0.15/src/Html.php +.. _Migration: https://github.com/glpi-project/glpi/blob/10.0.15/src/Migration.php +.. _Notepad: https://github.com/glpi-project/glpi/blob/10.0.15/src/Notepad.php +.. _Log: https://github.com/glpi-project/glpi/blob/10.0.15/src/Log.php +.. _Profile: https://github.com/glpi-project/glpi/blob/10.0.15/src/Profile.php +.. _Session: https://github.com/glpi-project/glpi/blob/10.0.15/src/Session.php +.. _gettext: https://www.gnu.org/software/gettext/ +.. _Metabase: http://www.metabase.com/ +.. _informatique décisionnelle: https://fr.wikipedia.org/wiki/Informatique_d%C3%A9cisionnelle From 0a14d9a916fbf2d73d921f93d87d14ebb48ea29f Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Sat, 17 May 2025 11:54:08 -0400 Subject: [PATCH 26/26] add new hooks documentation --- source/plugins/hooks.rst | 1514 ++++++++++++++++++++++++++------------ 1 file changed, 1032 insertions(+), 482 deletions(-) diff --git a/source/plugins/hooks.rst b/source/plugins/hooks.rst index c3db740..6c4f909 100644 --- a/source/plugins/hooks.rst +++ b/source/plugins/hooks.rst @@ -1,713 +1,1263 @@ Hooks ----- -GLPI provides a certain amount of "hooks". Their goal is for plugins (mainly) to work on certain places of the framework; like when an item has been added, updated, deleted, ... +GLPI provides over 130 "hooks". Their goal is for plugins to be able to expand functionality of GLPI and react to specific events; like when an item has been added, updated, deleted, etc. +The hooks are primarily interacted with through the "$PLUGIN_HOOKS" global array from the plugin's ``init`` function. +Some hooks though are automatically called if a specific function exists in the plugin's ``hook.php`` file. -This page describes current existing hooks; but not the way they must be implemented from plugins. Please refer to the plugins development documentation. +This page describes the different currently existing hooks. For more information about plugin development, please refer to the plugins development documentation. -.. _standards_hooks: +Hooks +##### +ADD_CSS +******* + +Add CSS file in the head of all non-anonymous pages. + + + +ADD_JAVASCRIPT +************** + +Add classic JavaScript file in the head of all non-anonymous pages. + + + +ADD_JAVASCRIPT_MODULE +********************* + +Add ESM JavaScript module in the head of all non-anonymous pages. + + +ADD_HEADER_TAG +************** + +Add a header tag in the head of all non-anonymous pages. + + +JAVASCRIPT +********** + +Register one or more on-demand JavaScript files. +On-demand JS files are loaded based on the `$CFG_GLPI['javascript']` array. +Example: `$PLUGIN_HOOKS[Hooks::JAVASCRIPT]['your_js_name'] = ['path/to/your/file.js'];` + + +ADD_CSS_ANONYMOUS_PAGE +********************** + +Add CSS file in the head of all anonymous pages. + + +ADD_JAVASCRIPT_ANONYMOUS_PAGE +***************************** + +Add classic JavaScript file in the head of all anonymous pages. + + +ADD_JAVASCRIPT_MODULE_ANONYMOUS_PAGE +************************************ + +Add ESM JavaScript module in the head of all anonymous pages. + + +ADD_HEADER_TAG_ANONYMOUS_PAGE +***************************** + +Add a header tag in the head of all anonymous pages. + + +CHANGE_ENTITY +************* + +Register a function to be called when the entity is changed. + + +CHANGE_PROFILE +************** + +Register a function to be called when the profile is changed. + + +DISPLAY_LOGIN +************* + +Register a function to output some content on the login page. + + +DISPLAY_CENTRAL +*************** + +Register a function to output some content on the standard (central) or simplified interface (helpdesk) home page. +This hook is called inside a table element. + + +DISPLAY_NETPORT_LIST_BEFORE +*************************** + +Register a function to output some content before the network port list. + + +INIT_SESSION +************ + +Register a function to be called when the session is initialized. + + +POST_INIT +********* + +Register a function to be called after all plugins are initialized. + + +CONFIG_PAGE +*********** + +Register a URL relative to the plugin's root URL for the plugin's config page. + + +USE_MASSIVE_ACTION +****************** + +Set to true if the plugin wants to use the Hooks::AUTO_MASSIVE_ACTIONS hook. +Example: $PLUGIN_HOOKS[Hooks::USE_MASSIVE_ACTION]['myplugin'] = true; + + +ASSIGN_TO_TICKET +**************** + +Set to true if the plugin wants to use the Hooks::AUTO_ASSIGN_TO_TICKET hook. +Example: $PLUGIN_HOOKS[Hooks::ASSIGN_TO_TICKET]['myplugin'] = true; + + +IMPORT_ITEM +*********** + +Set to true if the plugin can import items. Adds the plugin as a source criteria for 'Rules for assigning an item to an entity' + + +RULE_MATCHED +************ + +Register a function to be called when the rules engine matches a rule. +The function is called with an array containing several properties including: +* 'sub_type' => The subtype of the rule (Example: RuleTicket) +* 'ruleid' => The ID of the rule +* 'input' => The input data sent to the rule engine +* 'output' => The current output data +The function is not expected to return anything and the data provided to it cannot be modified. + + +VCARD_DATA +********** + +Register a function to be called when a vCard is generated. +The function is called with an array containing several properties including: +* 'item' => The item for which the vCard is generated +* 'data' => The vCard data +The function is expected to modify the given array as needed and return it. + + +POST_PLUGIN_DISABLE +******************* + +Register a function to be called when the plugin is disabled. +The function is called with the plugin name as a parameter. + + +POST_PLUGIN_CLEAN +***************** + +Register a function to be called when the plugin is cleaned from the database. +The function is called with the plugin name as a parameter. + + +POST_PLUGIN_INSTALL +******************* + +Register a function to be called when the plugin is installed. +The function is called with the plugin name as a parameter. + + +POST_PLUGIN_UNINSTALL +********************* + +Register a function to be called when the plugin is uninstalled. +The function is called with the plugin name as a parameter. + + +POST_PLUGIN_ENABLE +****************** + +Register a function to be called when the plugin is enabled. +The function is called with the plugin name as a parameter. + + +DISPLAY_LOCKED_FIELDS +********************* + +Register a function to be called to show locked fields managed by the plugin. +The function is called with an array containing several properties including: +* 'item' => The item for which the locked fields are shown +* 'header' => Always false. //TODO WHY!? + + +PRE_KANBAN_CONTENT +****************** + +Register a function to define content to show before the main content of a Kanban card. +This function is called with an array containing several properties including: +* 'itemtype' => The type of the item represented by the Kanban card +* 'items_id' => The ID of the item represented by the Kanban card +The function is expected to return HTML content. + + +POST_KANBAN_CONTENT +******************* + +Register a function to define content to show after the main content of a Kanban card. +This function is called with an array containing several properties including: +* 'itemtype' => The type of the item represented by the Kanban card +* 'items_id' => The ID of the item represented by the Kanban card +The function is expected to return HTML content. + + +KANBAN_ITEM_METADATA +******************** + +Register a function to redefine metadata for a Kanban card. +This function is called with an array containing several properties including: +* 'itemtype' => The type of the item represented by the Kanban card +* 'items_id' => The ID of the item represented by the Kanban card +* 'metadata' => The current metadata for the Kanban card +The function is expected to modify the given array as needed and return it. + + +KANBAN_FILTERS +************** + +Define extra Kanban filters by itemtype. +Example: +``` +$PLUGIN_HOOKS[Hooks::KANBAN_FILTERS]['myplugin'] = [ + 'Ticket' => [ + 'new_metadata_property' => [ + 'description' => 'My new property' + 'supported_prefixes' => ['!'] + ] + ] +] +``` + + +PRE_KANBAN_PANEL_CONTENT +************************ + +Register a function to display content at the beginning of the item details panel in the Kanban. +The function is called with an array containing several properties including: +* 'itemtype' => The type of the item represented by the Kanban card +* 'items_id' => The ID of the item represented by the Kanban card +The function is expected to return HTML content. + + + +POST_KANBAN_PANEL_CONTENT +************************* + +Register a function to display content at the end of the item details panel in the Kanban. +The function is called with an array containing several properties including: +* 'itemtype' => The type of the item represented by the Kanban card +* 'items_id' => The ID of the item represented by the Kanban card +The function is expected to return HTML content. + + + +PRE_KANBAN_PANEL_MAIN_CONTENT +***************************** + +Register a function to display content at the beginning of the item details panel in the Kanban after the content from Hooks::PRE_KANBAN_PANEL_CONTENT but before the default main content. +The function is called with an array containing several properties including: +* 'itemtype' => The type of the item represented by the Kanban card +* 'items_id' => The ID of the item represented by the Kanban card +The function is expected to return HTML content. + + + +POST_KANBAN_PANEL_MAIN_CONTENT +****************************** + +Register a function to display content at the end of the item details panel in the Kanban after the default main content but before the content from Hooks::POST_KANBAN_PANEL_CONTENT. +The function is called with an array containing several properties including: +* 'itemtype' => The type of the item represented by the Kanban card +* 'items_id' => The ID of the item represented by the Kanban card +The function is expected to return HTML content. + + + +REDEFINE_MENUS +************** + +Register a function to redefine the GLPI menu. +The function is called with the current menu as a parameter. +The function is expected to modify the given array as needed and return it. + + + +RETRIEVE_MORE_DATA_FROM_LDAP +**************************** + +Register a function to get more user field data from LDAP. +The function is called with an array containing the current fields for the user along with: +* '_ldap_result' => The LDAP query result +* '_ldap_conn' => The LDAP connection resource +The function is expected to modify the given array as needed and return it. + + +RETRIEVE_MORE_FIELD_FROM_LDAP +***************************** + +Register a function to get more LDAP -> Field mappings. +The function is called with an array containing the current mappings. +The function is expected to modify the given array as needed and return it. + + + +RESTRICT_LDAP_AUTH +****************** + +Register a function to add additional checks to the LDAP authentication. +The function is called with an array containing several properties including: +* 'dn' => The DN of the user +* login field => Login field value where 'login field' is the name of the login field (usually samaccountname or uid) set in the LDAP config in GLPI. +* sync field => Sync field value where 'sync field' is the name of the sync field (usually objectguid or entryuuid) set in the LDAP config in GLPI + + +UNLOCK_FIELDS +************* + +Register a function to handle unlocking additional fields. +The function is called with the $_POST array containing several properties including: +* 'itemtype' => The type of the item for which the fields are unlocked +* 'id' => The ID of the item for which the fields are unlocked +* itemtype => Array of fields to unlock where 'itemtype' is the name of the item type (usually the same as the itemtype value). +The function is expected to return nothing. + + +UNDISCLOSED_CONFIG_VALUE +************************ + +Register a function to optionally hide a config value in certain locations such as the API. +The function is called with an array containing several properties including: +* 'context' => The context of the config option ('core' for core GLPI configs) +* 'name' => The name of the config option +* 'value' => The value of the config option +The function is expected to modify the given array as needed (typically unsetting the value if it should be hidden) and return it. + + +FILTER_ACTORS +************* + +Register a function to modify the actor results in the right panel of ITIL objects. +The function is called with an array containing several properties including: +* 'actors' => The current actor results +* 'params' => The parameters used to retrieve the actors +The function is expected to modify the given array as needed and return it. + + +DEFAULT_DISPLAY_PREFS +********************* + +Register a function to declare what the default display preferences are for an itemtype. +This is not used when no display preferences are set for the itemtype, but rather when hte preferences are being reset. +Therefore, defaults should be set during the plugin installation and the result of the function should be the same as the default values set in the plugin installation. +Core GLPI itemtypes with display preferences set in `install/empty_data.php` will never use this hook. +The function is called with an array containing several properties including: +* 'itemtype' => The type of the item for which the display preferences are set +* 'prefs' => The current defaults (usually empty unless also modified by another plugin) +The function is expected to modify the given array as needed and return it. + + +USE_RULES +********* + +Must be set to true for some other hooks to function including: +* Hooks::AUTO_GET_RULE_CRITERIA +* Hooks::AUTO_GET_RULE_ACTIONS +* Hooks::AUTO_RULE_COLLECTION_PREPARE_INPUT_DATA_FOR_PROCESS +* Hooks::AUTO_PRE_PROCESS_RULE_COLLECTION_PREVIEW_RESULTS +* Hooks::AUTO_RULEIMPORTASSET_GET_SQL_RESTRICTION +* Hooks::AUTO_RULEIMPORTASSET_ADD_GLOBAL_CRITERIA + + +ADD_RECIPIENT_TO_TARGET +*********************** + +Register a function to be called when a notification recipient is to be added. +The function is called with the NotificationTarget object as a parameter. +The function is expected to return nothing. +The added notification target information can be found in the `recipient_data` property of the object. Modifying this information will have no effect. +The current list of all added notification targets can be found in the `target` property of the object. +If you wish to remove/modify targets, you must do so in the `target` property. + + +AUTOINVENTORY_INFORMATION +************************* + +Register a function to be called to display some automatic inventory information. +The function is called with the item as a parameter. +The function is expected to return nothing, but the information may be output directly. +The function is only called for items that have the `is_dynamic` field, and it is set to 1. + + +INFOCOM +******* + +Register a function to be called to display extra Infocom form fields/information. +The function is called with the item as a parameter. +The function is expected to return nothing, but the information may be output directly. + + +ITEM_ACTION_TARGETS +******************* + +Register a function to handle adding a plugin-specific notification target. +The function is called with the NotificationTarget object as a parameter. +The function is expected to return nothing. +The notification target data can be found in the `data` property of the object. + + + +ITEM_ADD_TARGETS +**************** + +Register a function to handle adding new possible recipients for notification targets. +The function is called with the NotificationTarget object as a parameter. +The function is expected to return nothing. + + + +ITEM_EMPTY +********** + +Register a function to handle the 'item_empty' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +The hook is called at the very end of the process of initializing an empty item. + + + +PRE_ITEM_ADD +************ + +Register a function to handle the 'pre_item_add' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +This hook is called at the very beginning of the add process, before the input has been modified. +The input can be found in the `input` property of the item. Setting the `input` property to false will cancel the add process. + + + +POST_PREPAREADD +*************** + +Register a function to handle the 'post_prepareadd' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +This hook is called after the input has been modified, but before the item is added to the database. +The input can be found in the `input` property of the item. Setting the `input` property to false will cancel the add process. + + + +ITEM_ADD +******** + +Register a function to handle the 'item_add' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +This hook is called at the very end of the add process, after the item has been added to the database. + + +PRE_ITEM_UPDATE +*************** + +Register a function to handle the 'pre_item_update' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +This hook is called at the very beginning of the update process, before the input has been modified. +The input can be found in the `input` property of the item. Setting the `input` property to false will cancel the update process. + + + +ITEM_UPDATE +*********** + +Register a function to handle the 'item_update' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +This hook is called at the very end of the update process, after the item has been updated in the database. +The input can be found in the `input` property of the item while the updated field names can be found in the `updates` property. +The old values of changed field can be found in the `oldvalues` property. + + +PRE_ITEM_DELETE +*************** + +Register a function to handle the 'pre_item_delete' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +This hook is called at the very beginning of the soft-deletion process. +The input can be found in the `input` property of the item. Setting the `input` property to false will cancel the deletion process. + + +ITEM_DELETE +*********** + +Register a function to handle the 'item_delete' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +This hook is called at the very end of the soft-deletion process, after the item has been soft-deleted from the database (`is_deleted` set to 1). + + +PRE_ITEM_PURGE +************** + +Register a function to handle the 'pre_item_purge' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +This hook is called at the very beginning of the purge process. +The input can be found in the `input` property of the item. Setting the `input` property to false will cancel the purge process. + + +ITEM_PURGE +********** + +Register a function to handle the 'item_purge' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +This hook is called at the very end of the purge process, after the item has been purged from the database. + + +PRE_ITEM_RESTORE +**************** + +Register a function to handle the 'pre_item_restore' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +This hook is called at the very beginning of the restore process. +The input can be found in the `input` property of the item. Setting the `input` property to false will cancel the restore process. + + +ITEM_RESTORE +************ + +Register a function to handle the 'item_restore' lifecycle event for an item. +The function is called with the item as a parameter. +The function is expected to return nothing. +This hook is called at the very end of the restore process, after the item has been restored in the database (`is_deleted` set to 0). + + +ITEM_GET_DATA +************* + +Register a function to handle adding data for a notification target. +The function is called with the NotificationTarget object as a parameter. +The function is expected to return nothing. +The notification target data can be found in the `data` property of the object. + + + +ITEM_GET_EVENTS +*************** + +Register a function to handle adding events for a notification target. +The function is called with the NotificationTarget object as a parameter. +The function is expected to return nothing. +The notification target events can be found in the `events` property of the object. -Standards Hooks -^^^^^^^^^^^^^^^ -Usage -+++++ -Aside from their goals or when/where they're called; you will see three types of different hooks. Some will receive an item as parameter, others an array of parameters, and some won't receive anything. Basically, the way they're declared into your plugin, and the way you'll handle that will differ. +SHOW_ITEM_STATS +*************** -All hooks called are defined in the ``setup.php`` file of your plugin; into the ``$PLUGIN_HOOKS`` array. The first key is the hook name, the second your plugin name; values can be just text (to call a function declared in the ``hook.php`` file), or an array (to call a static method from an object): +Register a function to show additional statistics in the Statistics tab of Tickets, Changes and Problems. +The function is called with the item as a parameter. +The function is expected to return nothing, but the information may be output directly. -.. code-block:: php - The item for which the fields are shown +* 'options' => An array of form parameters -You will also have to declare the function you want to call in you ``hook.php`` file: -.. code-block:: php - The item for which the fields are shown + * 'options' => An array of form parameters -.. _hook_item_parameter: -With item as parameter -~~~~~~~~~~~~~~~~~~~~~~ -Those hooks will send you an item instance as parameter; you'll have to attach them to the itemtypes you want to apply on. Let's say you want to call the ``pre_item_update`` hook for `Computer` and `Phone` item types, in your ``setup.php`` you'll add something like: +ITEM_TRANSFER +************* -.. code-block:: php +Register a function to be called after an item is transferred to another entity. +The function is called with an array containing several properties including: +* 'type' => The type of the item being transferred. +* 'id' => The original ID of the item being transferred. +* 'newID' => The new ID of the item being transferred. If the item was cloned into the new entity, this ID will differ from the original ID. +* 'entities_id' => The ID of the destination entity. +The function is expected to return nothing. - 'myplugin_updateitem_called', - 'Phone' => 'myplugin_updateitem_called' - ]; -You will also have to declare the function you want to call in you ``hook.php`` file: +PRE_SHOW_ITEM +************* -.. code-block:: php +Register a function to be called before showing an item in the timeline of a Ticket, Change or Problem. +The function is called with the following parameters: +* 'item' => The item being shown in the timeline +* 'options' => An array containing the following properties: + * 'parent' => The Ticket, Change or Problem + * 'rand' => A random number that may be used for unique element IDs within the timeline item HTML +The function is expected to return nothing, but the information may be output directly. - ` expect they will send you an array of parameters instead of only an item instance. The array will contain two entries: ``item`` and ``options``, the first one is the item instance, the second options that have been passed: +Register a function to be called after showing an item in the timeline of a Ticket, Change or Problem. +The function is called with the following parameters: +* 'item' => The item being shown in the timeline +* 'options' => An array containing the following properties: + * 'parent' => The Ticket, Change or Problem + * 'rand' => A random number that may be used for unique element IDs within the timeline item HTML +The function is expected to return nothing, but the information may be output directly. -.. code-block:: php - Computer Object - // (...) - // - // [options] => Array - // ( - // [_target] => /front/computer.form.php - // [id] => 1 - // [withtemplate] => - // [tabnum] => 1 - // [itemtype] => Computer - // ) - //) - } -The hooks that are called with an array of parameters are: ``post_item_form``, ``pre_item_form``, ``pre_show_item``, ``post_show_item``, ``pre_show_tab``, ``post_show_tab``, ``pre_itil_info_section``, ``post_itil_info_section``, ``item_transfer``. +PRE_ITEM_FORM +************* -Some hooks will receive a specific array as parameter, they will be detailled below. +Register a function to show additional fields at the top of an item form. +The function is called with the following parameters: +* 'item' => The item for which the fields are shown +* 'options' => An array of form parameters +The function is expected to return nothing, but the information may be output directly. -Unclassified -++++++++++++ -Hooks that cannot be classified in above categories :) +POST_ITEM_FORM +************** -``secured_fields`` - .. versionadded:: 9.4.6 +Register a function to show additional fields at the bottom of an item form. +The function is called with the following parameters: +* 'item' => The item for which the fields are shown +* 'options' => An array of form parameters +The function is expected to return nothing, but the information may be output directly. - An array of fields names (with table like ``glpi_mytable.myfield``) that are stored using GLPI crypting methods. - This allows plugins to add some fields to the ``glpi:security:changekey`` command. - .. warning:: +PRE_SHOW_TAB +************ - Plugins have to ensure crypt migration on their side is OK; and once using it, they **must** properly declare fields. +Register a function to show additional content before the main content in a tab. +This function is not called for the main tab of a form. +The function is called with the following parameters: +* 'item' => The item for which the tab is shown +* 'options' => An array containing the following properties: + * 'itemtype' => The type of the item being shown in the tab + * 'tabnum' => The number of the tab being shown for the itemtype +The function is expected to return HTML content or an empty string. - All fields that would use the key file without being listed would be unreadable after key has been changed (and stored data would stay potentially unsecure). -``secured_configs`` - .. versionadded:: 9.4.6 +POST_SHOW_TAB +************* - An array of configuration entries that are stored using GLPI crypting methods. - This allows plugins to add some entries to the ``glpi:security:changekey`` command. +Register a function to show additional content after the main content in a tab. +This function is not called for the main tab of a form. +The function is called with the following parameters: +* 'item' => The item for which the tab is shown +* 'options' => An array containing the following properties: + * 'itemtype' => The type of the item being shown in the tab + * 'tabnum' => The number of the tab being shown for the itemtype +The function is expected to return HTML content or an empty string. - .. warning:: - Plugins have to ensure crypt migration on their side is OK; and once using it, they **must** properly declare fields. +PRE_ITEM_LIST +************* - All configuration entries that would use the key file without being listed would be unreadable after key has been changed (and stored data would stay potentially unsecure). +Register a function to show additional content before the search result list for an itemtype. +The function is called with the following parameters: +* 'itemtype' => The type of the item being shown in the list +* 'options' => Unused. Always an empty array. +The function is expected to return nothing, but the information may be output directly. -``add_javascript`` - Add javascript in **all** pages headers - .. versionadded:: 9.2 - Minified javascript files are checked automatically. You will just have to provide a minified file along with the original to get it used! +POST_ITEM_LIST +************** - The name of the minified ``plugin.js`` file must be ``plugin.min.js`` +Register a function to show additional content after the search result list for an itemtype. +The function is called with the following parameters: +* 'itemtype' => The type of the item being shown in the list +* 'options' => Unused. Always an empty array. +The function is expected to return nothing, but the information may be output directly. -``add_css`` - Add CSS stylesheet on **all** pages headers - .. versionadded:: 9.2 +TIMELINE_ACTIONS +**************** - Minified CSS files are checked automatically. You will just have to provide a minified file along with the original to get it used! +Register a function to show action buttons in the footer of a Ticket, Change or Problem timeline. +This is how timeline actions were displayed before version 10.0, but now using the Hooks::TIMELINE_ANSWER_ACTIONS is the preferred way. +The function is called with the following parameters: +* 'item' => The item for which the actions are shown +* 'rand' => A random number that may be used for unique element IDs within the HTML +The function is expected to return nothing, but the information may be output directly. - The name of the minified ``plugin.css`` file must be ``plugin.min.css`` -``add_javascript_anonymous_page`` - Add javascript in **all anonymous** pages headers +TIMELINE_ANSWER_ACTIONS +*********************** - .. versionadded:: 10.0.18 +Register a function to add new itemtypes to the answer/action split dropdown, and be made available to show in a Ticket, Change or Problem timeline. +The function is called with the following parameters: +* 'item' => The item for which the actions are shown +The function is expected to return an array of options to be added to the dropdown. +Each option should have a unique key and be an array with the following properties: +* 'type' => The type of the item to be used for the action. In some cases, this is a parent/abstract class such as ITILTask. This is used as a CSS class on the main timeline item element. +* 'class' => The actual type of the item to be used for the action such as TicketTask. +* 'icon' => The icon to be used for the action. +* 'label' => The label to be used for the action. +* 'short_label' => The short label to be used for the action. +* 'template' => The Twig template to use when showing related items in the timeline. +* 'item' => An instance of the related itemtype. +* 'hide_in_menu' => If true, the option is not available in the dropdown menu but the related items may still be shown in the timeline. - Minified javascript files are checked automatically. You will just have to provide a minified file along with the original to get it used! - The name of the minified ``plugin_anonymous.js`` file must be ``plugin_anonymous.min.js`` +SHOW_IN_TIMELINE +**************** -``add_javascript_module_anonymous_page`` - Add javascript module in **all anonymous** pages headers +.. warning::\nDeprecated: 11.0.0 Use `TIMELINE_ITEMS` instead. The usage of both hooks is the same.\n - .. versionadded:: 10.0.18 - Minified javascript files are checked automatically. You will just have to provide a minified file along with the original to get it used! +TIMELINE_ITEMS +************** - The name of the minified ``mymodule_anonymous.js`` file must be ``mymodule_anonymous.min.js`` +Register a function to add new items to the timeline of a Ticket, Change or Problem. +The function is called with the following parameters: +* 'item' => The item for which the actions are shown. +* 'timeline' => The array of items currently shown in the timeline. This is passed by reference. +The function is expected to modify the timeline array as needed. +The timeline item array contains arrays where the keys are typically "${itemtype}_${items_id}" and the values are arrays with the following properties: +* 'type' => The type of the item being shown in the timeline. This should match the 'class' property used in Hooks::TIMELINE_ANSWER_ACTIONS. +* 'item' => Array of information to pass to the 'template' used in Hooks::TIMELINE_ANSWER_ACTIONS, and notifications. -``add_css_anonymous_page`` - Add CSS stylesheet on **all anonymous** pages headers +SET_ITEM_IMPACT_ICON +******************** - .. versionadded:: 10.0.18 +Register a function to set the icon used by an item in the impact graph. +The function is called with the following parameters: +* 'itemtype' => The type of the item being shown in the graph +* 'items_id' => The ID of the item being shown in the graph +The function is expected to return a URL starting with a '/' relative to the GLPI root directory, or an empty string. - Minified CSS files are checked automatically. You will just have to provide a minified file along with the original to get it used! - The name of the minified ``plugin_anonymous.css`` file must be ``plugin_anonymous.min.css`` +SECURED_FIELDS +************** -``add_header_tag_anonymous_page`` - Add header tags in **all anonymous** pages headers +An array of database columns (example: glpi_mytable.myfield) that are stored using GLPI encrypting methods. +This allows plugin fields to be handled by the `glpi:security:changekey` command. +Added in version 9.4.6 - .. versionadded:: 10.0.18 +SECURED_CONFIGS +*************** -``display_central`` - Displays something on central page +An array of configuration keys that are stored using GLPI encrypting methods. +This allows plugin configuration values to be handled by the `glpi:security:changekey` command. +Added in version 9.4.6 -``display_login`` - Displays something on the login page +PROLOG_RESPONSE +*************** -``status`` - Displays status -``post_init`` - After the framework initialization -``rule_matched`` - After a rule has matched. +NETWORK_DISCOVERY +***************** - This hook will receive a specific array that looks like: - .. code-block:: php - 'an item type', - 'rule_id' => 'tule id', - 'input' => array(), //original input - 'output' => array() //output modified by rule - ]; +NETWORK_INVENTORY +***************** -``redefine_menus`` - Add, edit or remove items from the GLPI menus. - This hook will receive the current GLPI menus definition as an argument and must return the new definition. +INVENTORY_GET_PARAMS +******************** -``init_session`` - At session initialization -``change_entity`` - When entity is changed -``change_profile`` - When profile is changed +PRE_INVENTORY +************* -``pre_kanban_content`` - .. versionadded:: 9.5 - Set or modify the content that shows before the main content in a Kanban card. + You may modify the inventory data which is passed as a parameter (stdClass) and return the modified data. + Returning null will cancel the inventory submission with no specific reason. + Throwing an Exception will cancel the inventory submission with the exception message as the reason. + To avoid unrelated exception messages from being sent to the agent, you must handle all exceptions (except the one you would throw to cancel the inventory) within the hook function. - This hook will receive a specific array that looks like: - .. code-block:: php +POST_INVENTORY +************** - string, //item type that is showing the Kanban - 'items_id' => int, //ID of itemtype showing the Kanban - 'content' => string //current content shown before main content - ]; -``post_kanban_content`` - .. versionadded:: 9.5 + You may view the inventory data which is passed as a parameter (stdClass). + Nothing is expected to be returned. + This hook is only called if the inventory submission was successful. - Set or modify the content that shows after the main content in a Kanban card. - This hook will receive a specific array that looks like: +HANDLE_INVENTORY_TASK +********************* - .. code-block:: php - string, //item type that is showing the Kanban - 'items_id' => int, //ID of itemtype showing the Kanban - 'content' => string //current content shown after main content - ]; -``kanban_filters`` - .. versionadded 10.0 +HANDLE_NETDISCOVERY_TASK +************************ - Add new filter definitions for Kanban by itemtype. - This data is set directly in $PLUGIN_HOOKS like: - .. code-block:: php +HANDLE_NETINVENTORY_TASK +************************ - [ - 'tag' => [ - 'description' => _x('filters', 'If the item has a tag'), - 'supported_prefixes' => ['!'] - ], - 'tagged' => [ - 'description' => _x('filters', 'If the item is tagged'), - 'supported_prefixes' => ['!'] - ] - ], - 'Project' => [ - 'tag' => [ - 'description' => _x('filters', 'If the item has a tag'), - 'supported_prefixes' => ['!'] - ], - 'tagged' => [ - 'description' => _x('filters', 'If the item is tagged'), - 'supported_prefixes' => ['!'] - ] - ]; - ] -``kanban_item_metadata`` - .. versionadded 10.0 - Set or modify the metadata for a Kanban card. This metadata isn't displayed directly but will be used by the filtering system. +HANDLE_ESX_TASK +*************** - This hook will receive a specific array that looks like: - .. code-block:: php - string, //item type that is showing the Kanban - 'items_id' => int, //ID of itemtype showing the Kanban - 'metadata' => array //current metadata array - ]; -``vcard_data`` - .. versionadded 9.5 +HANDLE_COLLECT_TASK +******************* - Add or modify data in vCards such as IM contact information - .. code-block:: php - CommonDBTM, //The item the vCard is for such as a User or Contact - 'data' => array, //The current vCard data for the item - ]; +HANDLE_DEPLOY_TASK +****************** -``filter_actors`` - .. versionadded 9.5 - Add or modify data actor fields provided in the right panel of ITIL objects +HANDLE_WAKEONLAN_TASK +********************* - .. code-block:: php - array, // actors array send to select2 field - 'params' => array, // actor field param - ]; -``helpdesk_menu_entry`` - Add a link to the menu for users with the simplified interface +HANDLE_REMOTEINV_TASK +********************* - .. code-block:: php - The label to be used for the action. +* 'render_callback' => Callable used to display the configuration field. The callable will be called with the inventory configuration values array. +* 'action_callback' => Callable used to perform the action. The callable will be called with the following parameters: + * 'agent' => The agent to be cleaned + * 'config' => The inventory configuration values array + * 'item' => The asset that the agent is for - Array of item types to be added +* 'icon' => The icon for the top-level menu item which is expected to be a Tabler icon CSS class - 'ExampleTab', - 'display_callable' => 'ExampleClass::displayDebugTab' - ] - ]; -``post_plugin_install`` - Called after a plugin is installed +HELPDESK_MENU_ENTRY +******************* -``post_plugin_enable`` - Called after a plugin is enabled +Add a menu item in the simplified interface. +The hook is expected to be a URL relative to the plugin's directory. -``post_plugin_disable`` - Called after a plugin is disabled -``post_plugin_uninstall`` - Called after a plugin is uninstalled +HELPDESK_MENU_ENTRY_ICON +************************ -``post_plugin_clean`` - Called after a plugin is cleaned (removed from the database after the folder is deleted) +Add an icon for the menu item added with the Hooks::HELPDESK_MENU_ENTRY hook. +The hook is expected to be a Tabler icon CSS class. -.. _business_related_hooks: -Items business related -++++++++++++++++++++++ +DASHBOARD_CARDS +*************** -Hooks that can do some busines stuff on items. +Register a function to add new dashboard cards. +The function is called with no parameters. +The function is expected to return an array of dashboard cards. +Each key in the returned array should be a unique identifier for the card. +The value should be an array with the following properties (but not limited to): +* 'widgettype' => Array of widget types this card can use (pie, bar, line, etc) +* 'label' => The label to be used for the card +* 'group' => Group string to be used to organize the card in dropdowns +* 'filters' => An optional array of filters that can apply to this card -``item_empty`` - When a new (empty) item has been created. Allow to change / add fields. -``post_prepareadd`` - Before an item has been added, after ``prepareInputForAdd()`` has been run, so after rule engine has ben run, allow to edit ``input`` property, setting it to false will stop the process. +DASHBOARD_FILTERS +***************** -``pre_item_add`` - Before an item has been added, allow to edit ``input`` property, setting it to false will stop the process. +Add new dashboard filters. +The hook is expected to be an array of classes which extend Glpi\Dashboard\Filters\AbstractFilter. -``item_add`` - After adding an item, ``fields`` property can be used. -``pre_item_update`` - Before an item is updated, allow to edit ``input`` property, setting it to false will stop the process. +DASHBOARD_PALETTES +****************** -``item_update`` - While updating an item, ``fields`` and ``updates`` properties can be used. +Add new dashboard color palettes. +The hook is expected to be an array where the keys are unique identifiers and the values are arrays of #rrggbb color strings. -``pre_item_purge`` - Before an item is purged, allow to edit ``input`` property, setting it to false will stop the process. -``item_purge`` - After an item is purged (not pushed to trash, see ``item_delete``). The ``fields`` property still available. +DASHBOARD_TYPES +*************** -``pre_item_restore`` - Before an item is restored from trash. +Register a function to add new dashboard widget types. +The function is called with no parameters. +The function is expected to return an array where the keys are unique identifiers and the values are arrays with the following properties: +* 'label' => The label to be used for the widget type +* 'function' => A callable to be used to display the widget +* 'image' => The image to be used for the widget +* 'limit' => Indicate if the amount of data shown by the widget can be limited +* 'width' => The default width of cards using this widget +* 'height' => The default height of cards using this widget -``item_restore`` - After an item is restored from trash. -``pre_item_delete`` - Before an item is deleted (moved to trash), allow to edit ``input`` property, setting it to false will stop the process. +REDEFINE_API_SCHEMAS +******************** -``item_delete`` - After an item is moved to tash. +The hook function to call to redefine schemas. +Each time a controller's schemas are retrieved, the hook is called with a $data parameter. +The $data parameter will contain the Controller class name in the 'controller' key and an array of schemas in the 'schemas' key. +The function should return the modified $data array. +The controller value should not be changed as it would result in undefined behavior. -``autoinventory_information`` - After an automated inventory has occured -``item_transfer`` - When an item is transfered from an entity to another +API_CONTROLLERS +*************** -``item_can`` - .. versionadded:: 9.2 +This hook should provide an array of the plugin's API controller class names. - Allow to restrict user rights (can't grant more right). - If ``right`` property is set (called during CommonDBTM::can) changing it allow to - deny evaluated access. Else (called from Search::addDefaultWhere) ``add_where`` - property can be set to filter search results. -``add_plugin_where`` - .. versionadded:: 9.2 +API_MIDDLEWARE +************** - Permit to filter search results. +This hook should provide an array of arrays containing a 'middlware' value that is the class name. +The middleware classes should extend HL_API\Middleware\AbstractMiddleware and +implement either {@link HL_API\Middleware\RequestMiddlewareInterface{ or HL_API\Middleware\ResponseMiddlewareInterface. +The arrays may also contain values for 'priority' and 'condition' where priority is an integer (higher is more important) and condition is a callable. +If a condition is provided, that callable will be called with the current controller as a parameter, and it must return true for the middleware to be used, or false to not be. -.. _display_related_hooks: -Items display related -+++++++++++++++++++++ +STATS +***** -Hooks that permits to add display on items. +Add new statistics reports. +The hook is expected to be an array where the keys are URLs relative to the plugin's directory and the values are the report names. -``pre_itil_info_section`` - .. versionadded:: 11 - Before displaying ITIL object sections (Ticket, Change, Problem) Waits for a ``
``. +MAIL_SERVER_PROTOCOLS +********************* +Register a function to add new email server protocols. +The function is called with no parameters. +The function is expected to return an array where the keys are the protocol name and the values are arrays with the following properties: +* 'label' => The label to be used for the protocol. +* 'protocol' => The name of the class to be used for the protocol. The class should use the `Laminas\Mail\Protocol\ProtocolTrait` trait. +* 'storage' => The name of the class to be used for the protocol storage. The class should extend the `Laminas\Mail\Storage\AbstractStorage` class. -``post_itil_info_section`` - .. versionadded:: 11 - After displaying ITIL object sections (ticket, Change, Problem) Waits for a ``
``. +AUTO_MASSIVE_ACTIONS +******************** +Automatic hook function to add new massive actions. +The function is called with the itemtype as a parameter. +The function is expected to return an array of massive action. +Only called if the plugin also uses the Hooks::USE_MASSIVE_ACTION hook set to true. -``pre_item_form`` - .. versionadded:: 9.1.2 - Before an item is displayed; just after the form header if any; or at the beginnning of the form. Waits for a ````. +AUTO_MASSIVE_ACTIONS_FIELDS_DISPLAY +*********************************** +Automatic hook function to display the form for the "update" massive action for itemtypes or search options related to the plugin. +The function is called with the following parameters: +* 'itemtype' => The type of the item for which the fields are shown +* 'options' => The search option array +The function is expected to return true if the display is handled, or false if the default behavior should be used. -``post_item_form`` - .. versionadded:: 9.1.2 - After an item form has been displayed; just before the dates or the save buttons. Waits for a ````. +AUTO_DYNAMIC_REPORT +******************* -``pre_show_item`` - Before an item is displayed +Automatic hook function called to handle the export display of an itemtype added by the plugin. +The function is called with the $_GET array containing several properties including: +* 'item_type' => The type of the item for which the fields are shown +* 'display_type' => The numeric type of the display. See the constants in the `Search` class. +* 'export_all' => If all pages are being exported or just the current one. +The function is expected to return true if the display is handled, or false if the default behavior should be used. -``post_show_item`` - After an item has been displayed -``pre_show_tab`` - Before a tab is displayed +AUTO_ASSIGN_TO_TICKET +********************* -``post_show_tab`` - After a tab has been displayed +Automatic hook function to add new itemtypes which can be linked to Tickets, Changes or Problems. +The function is called with the current array of plugin itemtypes allowed to be linked. +The function is expected to modify the given array as needed and return it. -``show_item_stats`` - .. versionadded:: 9.2.1 - Add display from statistics tab of a item like ticket +AUTO_GET_DROPDOWN +***************** -``timeline_actions`` - .. versionadded:: 9.4.1 - .. versionchanged:: 10.0.0 The timeline action buttons were moved to the timeline footer. Some previous actions may no longer be compatible with the new timeline and will need to be adjusted. +Automatic hook function called to get additional dropdown classes which would be displayed in Setup > Dropdowns. +The function is called with no parameters. +The function is expected to return an array where the class names are in the keys or null. For the array values, anything can be used, but typically it is just `null`. - Display new actions in the ITIL object's timeline -``timeline_answer_actions`` - .. versionadded:: 10.0.0 +AUTO_GET_RULE_CRITERIA +********************** - Display new actions in the ITIL object's answer dropdown +Automatic hook function called with an array with the key 'rule_itemtype' set to the itemtype and 'values' set to the input sent to the rule engine. +The function is expected to return an array of criteria to add. +Only called if the plugin also uses the Hooks::USE_RULES hook set to true. -``show_in_timeline`` - .. versionadded:: 10.0.0 - Display forms in the ITIL object's timeline -Notifications -+++++++++++++ -Hooks that are called from notifications +AUTO_GET_RULE_ACTIONS +********************* -``item_add_targets`` - When a target has been added to an item +Automatic hook function called with an array with the key 'rule_itemtype' set to the itemtype and 'values' set to the input sent to the rule engine. +The function is expected to return an array of actions to add. +Only called if the plugin also uses the Hooks::USE_RULES hook set to true. -``item_get_events`` - After notifications events have been retrieved -``item_action_targets`` - After target addresses have been retrieved -``item_get_datas`` - After data for template have been retrieved +AUTO_RULE_COLLECTION_PREPARE_INPUT_DATA_FOR_PROCESS +*************************************************** -``add_recipient_to_target`` - .. versionadded:: 9.4.0 +Only called if the plugin also uses the Hooks::USE_RULES hook set to true. - When a recipient is added to targets. - The object passed as hook method parameter will contain a property ``recipient_data`` which will - be an array containing `itemtype` and `items_id` fields corresponding to the added target. +AUTO_PRE_PROCESS_RULE_COLLECTION_PREVIEW_RESULTS +************************************************ -Functions hooks -^^^^^^^^^^^^^^^ +Only called if the plugin also uses the Hooks::USE_RULES hook set to true. -Usage -+++++ -Functions hooks declarations are the same than standards hooks one. The main difference is that the hook will wait as output what have been passed as argument. +AUTO_RULEIMPORTASSET_GET_SQL_RESTRICTION +**************************************** -.. code-block:: php +Automatic hook function called with an array containing several criteria including: +* 'where_entity' => the entity to restrict +* 'input' => the rule input +* 'criteria' => the rule criteria +* 'sql_where' => the SQL WHERE clause as a string +* 'sql_from' => the SQL FROM clause as a string +The function is expected to modify the given array as needed and return it. +Only called if the plugin also uses the Hooks::USE_RULES hook set to true. - The HTML input name expected. +* searchtype' => The search type of the criteria (contains, equals, etc). +* 'searchoption' => The search option array related to the criteria. +* 'value' => The current value of the criteria. +The function is expected to output HTML content if it customizes the value field and then return true. If the default behavior is desired, the function should not output anything and return false. -``infocom`` - Additional infocom informations oin an item. Will receive an item instance as parameter, is expected to return a table line (````). -``retrieve_more_field_from_ldap`` - Retrieve aditional fields from LDAP for a user. Will receive the current fields lists, is expected to return a fields list. +AUTO_ADD_PARAM_FOR_DYNAMIC_REPORT +********************************* -``retrieve_more_data_from_ldap`` - Retrieve aditional data from LDAP for a user. Will receive current fields list, is expected to return a fields list. +Automatic hook function to add URL parameters needed for a dynamic report/export. +The function is called with the itemtype as a parameter. +The function is expected to return a key/value array of parameters to add. -``display_locked_fields`` - To manage fields locks. Will receive an array with ``item`` and ``header`` entries. Is expected to output a table line (````). -``migratetypes`` - Item types to migrate, will receive an array of types to be updated; must return an aray of item types to migrate. +AUTO_ADD_DEFAULT_JOIN +********************* -Automatic hooks -^^^^^^^^^^^^^^^ +Automatic hook function to add a JOIN clause to the SQL query for a search of itemtypes added by the plugin. +This can be a LEFT JOIN , INNER JOIN or RIGHT JOIN. +The function is called with the following parameters: +* 'itemtype' => The type of the items being searched. +* 'reference_table' => The name of the reference table. This should be the table for the itemtype. +* 'already_link_table' => An array of tables that are already joined. +The function is expected to return a SQL JOIN clause as a string or an empty string if the default behavior should be used. -Some hooks are automated; they'll be called if the relevant function exists in you plugin's ``hook.php`` file. Required function must be of the form ``plugin_{plugin_name}_{hook_name}``. -``MassiveActionsFieldsDisplay`` - Add massive actions. Will receive an array with ``item`` (the item type) and ``options`` (the search options) as input. These hook have to output its content, and to return true if there is some specific output, false otherwise. +AUTO_ADD_DEFAULT_SELECT +*********************** -``dynamicReport`` - Add parameters for print. Will receive the ``$_GET`` array used for query. Is expected to return an array of parameters to add. +Automatic hook function to add a SELECT clause to the SQL query for a searchof itemtypes added by the plugin. +The function is called with the following parameters: +* 'itemtype' => The type of the items being searched. +The function is expected to return a SQL SELECT clause as a string or an empty string if the default behavior should be used. -``AssignToTicket`` - Declare types an ITIL object can be assigned to. Will receive an empty array adn is expected to return a list an array of type of the form: - .. code-block:: php +AUTO_ADD_DEFAULT_WHERE +********************** - 'label' - ]; +Automatic hook function to add a WHERE clause to the SQL query for a searchof itemtypes added by the plugin. +The function is called with the following parameters: +* 'itemtype' => The type of the items being searched. +The function is expected to return a SQL WHERE clause as a string or an empty string if the default behavior should be used. -``MassiveActions`` - If plugin is parameted to provide massive actions (via ``$PLUGIN_HOOKS['use_massive_actions']``), will pass the item type as parameter, and expect an array of aditional massives actions of the form: - .. code-block:: php +ADD_DEFAULT_JOIN +**************** - 'label' - ]; +Automatic hook function to add a JOIN clause to the SQL query for a search. +The function is called with the following parameters: +* 'itemtype' => The type of the items being searched. +* 'join' => The current JOIN clause in the iterator format. +The function is expected to return the modified join array or an empty array if no join should be added. + This function is called after the Hooks::AUTO_ADD_DEFAULT_JOIN hook and after the default joins are added. -``getDropDown`` - To declare extra dropdowns. Will not receive any parameter, and is expected to return an array of the form: - .. code-block:: php +ADD_DEFAULT_WHERE +***************** - 'label' - ]; +Automatic hook function to add a WHERE clause to the SQL query for a search. +The function is called with the following parameters: +* 'itemtype' => The type of the items being searched. +* 'criteria' => The current WHERE clause in the iterator format. +The function is expected to return the modified criteria array or an empty array if no criteria should be added. +This function is called after the Hooks::AUTO_ADD_DEFAULT_WHERE hook and after the default WHERE clauses are added. -``rulePrepareInputDataForProcess`` - Provide data to process rules. Will receive an array with ``item`` (data used to check criteria) and ``params`` (the parameters) keys. Is expected to retrun an array of rules. -``executeActions`` - Actions to execute for rule. Will receive an array with ``output``, ``params`` ans ``action`` keys. Is expected to return an array of actions to execute. +AUTO_ADD_HAVING +*************** -``preProcessRulePreviewResults`` +Automatic hook function to add a HAVING clause to the SQL query for a specific search criteria. +The function is called with the following parameters: +* 'link' => The linking operator (AND/OR) for the criteria. +* 'not' => Indicates if the criteria is negated. +* 'itemtype' => The type of the items being searched. +* 'search_option_id' => The ID of the search option of the criteria. +* 'search_value' => The value to search for. +* 'num' => A string in the form of "${itemtype}_{$search_option_id}". The alias of the related field in the SELECT clause will be "ITEM_{$num}". +The function is expected to return a SQL HAVING clause as a string or an empty string if the default behavior should be used. - .. todo:: - Write documentation for this hook. +AUTO_ADD_LEFT_JOIN +****************** -``use_rules`` +Automatic hook function to add a JOIN clause to the SQL query for a specific search criteria. +Despite the name, this can be a LEFT JOIN , INNER JOIN or RIGHT JOIN. +The function is called with the following parameters: +* 'itemtype' => The type of the items being searched. +* 'reference_table' => The name of the reference table. This is typically the table for the itemtype. +* 'new_table' => The name of the table to be joined. Typically, this is the table related to the search option. +* 'link_field' => The name of the field in the reference table that links to the new table. +* 'already_link_table' => An array of tables that are already joined. +The function is expected to return a SQL JOIN clause as a string or an empty string if the default behavior should be used. - .. todo:: - Write documentation for this hook. It lloks at bit particular. +AUTO_ADD_ORDER_BY +***************** -``ruleCollectionPrepareInputDataForProcess`` - Prepare input data for rules collections. Will receive an array of the form: +Automatic hook function to add an ORDER clause to the SQL query for a specific search criteria. +The function is called with the following parameters: +* 'itemtype' => The type of the items being searched. +* 'search_option_id' => The ID of the search option of the criteria. +* 'order' => The order requested (ASC/DESC). +* 'num' => A string in the form of "${itemtype}_{$search_option_id}". The alias of the related field in the SELECT clause will be "ITEM_{$num}". +The function is expected to return a SQL ORDER clause as a string or an empty string if the default behavior should be used. - .. code-block:: php - 'name fo the rule itemtype', - 'values' => array( - 'input' => 'input array', - 'params' => 'array of parameters' - ) - ); +AUTO_ADD_SELECT +*************** - Is expected to return an array. +Automatic hook function to add a SELECT clause to the SQL query for a specific search criteria. +The function is called with the following parameters: +* 'itemtype' => The type of the items being searched. +* 'search_option_id' => The ID of the search option of the criteria. +* 'num' => A string in the form of "${itemtype}_{$search_option_id}". The alias of the related field in the clause returned should be "ITEM_{$num}". +The function is expected to return a SQL SELECT clause as a string or an empty string if the default behavior should be used. -``preProcessRuleCollectionPreviewResults`` -.. todo:: +AUTO_ADD_WHERE +************** - Write documentation for this hook. +Automatic hook function to add a WHERE clause to the SQL query for a specific search criteria. +The function is called with the following parameters: +* 'link' => No longer used but used to indicate the linking operator (AND/OR) for the criteria. +* 'not' => Indicates if the criteria is negated. +* 'itemtype' => The type of the items being searched. +* 'search_option_id' => The ID of the search option of the criteria. +* 'search_value' => The value to search for. +* 'search_type' => The type of the search (notcontains, contains, equals, etc.). +The function is expected to return a SQL WHERE clause as a string or an empty string if the default behavior should be used. -``ruleImportComputer_addGlobalCriteria`` - Add global criteria for computer import. Will receive an array of global criteria, is expected to return global criteria array. -``ruleImportComputer_getSqlRestriction`` - Adds SQL restriction to links. Will receive an array of the form: +AUTO_GIVE_ITEM +************** - .. code-block:: php +Automatic hook function to show an HTML search result column value for an item of one of the itemtypes added by the plugin. +The function is called with the following parameters: +* 'itemtype' => The type of the result items. +* 'search_option_id' => The ID of the search option. +* 'data' => The data retrieved from the database. +* 'id' => The ID of the result item. +The function is expected to return the HTML content to display or an empty string if the default display should be used. - 'where entity clause', - 'input' => 'input array', - 'criteria' => 'complex cirteria array', - 'sql_where' => 'sql where clause as string', - 'sql_from' => 'sql from clause as string' - ) - Is expected to return the input array modified. +AUTO_DISPLAY_CONFIG_ITEM +************************ + +Automatic hook function to show an export (CSV, PDF, etc) search result column value for an item of one of the itemtypes added by the plugin. +This function is called with the following parameters: +* 'itemtype' => The type of the items being searched. +* 'search_option_id' => The ID of the search option. +* 'data' => The data retrieved from the database. +* 'num' => A string in the form of "${itemtype}_{$search_option_id}". The alias of the related field in the SELECT clause will be "ITEM_{$num}". +The function is expected to return content to display or an empty string if the default display should be used. -``getAddSearchOptions`` - Adds :ref:`search options `, using "old" method. Will receive item type as string, is expected to return an array of search options. -``getAddSearchOptionsNew`` - Adds :ref:`search options `, using "new" method. Will receive item type as string, is expected to return an **indexed** array of search options. + +AUTO_STATUS +*********** + +Automatic hook function to report status information through the GLPI status feature. +The function receives a parameter with the following keys: +* 'ok' => Always true +* '_public_only' => True if only non-sensitive/public information should be returned +The function is expected to return an array containing at least a 'status' key with a `StatusChecker::STATUS_*` value. +`https://glpi-user-documentation.readthedocs.io/fr/latest/advanced/status.html `_