Code of Conduct
Is there an existing issue for this?
GLPI Version
11.0.7
Plugin version
1.9.6
Bug description
Hello! I have been debugging an issue where exporting native reports to ODT format generates either broken files or documents without the data tables (only charts). During the debugging session, I found two specific bugs in the code that prevent the export from working correctly.
Bug 1: Hardcoded _tmp path
The plugin assumes that the _tmp folder is always located inside the documents directory. This causes path/permission errors on instances that use custom paths or strict server setups.
Suggested fix: The plugin should ideally rely on GLPI's core constants (like GLPI_TMP_DIR) to handle temporary files instead of assuming a relative path.
Bug 2: property_exists fails with Odf magic properties
When exporting a single report to ODT, the data table is missing from the document. In inc/common.class.php (around line 1313, inside the export() method's else block), the code tries to verify if the template block exists using property_exists:
if (property_exists($singledatas, 'datas') && $singledatas->datas !== null)
Because the Odf library uses PHP magic methods (__get) to handle its child properties, property_exists() evaluates to false, causing the script to skip the data injection (the foreach loop) entirely, leaving the template empty.
(This also happens in the multipledatas block around lines 1294 and 1301).
Suggested fix: Replace property_exists with isset(), which correctly triggers the magic methods:
if (isset($singledatas->datas) || $singledatas->datas !== null) {
// ... loop and merge
}
Relevant log output
Page URL
No response
Steps To reproduce
- Go to a native report (e.g., Ticket Number by Entity).
- Click on Export -> ODT.
- The downloaded ODT will contain the charts but the data table block will be empty/missing due to the failing condition.
Your GLPI setup information
GLPI information
GLPI: 11.0.7 ( => /var/www/glpi)
Installation mode: TARBALL
Current language: es_VE
Source Integrity: 20 files changed
A: inc/downstream.php
Server
Operating system: Linux btoursv315 6.8.0-124-generic #124-Ubuntu SMP PREEMPT_DYNAMIC Tue May 26 13:00:45 UTC 2026 x86_64
PHP: 8.3.6 apache2handler
PHP extensions: Core, date, libxml, openssl, pcre, zlib, filter, hash, json, random, Reflection, SPL, session, standard, sodium, apache2handler, mysqlnd, PDO, xml, apcu, bcmath, bz2, calendar, ctype, curl, dom, mbstring, FFI, fileinfo, ftp, gd, gettext, iconv, intl, ldap, exif, mysqli, pdo_mysql, Phar, posix, readline, shmop, SimpleXML, sockets, sysvmsg, sysvsem, sysvshm, tokenizer, xmlreader, xmlrpc, xmlwriter, xsl, zip, Zend OPcache
Setup: disable_functions="" max_execution_time="30" max_input_vars="1000" memory_limit="128M" post_max_size="8M" session.cookie_secure="1" session.cookie_httponly="1" session.cookie_samesite="" session.save_handler="files" upload_max_filesize="2M"
Web server: Apache/2.4.58 (Ubuntu) (Apache/2.4.58 (Ubuntu) Server at glpi.***** Port 443)
User agent: Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0
Database:
Server Software: (Ubuntu)
Server Version: 8.0.46-0ubuntu0.24.04.2
Server SQL Mode: STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
Parameters: adminglpi@localhost/glpi
Host info: Localhost via UNIX socket
Requirements:
PHP version (8.3.6) is supported.
OS and PHP are relying on 64 bits integers.
Sessions configuration is OK.
Allocated memory is sufficient.
Following extensions are installed: dom, fileinfo, filter, libxml, simplexml, tokenizer, xmlreader, xmlwriter.
mysqli extension is installed
curl extension is installed
gd extension is installed
intl extension is installed
mbstring extension is installed
zlib extension is installed
bcmath extension is installed
The constant SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES is present.
openssl extension is installed
Database engine version (8.0.46) is supported.
The log file has been created successfully.
Write access to /var/lib/glpi/files/_cache has been validated.
Write access to /var/lib/glpi/files/_cron has been validated.
Write access to /var/lib/glpi/docs has been validated.
Write access to /var/lib/glpi/files/_graphs has been validated.
Write access to /var/lib/glpi/files/_lock has been validated.
Write access to /var/lib/glpi/files/_pictures has been validated.
Write access to /var/lib/glpi/files/_plugins has been validated.
Write access to /var/lib/glpi/files/_rss has been validated.
Write access to /var/lib/glpi/files/_sessions has been validated.
Write access to /var/lib/glpi/files/_tmp has been validated.
Write access to /var/lib/glpi/files/_uploads has been validated.
Sessions configuration is secured.
exif extension is installed
ldap extension is installed
Following extensions are installed: bz2, Phar, zip.
Zend OPcache extension is installed
Following extensions are installed: ctype, iconv, sodium.
Write access to /var/lib/glpi/marketplace has been validated.
Timezones seems loaded in database.
GLPI constants
GLPI_ROOT: "/var/www/glpi"
GLPI_VERSION: "11.0.7"
GLPI_SCHEMA_VERSION: "11.0.7@a797be2bef86f3888448b141fa810dba6fb67795"
GLPI_FILES_VERSION: "11.0.7-49a93008"
GLPI_MIN_PHP: "8.2"
GLPI_MAX_PHP: "8.5"
GLPI_YEAR: "2026"
GLPI_I18N_DIR: "/var/www/glpi/locales"
GLPI_CONFIG_DIR: "/etc/glpi"
GLPI_VAR_DIR: "/var/lib/glpi/files"
GLPI_DOC_DIR: "/var/lib/glpi/docs"
GLPI_LOG_DIR: "/var/log/glpi"
GLPI_MARKETPLACE_DIR: "/var/lib/glpi/marketplace"
GLPI_ENVIRONMENT_TYPE: "production"
GLPI_ALLOW_IFRAME_IN_RICH_TEXT: false
GLPI_SERVERSIDE_URL_ALLOWLIST: ["^\n (http|https|feed):// # protocol\n (\n (?:\n (?:xn--[a-z0-9-]++\.)*+xn--[a-z0-9-]++ # a domain name using punycode\n |\n (?:[\pL\pN\pS\pM\-\]++\.)+[\pL\pN\pM]++ # a multi-level domain name\n |\n [a-z0-9\-\]++ # a single-level domain name\n )\.?\n | # or\n \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # an IP address\n | # or\n \[\n (?:(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-f]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,1}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,2}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,3}(?:(?:[0-9a-f]{1,4})))?::(?:(?:[0-9a-f]{1,4})):)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,4}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,5}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,6}(?:(?:[0-9a-f]{1,4})))?::))))\n \] # an IPv6 address\n )\n (?:/ (?:[\pL\pN\pS\pM\-._\!$&'()+,;=:@]|%[0-9A-Fa-f]{2}) )* # a path\n (?:\? (?:[\pL\pN\-._\~!$&'\\+,;=:@/?]|%[0-9A-Fa-f]{2}) )? # a query (optional)\n $~ixuD"]
GLPI_DISALLOWED_UPLOADS_PATTERN: "/\.(php\d*|phar)$/i"
GLPI_TELEMETRY_URI: "https://telemetry.glpi-project.org"
GLPI_INSTALL_MODE: "TARBALL"
GLPI_NETWORK_MAIL: "glpi@teclib.com"
GLPI_NETWORK_SERVICES: "https://services.glpi-network.com"
GLPI_MARKETPLACE_ENABLE: 3
GLPI_MARKETPLACE_PRERELEASES: false
GLPI_MARKETPLACE_ALLOW_OVERRIDE: true
GLPI_MARKETPLACE_MANUAL_DOWNLOADS: true
GLPI_USER_AGENT_EXTRA_COMMENTS: ""
GLPI_DOCUMENTATION_ROOT_URL: "https://links.glpi-project.org"
GLPI_DISABLE_ONLY_FULL_GROUP_BY_SQL_MODE: "1"
GLPI_LOG_LVL: "warning"
GLPI_SKIP_UPDATES: false
GLPI_STRICT_ENV: false
GLPI_AJAX_DASHBOARD: "1"
GLPI_CALDAV_IMPORT_STATE: 0
GLPI_CENTRAL_WARNINGS: "1"
GLPI_SYSTEM_CRON: false
GLPI_TEXT_MAXSIZE: "4000"
GLPI_WEBHOOK_ALLOW_RESPONSE_SAVING: "0"
GLPI_WEBHOOK_CRA_MANDATORY: false
GLPI_ALTCHA_MODE: "interactive"
GLPI_ALTCHA_MAX_NUMBER: 50000
GLPI_ALTCHA_EXPIRATION_INTERVAL: "PT20M"
GLPI_CACHE_DIR: "/var/lib/glpi/files/_cache"
GLPI_CRON_DIR: "/var/lib/glpi/files/_cron"
GLPI_GRAPH_DIR: "/var/lib/glpi/files/_graphs"
GLPI_LOCAL_I18N_DIR: "/var/lib/glpi/files/_locales"
GLPI_LOCK_DIR: "/var/lib/glpi/files/_lock"
GLPI_PICTURE_DIR: "/var/lib/glpi/files/_pictures"
GLPI_PLUGIN_DOC_DIR: "/var/lib/glpi/files/_plugins"
GLPI_RSS_DIR: "/var/lib/glpi/files/_rss"
GLPI_SESSION_DIR: "/var/lib/glpi/files/_sessions"
GLPI_TMP_DIR: "/var/lib/glpi/files/_tmp"
GLPI_UPLOAD_DIR: "/var/lib/glpi/files/_uploads"
GLPI_INVENTORY_DIR: "/var/lib/glpi/files/_inventories"
GLPI_THEMES_DIR: "/var/lib/glpi/files/_themes"
GLPI_PLUGINS_DIRECTORIES: ["/var/lib/glpi/marketplace","/var/www/glpi/plugins"]
GLPI_NETWORK_API_URL: "https://services.glpi-network.com/api"
GLPI_NETWORK_REGISTRATION_API_URL: "https://services.glpi-network.com/api/registration/"
GLPI_MARKETPLACE_PLUGINS_API_URI: "https://services.glpi-network.com/api/marketplace/"
LDAP directories
Server: 'ldaps://',
Port: '636',
BaseDN: 'OU=,DC=,DC=,DC=,DC=',
Connection filter: '(&(objectClass=user)(objectCategory=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))',
RootDN: 'CN=,OU=,DC=,DC=,DC=,DC=',
Use TLS: none
SQL replicas
Not active
Notifications
Way of sending emails: SMTP(smtp://%40**:@smtp.gmail.com:465)
Name: '@'
Active: No
Server: '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX'
Login: '@'
Password: Yes
Name: '@'
Active: Yes
Server: '{imap.gmail.com:993/imap/ssl/novalidate-cert}INBOX'
Login: '@*'
Password: Yes
Plugins list
gantt Name: gantt Version: 1.3.3 State: Enabled Install Method: Marketplace
glpiinventory Name: GLPI Inventory Version: 1.6.7 State: Enabled Install Method: Marketplace
mreporting Name: More Reporting Version: 1.9.6 State: Enabled Install Method: Marketplace
tasklists Name: Tasks list Version: 2.1.7 State: Enabled Install Method: Marketplace
Anything else?
No response
Code of Conduct
Is there an existing issue for this?
GLPI Version
11.0.7
Plugin version
1.9.6
Bug description
Hello! I have been debugging an issue where exporting native reports to ODT format generates either broken files or documents without the data tables (only charts). During the debugging session, I found two specific bugs in the code that prevent the export from working correctly.
Bug 1: Hardcoded _tmp path
The plugin assumes that the _tmp folder is always located inside the documents directory. This causes path/permission errors on instances that use custom paths or strict server setups.
Suggested fix: The plugin should ideally rely on GLPI's core constants (like GLPI_TMP_DIR) to handle temporary files instead of assuming a relative path.
Bug 2: property_exists fails with Odf magic properties
When exporting a single report to ODT, the data table is missing from the document. In inc/common.class.php (around line 1313, inside the export() method's else block), the code tries to verify if the template block exists using property_exists:
Because the Odf library uses PHP magic methods (__get) to handle its child properties, property_exists() evaluates to false, causing the script to skip the data injection (the foreach loop) entirely, leaving the template empty.
(This also happens in the multipledatas block around lines 1294 and 1301).
Suggested fix: Replace property_exists with isset(), which correctly triggers the magic methods:
Relevant log output
Page URL
No response
Steps To reproduce
Your GLPI setup information
GLPI information
Server
GLPI constants
LDAP directories
SQL replicas
Notifications
Plugins list
Anything else?
No response