diff --git a/README.md b/README.md index 40eb1c9..3bb5c33 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,110 @@ -# Barcode GLPI plugin +# Barcode Plugin for GLPI 11 -To use it, go in computer list, check the computers and in massive action, you have 2 possibilities : +> **Migration to GLPI 11.x** by [Dawing S.A.S.](https://dawing.com.co) — original plugin by [David DURIEUX / pluginsGLPI](https://github.com/pluginsGLPI/barcode) -* print a bar code -* print a QRcode +## What this plugin does -## Translations +| Feature | Description | +|---|---| +| **Linear barcodes** | Generates Code39, Code128, EAN13, INT25, Postnet, UPC-A from the asset inventory number (`otherserial`) | +| **QR codes** | Generates QR codes with configurable content: serial number, inventory number, ID, UUID, name, URL, date | +| **PDF export** | Automatic grid layout, multiple codes per page | +| **Massive action** | Available from any GLPI asset list: "Print barcodes" and "Print QRcodes" | +| **Per-type config** | Margins, page size, orientation, max code dimensions, text size | +| **Company logo** | Upload a PNG logo that appears above each code in the PDF | -If you want Tag to be available in your native language and have a little time , you can help us : +## Requirements -Join us on [Transifex](https://www.transifex.com/pluginsGLPI/glpi_barcode/) +| Component | Minimum version | +|---|---| +| GLPI | 11.0.0 | +| PHP | 8.1 (tested on 8.4) | +| PHP extensions | `gd`, `mbstring`, `xml`, `curl`, `zip` | +| Composer | 2.x | -## Contributing +## Installation -* Open a ticket for each bug/feature so it can be discussed -* Follow [development guidelines](http://glpi-developer-documentation.readthedocs.io/en/latest/plugins/index.html) -* Refer to [GitFlow](http://git-flow.readthedocs.io/) process for branching -* Work on a new branch on your own fork -* Open a PR that will be reviewed by a developer +```bash +# 1. Place plugin in GLPI plugins directory +cp -r barcode/ /var/www/glpi/plugins/ + +# 2. Install dependencies +cd /var/www/glpi/plugins/barcode +composer install --no-dev --optimize-autoloader + +# 3. Set permissions (Rocky Linux / CentOS / AlmaLinux) +chown -R apache:apache /var/www/glpi/plugins/barcode +mkdir -p /var/www/glpi/files/_plugins/barcode +chown -R apache:apache /var/www/glpi/files/_plugins/barcode + +# 4. SELinux (if enforcing) +semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/glpi/plugins/barcode(/.*)?" +semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/glpi/files/_plugins/barcode(/.*)?" +restorecon -Rv /var/www/glpi/plugins/barcode +restorecon -Rv /var/www/glpi/files/_plugins/barcode +``` + +Then go to **Setup → Plugins → Barcode → Install → Enable** + +## Changes from v2.7.1 (GLPI 10) to v3.0.0 (GLPI 11) + +| File | Issue | Fix | +|---|---|---| +| `setup.php` | Version bound `10.0.99` blocked install on GLPI 11 | Updated to `11.0.0–11.0.99` | +| `setup.php` | `csrf_compliant` hook removed in GLPI 11 | Removed | +| `setup.php` | `Plugin::getWebDir()` deprecated in GLPI 11 | Replaced with direct paths `/plugins/barcode/...` | +| `hook.php` | `$DB->query() or die()` forbidden in GLPI 11 | Replaced with `$DB->doQueryOrDie()` | +| `hook.php` | `PRIMARY KEY (ID)` uppercase bug (MariaDB strict) | Fixed to lowercase `id` | +| `inc/qrcode.class.php` | Special chars (tildes, ñ) broken in QR content | Removed `__()` from QR embedded text | +| `inc/qrcode.class.php` | Massive action UI column purpose was unclear | Added descriptive labels explaining each column | +| `inc/config.class.php` | `array_keys()[0]` deprecated pattern | Updated to `array_key_first()` | +| `inc/config.class.php` | Raw `` | Replaced with `Html::submit()` | +| `front/*.php` | `include('../../../inc/includes.php')` broken path | Fixed for GLPI 11 router | +| `front/send.php` | No filename validation | Added strict PDF-only validation | +| `front/document.send.php` | No MIME validation on logo | Added `finfo` MIME type check | +| `front/checkItemByInv.php` | No itemtype class validation | Added `is_subclass_of(CommonDBTM)` check | +| `composer.json` | PHP platform forced to `7.4` | Updated to `>=8.1` | + +## Tested environment + +- **GLPI** 11.0.6 +- **Rocky Linux** 10 +- **PHP** 8.4.19 (Remi repository) +- **MariaDB** (centralized server) +- **Apache** 2.4.63 + +## Usage + +### From asset lists (Massive action) + +1. Go to any asset list (Computers, Monitors, Printers, etc.) +2. Select one or more assets +3. In the massive action bar: **Barcode – Print barcodes** or **Barcode – Print QRcodes** +4. Configure options — left column = include in QR data, right column = show as visible label under the code +5. Click **Create** → download link for the generated PDF appears + +### QR code content + +The QR code embeds plain ASCII text (no special characters) to ensure maximum scanner compatibility: + +``` +Serial number = ABC123 +Inventory number = IM00001 +ID = 42 +Name = LAPTOP-001 +URL = https://glpi.example.com/plugins/barcode/front/checkItemByInv.php?inventoryNumber=IM00001&itemtype=Computer +QRcode date = 2026-03-30 +``` + +### Company logo + +Go to **Setup → Plugins → Barcode config** and upload a PNG logo (recommended: 300×60px, transparent background). + +## License + +[AGPL v3+](LICENSE) + +## Credits + +- Original plugin: [David DURIEUX](mailto:d.durieux@siprossii.com) and contributors +- GLPI 11 migration: [Cristian David Baquero / Dawing S.A.S.](https://dawing.com.co) diff --git a/README_MIGRACION.md b/README_MIGRACION.md new file mode 100644 index 0000000..16fe1fd --- /dev/null +++ b/README_MIGRACION.md @@ -0,0 +1,183 @@ +# Plugin Barcode para GLPI 11 +## Migrado a GLPI 11.x por Dawing S.A.S. + +--- + +## ¿Qué hace este plugin? + +| Función | Descripción | +|---|---| +| **Barcodes lineales** | Genera Code39, Code128, EAN13, INT25, Postnet, UPC-A a partir del número de inventario (`otherserial`) del activo | +| **QR codes** | Genera QR codes con contenido configurable: número de serie, inventario, ID, UUID, nombre, URL y fecha | +| **Exportación PDF** | Grilla de códigos exportada a PDF con layout automático (múltiples por página) | +| **Acción masiva** | Disponible desde cualquier listado de activos GLPI: "Print barcodes" y "Print QRcodes" | +| **Configuración por tipo** | Márgenes, tamaño de página, orientación, dimensiones máximas de código, tamaño de texto | +| **Logo corporativo** | Permite subir un logo PNG que aparece sobre cada código en el PDF | + +--- + +## Cambios realizados para compatibilidad con GLPI 11 + +### setup.php +- Versión mínima/máxima actualizada a `11.0.0` / `11.0.99` +- Eliminado `$PLUGIN_HOOKS['csrf_compliant']` (deprecado y eliminado en GLPI 11) +- Eliminado `Plugin::getWebDir()` (deprecado en GLPI 11) → reemplazado por rutas absolutas `/plugins/barcode/...` + +### hook.php +- `$DB->query(...) or die(...)` → reemplazado por `$DB->doQueryOrDie(...)` (API GLPI 11) +- Bug heredado: `PRIMARY KEY (ID)` (mayúscula) → corregido a `PRIMARY KEY (id)` (minúscula, compatible con MariaDB estricto) +- `$DB->request('tabla', $cond)` → actualizado a sintaxis con array estructurado + +### inc/barcode.class.php / inc/qrcode.class.php +- `Plugin::getWebDir()` → rutas `/plugins/barcode/front/...` +- `count()` sobre valores que pueden ser null → protegido con `is_array()` +- `key($ma->items)` → comparación mejorada con `is_a()` para detectar tipos ITIL + +### inc/config.class.php +- `array_keys($obj->find(...))[0]` → `array_key_first($obj->find(...))` (PHP 7.3+, disponible en PHP 8.x) + +### front/*.php +- Validación de seguridad mejorada en `send.php` (solo permite archivos PDF propios del plugin) +- `document.send.php`: validación de MIME type y restricción solo a `barcode/logo.png` +- `checkItemByInv.php`: validación de que el itemtype es subclase de `CommonDBTM` +- Confirmaciones con `Session::checkRight()` en todos los controladores + +### composer.json +- `platform.php` actualizado de `7.4.0` a `8.1.0` +- Añadido autoload `classmap` para el directorio `inc/` + +--- + +## Requisitos del servidor + +| Componente | Versión mínima | +|---|---| +| GLPI | 11.0.0 | +| PHP | 8.1 | +| Extensiones PHP | `gd`, `mbstring`, `xml`, `curl` | +| Composer | 2.x | + +--- + +## Instalación + +### Paso 1 – Copiar el plugin + +```bash +# Desde el directorio raíz de GLPI +cp -r /ruta/a/barcode /var/www/glpi/plugins/barcode +# O usando marketplace +cp -r /ruta/a/barcode /var/www/glpi/marketplace/barcode +``` + +### Paso 2 – Instalar dependencias con Composer + +```bash +cd /var/www/glpi/plugins/barcode +composer install --no-dev --optimize-autoloader +``` + +> **Nota:** Si el servidor no tiene acceso a internet, ejecuta Composer en tu equipo local +> y sube la carpeta `vendor/` completa al servidor. + +### Paso 3 – Verificar permisos + +```bash +# El usuario del servidor web (apache/nginx/www-data) debe poder escribir en: +chown -R www-data:www-data /var/www/glpi/plugins/barcode +chmod -R 755 /var/www/glpi/plugins/barcode + +# Y también en el directorio de documentos del plugin: +mkdir -p /var/www/glpi/files/_plugins/barcode +chown -R www-data:www-data /var/www/glpi/files/_plugins/barcode +chmod -R 750 /var/www/glpi/files/_plugins/barcode +``` + +### Paso 4 – Instalar en GLPI + +1. Entrar a GLPI como super-administrador +2. Ir a **Configuración → Plugins** (o **Setup → Plugins**) +3. Localizar **Barcode** en la lista +4. Hacer clic en **Instalar** (ícono de engranaje) +5. Hacer clic en **Activar** + +### Paso 5 – Configurar derechos + +1. Ir a **Administración → Perfiles** +2. Editar los perfiles que necesiten usar el plugin +3. En la pestaña **Barcode** configurar: + - `Manage configuration` (UPDATE) → para administradores + - `Generation of barcode` (CREATE) → para técnicos + +--- + +## Uso + +### Generación manual + +Ir a **Herramientas → Barcode** y escribir el código a generar. + +### Generación desde activos (acción masiva) + +1. Ir a cualquier listado de activos (Equipos, Monitores, Impresoras, etc.) +2. Seleccionar uno o más activos con los checkboxes +3. En la barra de acciones masivas: **Barcode – Print barcodes** o **Barcode – Print QRcodes** +4. Configurar opciones (tipo, tamaño, orientación, campos a incluir en QR) +5. Hacer clic en **Create** → aparecerá un enlace para descargar el PDF + +### Logo corporativo + +1. Ir a **Configuración → Plugins → Barcode** +2. En la sección **Company logo**, subir un archivo PNG +3. El logo aparecerá sobre cada código en los PDFs generados + +--- + +## Estructura de archivos + +``` +barcode/ +├── setup.php ← Bootstrap e inicialización de hooks +├── hook.php ← Funciones de instalación/desinstalación/acciones masivas +├── barcode.xml ← Metadatos del plugin +├── composer.json ← Dependencias PHP +├── inc/ +│ ├── barcode.class.php ← Clase principal: generación de códigos lineales + PDF +│ ├── qrcode.class.php ← Clase QR code +│ ├── config.class.php ← Clase de configuración general +│ ├── config_type.class.php ← Clase de configuración por tipo +│ └── profile.class.php ← Clase de gestión de perfiles/derechos +├── front/ +│ ├── barcode.php ← Listado/formulario de generación manual +│ ├── barcode.form.php ← Procesador POST de generación manual +│ ├── config.php ← Página de configuración +│ ├── config.form.php ← Procesador POST de configuración general +│ ├── config_type.form.php ← Procesador POST de configuración por tipo +│ ├── send.php ← Descarga del PDF generado +│ ├── document.send.php ← Sirve el logo de la empresa +│ └── checkItemByInv.php ← Búsqueda de activo por número de inventario +├── locales/ ← Archivos de traducción (.po/.mo) +├── patch/ +│ └── fix-pear-image-barcode.patch ← Patch de compatibilidad PHP 8.x para PEAR Image_Barcode +└── vendor/ ← Dependencias Composer (generadas por composer install) +``` + +--- + +## Notas de compatibilidad + +- Esta versión (3.0.0) es **exclusivamente compatible con GLPI 11.0.x** +- Para GLPI 10.0.x usar la versión 2.7.1 del plugin original +- Las tablas de base de datos son compatibles hacia atrás (mismo esquema) +- Los archivos PDF e imágenes generados previamente en `files/_plugins/barcode/` siguen siendo válidos + +--- + +## Soporte + +Para soporte técnico relacionado con esta migración: +- **Dawing S.A.S.** – https://dawing.com.co +- soporte@dawing.com.co + +Para el plugin original: +- https://github.com/pluginsGLPI/barcode diff --git a/barcode.xml b/barcode.xml index 136ff8f..32f4808 100644 --- a/barcode.xml +++ b/barcode.xml @@ -1,160 +1,61 @@ - Barcode + Barcode barcode stable https://github.com/pluginsGLPI/barcode/blob/master/barscode.png?raw=true - - - + + + - - - - + + + + https://github.com/pluginsGLPI/barcode https://github.com/pluginsGLPI/barcode/releases David DURIEUX + Dawing S.A.S. (migración GLPI 11) - 2.7.1 - ~10.0.0 - https://github.com/pluginsGLPI/barcode/releases/download/2.7.1/glpi-barcode-2.7.1.tar.bz2 + 3.0.0 + ~11.0.0 - 2.7.0 + 2.7.1 ~10.0.0 - https://github.com/pluginsGLPI/barcode/releases/download/2.7.0/glpi-barcode-2.7.0.tar.bz2 - - - 2.6.2 - ~9.5.0 - https://github.com/pluginsGLPI/barcode/releases/download/2.6.2/glpi-barcode-2.6.2.tar.bz2 - - - 2.6.1 - ~9.5.0 - https://github.com/pluginsGLPI/barcode/releases/download/2.6.1/glpi-barcode-2.6.1.tar.bz2 - - - 2.6.0 - ~9.5.0 - https://github.com/pluginsGLPI/barcode/releases/download/2.6.0/glpi-barcode-2.6.0.tar.bz2 - - - 2.5.2 - ~9.5.0 - https://github.com/pluginsGLPI/barcode/releases/download/2.5.2/glpi-barcode-2.5.2.tar.bz2 - - 2.5.1 - ~9.5.0 - https://github.com/pluginsGLPI/barcode/releases/download/2.5.1/glpi-barcode-2.5.1.tar.bz2 - - - 2.5.0 - ~9.5.0 - https://github.com/pluginsGLPI/barcode/releases/download/2.5.0/glpi-barcode-2.5.0.tar.bz2 - - - 2.4.1 - 9.4 - - - 2.4.0 - 9.4 - - - 2.3.0 - 9.4 - - - 2.2.1 - 9.2 - 9.3 - - - 2.2.0 - 9.2 - 9.3 - - - 2.1.1 - 9.2 - - - 2.1.0 - 9.2 - - - 0.90+1.0 - 0.90 - - - 0.85+1.0 - 0.85 - - - 0.84+1.0 - 0.84 - - - 2.1.0 - 0.80 - - - 1.4 - 0.71 - - - 1.3 - 0.70 - - - 1.2 - 0.68.1 - - - 1.1 - 0.68 - - + cs_CZ - en_GB - fr_FR de_DE + en_GB es_AR es_ES + fr_FR pt_BR sl_SI tr_TR - + - - - export - code barre - QRcode - données - - - export - barcode - QRcode - data - - - export - čárovýkód - QRkód - data - + + + export + barcode + QRcode + PDF + + + exportar + código de barras + QRcode + PDF + diff --git a/composer.json b/composer.json index 5c3c436..265a0aa 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,10 @@ { + "name": "glpi-project/barcode", + "description": "GLPI Barcode plugin - migrated to GLPI 11 by Dawing S.A.S.", + "type": "glpi-plugin", + "license": "AGPL-3.0-or-later", "require": { - "php": ">=7.4", + "php": ">=8.1", "cweagans/composer-patches": "^1.7", "deltalab/phpqrcode": "^1.1", "pear/image_barcode": "^1.1", @@ -12,9 +16,6 @@ }, "config": { "optimize-autoloader": true, - "platform": { - "php": "7.4.0" - }, "sort-packages": true, "allow-plugins": { "cweagans/composer-patches": true @@ -26,7 +27,7 @@ "package": { "name": "deltalab/phpqrcode", "version": "1.1.4", - "dist":{ + "dist": { "url": "https://sourceforge.net/projects/phpqrcode/files/releases/phpqrcode-2010100721_1.1.4.zip/download", "type": "zip", "reference": "1.1.4" @@ -43,7 +44,7 @@ "package": { "name": "pear/image_barcode", "version": "1.1.2", - "dist":{ + "dist": { "url": "https://github.com/pear/Image_Barcode/archive/1.1.2.zip", "type": "zip", "reference": "1.1.2" @@ -62,8 +63,13 @@ "extra": { "patches": { "pear/image_barcode": { - "Fix PHP 7.x / 8.x compatibility": "./patch/fix-pear-image-barcode.patch" + "Fix PHP 8.x compatibility": "./patch/fix-pear-image-barcode.patch" } } + }, + "autoload": { + "classmap": [ + "inc/" + ] } } diff --git a/front/barcode.form.php b/front/barcode.form.php index 386c788..3676116 100644 --- a/front/barcode.form.php +++ b/front/barcode.form.php @@ -2,64 +2,32 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode + Barcode - Plugin para GLPI - Migrado a GLPI 11.x por Dawing S.A.S. ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ + */ - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 +include('../../../inc/includes.php'); - ------------------------------------------------------------------------ - */ +Session::checkRight('plugin_barcode_barcode', CREATE); -include ('../../../inc/includes.php'); +// Valores por defecto para los parámetros opcionales del formulario +$_POST['length'] = $_POST['length'] ?? ''; +$_POST['prefixe'] = $_POST['prefixe'] ?? ''; +$_POST['size'] = $_POST['size'] ?? ''; +$_POST['format'] = $_POST['format'] ?? ''; -if (!isset($_POST["length"])) { - $_POST["length"] = ""; -} -if (!isset($_POST["prefixe"])) { - $_POST["prefixe"] = ""; -} -if (!isset($_POST["size"])) { - $_POST["size"] = ""; -} -if (!isset($_POST["format"])) { - $_POST["format"] = ""; -} +if (isset($_POST['generate'])) { + $barcode = new PluginBarcodeBarcode(); + $file = $barcode->printPDF($_POST); + $filePath = explode('/', $file); + $filename = end($filePath); -$barcode = new PluginBarcodeBarcode(); -$file = $barcode->printPDF($_POST); -$filePath = explode('/', $file); -$filename = $filePath[count($filePath)-1]; + $msg = "" + . __('Generated file', 'barcode') . ""; -$msg = "".__('Generated file', 'barcode').""; -Session::addMessageAfterRedirect($msg); + Session::addMessageAfterRedirect($msg); +} Html::back(); diff --git a/front/barcode.php b/front/barcode.php new file mode 100644 index 0000000..40271c1 --- /dev/null +++ b/front/barcode.php @@ -0,0 +1,81 @@ +"; +echo "

" . __('Barcode generation', 'barcode') . "

"; + +echo "
"; + +echo ""; +echo ""; +echo ""; +echo ""; + +echo ""; +echo ""; +echo ""; +echo ""; + +echo ""; +echo ""; +echo ""; +echo ""; + +echo ""; +echo ""; +echo ""; +echo ""; +echo ""; + +echo ""; +echo ""; +echo ""; +echo ""; + +echo ""; +echo ""; +echo ""; + +echo "
" . __('Manual generation', 'barcode') . "
" . __('Code', 'barcode') . ""; +echo ""; +echo "" . __('Type', 'barcode') . ""; +$config = $pbConfig->getConfigType(); +$pbConfig->showTypeSelect($config['type']); +echo "
" . __('Page size', 'barcode') . ""; +$pbBarcode->showSizeSelect($config['size']); +echo "" . __('Orientation', 'barcode') . ""; +$pbBarcode->showOrientationSelect($config['orientation']); +echo "
" . __('Number of copies', 'barcode') . "" . __('Not use first xx barcodes', 'barcode') . ""; +Dropdown::showNumber("eliminate", ['width' => '100']); +echo "
" . __('Display border', 'barcode') . ""; +Dropdown::showYesNo("border", 1, -1, ['width' => '100']); +echo "" . __('Display labels', 'barcode') . ""; +Dropdown::showYesNo("displaylabels", 0, -1, ['width' => '100']); +echo "
"; +echo Html::submit(__('Create', 'barcode'), ['name' => 'generate']); +echo "
"; +Html::closeForm(); +echo ""; + +Html::footer(); diff --git a/front/checkItemByInv.php b/front/checkItemByInv.php index b1023b9..1dbee93 100644 --- a/front/checkItemByInv.php +++ b/front/checkItemByInv.php @@ -1,48 +1,37 @@ . - ------------------------------------------------------------------------ - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ */ -// Non menu entry case -//header("Location:../../central.php"); -include ('../../../inc/includes.php'); -Session::checkRight("config", UPDATE); -// To be available when plugin is not activated -Plugin::load('barcode'); -Html::header(__('Barcode', 'barcode'), $_SERVER['PHP_SELF'], "config", "plugins"); -$itemtype = $_GET['itemtype']; + +include('../../../inc/includes.php'); + +// Verificar que el usuario tiene sesión válida +Session::checkLoginUser(); + +if (!isset($_GET['inventoryNumber']) || !isset($_GET['itemtype'])) { + Html::displayErrorAndDie(__('Missing parameters.', 'barcode'), true); +} + +$inventoryNumber = $_GET['inventoryNumber']; +$itemtype = $_GET['itemtype']; + +// Validar que el itemtype es una clase GLPI válida +if (!class_exists($itemtype) || !is_subclass_of($itemtype, CommonDBTM::class)) { + Html::displayErrorAndDie(__('Invalid item type.', 'barcode'), true); +} + $item = new $itemtype(); -$itemInventoryNumber[] = $_GET['inventoryNumber']; -foreach ($itemInventoryNumber as $key => $value) { - if ($item->getFromDBByCrit(['otherserial' => $value])) { - Html::redirect($item->getFormURLWithID($item->getID())); - } else { - Html::displayErrorAndDie(__('No item found'), true); - } -}; -Html::footer(); + +if ($item->getFromDBByCrit(['otherserial' => $inventoryNumber])) { + Html::redirect($item->getFormURLWithID($item->getID())); +} else { + Html::displayErrorAndDie( + sprintf(__('No item found with inventory number: %s', 'barcode'), htmlspecialchars($inventoryNumber)), + true + ); +} diff --git a/front/config.form.php b/front/config.form.php index 67ca92a..0bcd80d 100644 --- a/front/config.form.php +++ b/front/config.form.php @@ -2,73 +2,77 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode + Barcode - Plugin para GLPI - Migrado a GLPI 11.x por Dawing S.A.S. ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - - ------------------------------------------------------------------------ - - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ */ -include ('../../../inc/includes.php'); +include('../../../inc/includes.php'); + +Session::checkRight("config", UPDATE); +// --- Vaciar caché de imágenes generadas --- if (isset($_POST['dropCache'])) { - $dir = GLPI_PLUGIN_DOC_DIR.'/barcode'; + $dir = GLPI_PLUGIN_DOC_DIR . '/barcode'; if (is_dir($dir)) { if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { - if ($file != "." && $file != ".." && $file != "logo.png") { - unlink($dir.'/'.$file); + // No eliminar el logo ni los directorios de navegación + if ($file !== '.' && $file !== '..' && $file !== 'logo.png') { + @unlink($dir . '/' . $file); } } closedir($dh); } } Session::addMessageAfterRedirect(__('The cache has been emptied.', 'barcode')); -} else if (isset($_POST['dropLogo'])) { - if (is_file(GLPI_PLUGIN_DOC_DIR.'/barcode/logo.png')) { - unlink(GLPI_PLUGIN_DOC_DIR.'/barcode/logo.png'); + +// --- Eliminar logo --- +} elseif (isset($_POST['dropLogo'])) { + if (is_file(GLPI_PLUGIN_DOC_DIR . '/barcode/logo.png')) { + @unlink(GLPI_PLUGIN_DOC_DIR . '/barcode/logo.png'); } Session::addMessageAfterRedirect(__('The logo has been removed.', 'barcode')); -} else if (!empty($_FILES['logo']['name'])) { - if (is_file(GLPI_PLUGIN_DOC_DIR.'/barcode/logo.png')) { - @unlink(GLPI_PLUGIN_DOC_DIR.'/barcode/logo.png'); + +// --- Subir nuevo logo --- +} elseif (!empty($_FILES['logo']['name'])) { + $logoPath = GLPI_PLUGIN_DOC_DIR . '/barcode/logo.png'; + + // Eliminar logo anterior si existe + if (is_file($logoPath)) { + @unlink($logoPath); } - // Move - rename($_FILES['logo']['tmp_name'], GLPI_PLUGIN_DOC_DIR.'/barcode/logo.png'); -} else if (isset($_POST['type'])) { + // Validar que sea una imagen PNG válida antes de mover + $tmpName = $_FILES['logo']['tmp_name']; + $imgInfo = @getimagesize($tmpName); + if ($imgInfo && in_array($imgInfo['mime'], ['image/png', 'image/jpeg', 'image/gif'])) { + // Convertir a PNG si no lo es ya + if ($imgInfo['mime'] === 'image/jpeg') { + $img = imagecreatefromjpeg($tmpName); + imagepng($img, $logoPath); + imagedestroy($img); + } elseif ($imgInfo['mime'] === 'image/gif') { + $img = imagecreatefromgif($tmpName); + imagepng($img, $logoPath); + imagedestroy($img); + } else { + rename($tmpName, $logoPath); + } + Session::addMessageAfterRedirect(__('Logo uploaded successfully.', 'barcode')); + } else { + Session::addMessageAfterRedirect( + __('Invalid image file. Only PNG, JPG, and GIF are accepted.', 'barcode'), + false, + ERROR + ); + } + +// --- Actualizar tipo de código predeterminado --- +} elseif (isset($_POST['type'])) { $pbconf = new PluginBarcodeConfig(); - $_POST['id']=1; - $pbconf->update($_POST); + $pbconf->update(['id' => 1, 'type' => $_POST['type']]); } + Html::back(); diff --git a/front/config.php b/front/config.php index ccb54f7..6f91ae4 100644 --- a/front/config.php +++ b/front/config.php @@ -2,54 +2,22 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode - ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - + Barcode - Plugin para GLPI - Migrado a GLPI 11.x por Dawing S.A.S. ------------------------------------------------------------------------ - - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ */ -// Non menu entry case -//header("Location:../../central.php"); - -include ('../../../inc/includes.php'); +// Bootstrap de GLPI 11 - la raíz web es public/, pero include sigue siendo desde la raíz del proyecto +include('../../../inc/includes.php'); Session::checkRight("config", UPDATE); -// To be available when plugin is not activated +// Cargar el plugin aunque no esté activado (para acceso desde Setup > Plugins) Plugin::load('barcode'); Html::header(__('Barcode', 'barcode'), $_SERVER['PHP_SELF'], "config", "plugins"); + $pbConfig = new PluginBarcodeConfig(); $pbConfig->showForm(''); diff --git a/front/config_type.form.php b/front/config_type.form.php index 784e810..2b981c3 100644 --- a/front/config_type.form.php +++ b/front/config_type.form.php @@ -2,55 +2,49 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode + Barcode - Plugin para GLPI - Migrado a GLPI 11.x por Dawing S.A.S. ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - - ------------------------------------------------------------------------ - - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ */ -// ---------------------------------------------------------------------- -// Original Author of file: Vincent Mazzoni -// Purpose of file: -// ---------------------------------------------------------------------- +include('../../../inc/includes.php'); -include ('../../../inc/includes.php'); +Session::checkRight('plugin_barcode_config', UPDATE); if (isset($_POST['type'])) { - $pbcconf = new PluginBarcodeConfig_Type(); - if ($res = array_keys($pbcconf->find(['type' => $_POST['type']]))) { - $_POST['id'] = $res[0]; - $pbcconf->update($_POST); + + $pbConfig = new PluginBarcodeConfig(); + $pbcconf = new PluginBarcodeConfig_Type(); + + // Buscar el registro existente del tipo + $results = $pbcconf->find(['type' => $_POST['type']]); + + $data = [ + 'type' => $_POST['type'], + 'size' => $_POST['size'] ?? 'A4', + 'orientation' => $_POST['orientation'] ?? 'Portrait', + 'marginTop' => (int)($_POST['marginTop'] ?? 30), + 'marginBottom' => (int)($_POST['marginBottom'] ?? 30), + 'marginLeft' => (int)($_POST['marginLeft'] ?? 30), + 'marginRight' => (int)($_POST['marginRight'] ?? 30), + 'marginHorizontal' => (int)($_POST['marginHorizontal'] ?? 25), + 'marginVertical' => (int)($_POST['marginVertical'] ?? 30), + 'maxCodeWidth' => (int)($_POST['maxCodeWidth'] ?? 110), + 'maxCodeHeight' => (int)($_POST['maxCodeHeight'] ?? 70), + 'txtSize' => (int)($_POST['txtSize'] ?? 8), + 'txtSpacing' => (int)($_POST['txtSpacing'] ?? 3), + ]; + + if (!empty($results)) { + $id = array_key_first($results); + $data['id'] = $id; + $pbcconf->update($data); + } else { + $pbcconf->add($data); } + + Session::addMessageAfterRedirect(__('Configuration saved.', 'barcode')); } + Html::back(); diff --git a/front/document.send.php b/front/document.send.php index 79cbd20..32b084a 100644 --- a/front/document.send.php +++ b/front/document.send.php @@ -2,67 +2,51 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode + Barcode - Plugin para GLPI - Migrado a GLPI 11.x por Dawing S.A.S. ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ + */ - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 +include('../../../inc/includes.php'); - ------------------------------------------------------------------------ - */ +Session::checkRight('config', UPDATE); -include ('../../../inc/includes.php'); +if (!isset($_GET['file'])) { + http_response_code(400); + exit; +} + +$requestedFile = $_GET['file']; -if (!$CFG_GLPI["use_public_faq"]) { - Session::checkLoginUser(); +// Validación de seguridad: solo permitir acceso a barcode/logo.png +if ($requestedFile !== 'barcode/logo.png') { + Toolbox::logWarning( + "[Plugin barcode][security][document.send] Intento de acceso no permitido: " . $requestedFile + ); + http_response_code(403); + exit; } -$doc = new Document; +$filePath = GLPI_PLUGIN_DOC_DIR . '/' . $requestedFile; -if (isset($_GET["file"])) { // for other file - $splitter = explode("/", $_GET["file"]); - if (count($splitter) == 2) { - $send = false; +if (!file_exists($filePath)) { + http_response_code(404); + exit; +} - if ($splitter[0] == "barcode") { - $send = true; - } +// Detectar tipo MIME real +$finfo = finfo_open(FILEINFO_MIME_TYPE); +$mimeType = finfo_file($finfo, $filePath); +finfo_close($finfo); - if (file_exists(GLPI_PLUGIN_DOC_DIR."/".$_GET["file"])) { - Toolbox::sendFile(GLPI_PLUGIN_DOC_DIR."/".$_GET["file"], $splitter[1]); - } else { - Html::displayErrorAndDie(__('Unauthorized access to this file'), true); - } - } else { - Html::displayErrorAndDie(__('Invalid Filename'), true); - } +// Solo servir imágenes +if (!in_array($mimeType, ['image/png', 'image/jpeg', 'image/gif'])) { + http_response_code(403); + exit; } +header('Content-Type: ' . $mimeType); +header('Content-Length: ' . filesize($filePath)); +header('Cache-Control: max-age=3600, public'); +readfile($filePath); diff --git a/front/send.php b/front/send.php index 937c971..5fd528f 100644 --- a/front/send.php +++ b/front/send.php @@ -2,85 +2,59 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode + Barcode - Plugin para GLPI - Migrado a GLPI 11.x por Dawing S.A.S. ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - - ------------------------------------------------------------------------ - - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ */ -include ('../../../inc/includes.php'); +include('../../../inc/includes.php'); -if (!defined("GLPI_PLUGIN_DOC_DIR")) { - define("GLPI_PLUGIN_DOC_DIR", GLPI_ROOT . "/files/_plugins"); +Session::checkRight('plugin_barcode_barcode', CREATE); + +if (!isset($_GET['file'])) { + Html::displayErrorAndDie(__('No file specified.', 'barcode'), true); } -$docDir = GLPI_PLUGIN_DOC_DIR.'/barcode'; -if (isset($_GET['file'])) { - $filename = $_GET['file']; +$docDir = GLPI_PLUGIN_DOC_DIR . '/barcode'; +$filename = $_GET['file']; + +// Validación de seguridad: evitar path traversal +if (strpos($filename, '../') !== false || strpos($filename, '..\\') !== false) { + Toolbox::logWarning( + "[Plugin barcode][security][sendfile] " . + ($_SESSION['glpiname'] ?? 'unknown') . + " intentó acceder a un archivo fuera del directorio permitido: " . $filename + ); + Html::displayErrorAndDie(__('Security error.', 'barcode'), true); +} - // Security test : document in $docDir - if (strstr($filename, "../") || strstr($filename, "..\\")) { - echo "Security attack !!!"; - Toolbox::logDebug("[Plugin barcode][security][sendfile] ". - $_SESSION["glpiname"]." try to get a non standard file : ".$filename); - exit; - } +// Solo permitir archivos PDF (los generados por el plugin) +if (!preg_match('/^[a-zA-Z0-9_\-]+\.(pdf)$/', $filename)) { + Html::displayErrorAndDie(__('Invalid file name.', 'barcode'), true); +} - $file = $docDir.'/'.$filename; - if (!file_exists($file)) { - echo "Error file $filename does not exist"; //TODO : traduire - } else { - // Now send the file with header() magic - header("Expires: Mon, 26 Nov 1962 00:00:00 GMT"); - header('Pragma: private'); /// IE BUG + SSL - //header('Pragma: no-cache'); - header('Cache-control: private, must-revalidate'); /// IE BUG + SSL - header("Content-disposition: filename=\"$filename\""); - header("Content-type: application/pdf"); +$file = $docDir . '/' . $filename; - $f=fopen($file, "r"); +if (!file_exists($file)) { + Html::displayErrorAndDie(sprintf(__('File %s does not exist.', 'barcode'), $filename), true); +} - if (!$f) { - echo "Error opening file $filename"; - } else { - $fsize=filesize($file); +// Enviar el archivo PDF al navegador +header("Expires: Mon, 26 Nov 1962 00:00:00 GMT"); +header('Pragma: private'); +header('Cache-control: private, must-revalidate'); +header('Content-disposition: attachment; filename="' . $filename . '"'); +header('Content-type: application/pdf'); +header('Content-Length: ' . filesize($file)); + +$f = fopen($file, 'r'); +if (!$f) { + Html::displayErrorAndDie(__('Error opening file.', 'barcode'), true); +} - if ($fsize) { - echo fread($f, filesize($file)); - } else { - echo 'error'; - } - } - } +$fsize = filesize($file); +if ($fsize > 0) { + echo fread($f, $fsize); } +fclose($f); diff --git a/hook.php b/hook.php index 2170550..69d4019 100644 --- a/hook.php +++ b/hook.php @@ -2,63 +2,36 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode + Barcode - Plugin para GLPI + Migrado a GLPI 11.x por Dawing S.A.S. + Original: Copyright (C) 2009-2016 by the Barcode plugin Development Team. ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - - ------------------------------------------------------------------------ - - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ */ -// Define actions : +/** + * Define las acciones masivas disponibles por tipo de objeto + */ function plugin_barcode_MassiveActions($itemtype) { $generate_barcode_action = 'PluginBarcodeBarcode' . MassiveAction::CLASS_ACTION_SEPARATOR . 'Generate'; - $generate_barcode_label = ' ' . __('Barcode', 'barcode')." - ".__('Print barcodes', 'barcode'); + $generate_barcode_label = ' ' . __('Barcode', 'barcode') . " - " . __('Print barcodes', 'barcode'); $generate_qrcode_action = 'PluginBarcodeQRcode' . MassiveAction::CLASS_ACTION_SEPARATOR . 'Generate'; - $generate_qrcode_label = ' ' . __('Barcode', 'barcode')." - ".__('Print QRcodes', 'barcode'); + $generate_qrcode_label = ' ' . __('Barcode', 'barcode') . " - " . __('Print QRcodes', 'barcode'); if (!is_a($itemtype, CommonDBTM::class, true)) { return []; } + // QR code siempre disponible (contiene campo ID) $actions = [ - // QR code is always available as it contains ID field value $generate_qrcode_action => $generate_qrcode_label, ]; if (is_a($itemtype, CommonITILObject::class, true)) { - // CommonITILObject specific case, barcode is generated based on ticket ID + // Para objetos ITIL, el barcode se genera con el ID del ticket $actions[$generate_barcode_action] = $generate_barcode_label; } @@ -67,7 +40,7 @@ function plugin_barcode_MassiveActions($itemtype) { $item->getEmpty(); if (array_key_exists('otherserial', $item->fields)) { - // Barcode is based on otherserial field value + // Barcode basado en número de inventario (otherserial) $actions[$generate_barcode_action] = $generate_barcode_label; } @@ -75,145 +48,151 @@ function plugin_barcode_MassiveActions($itemtype) { } - -// Install process for plugin : need to return true if succeeded +/** + * Instalación del plugin - debe retornar true si fue exitoso + */ function plugin_barcode_install() { global $DB; $migration = new Migration(PLUGIN_BARCODE_VERSION); - $default_charset = DBConnection::getDefaultCharset(); + // Obtener charset y collation por defecto (API GLPI 11) + $default_charset = DBConnection::getDefaultCharset(); $default_collation = DBConnection::getDefaultCollation(); - if (!file_exists(GLPI_PLUGIN_DOC_DIR."/barcode")) { - mkdir(GLPI_PLUGIN_DOC_DIR."/barcode"); + // Crear directorio de documentos del plugin si no existe + if (!file_exists(GLPI_PLUGIN_DOC_DIR . "/barcode")) { + @mkdir(GLPI_PLUGIN_DOC_DIR . "/barcode", 0750, true); } + + // Renombrar tabla legacy si existe $migration->renameTable("glpi_plugin_barcode_config", "glpi_plugin_barcode_configs"); + + // Crear tabla de configuración general si no existe if (!$DB->tableExists("glpi_plugin_barcode_configs")) { $query = "CREATE TABLE `glpi_plugin_barcode_configs` ( - `id` int NOT NULL auto_increment, - `type` varchar(20) default NULL, - PRIMARY KEY (`ID`) - ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->query($query) or die("error creating glpi_plugin_barcode_configs ". $DB->error()); - - $query = "INSERT INTO `glpi_plugin_barcode_configs` - (`id`, `type`) - VALUES - ('1', 'code128')"; - $DB->query($query) or die("error populate glpi_plugin_barcode_configs ". $DB->error()); + `id` int NOT NULL AUTO_INCREMENT, + `type` varchar(20) DEFAULT NULL, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB + DEFAULT CHARSET={$default_charset} + COLLATE={$default_collation} + ROW_FORMAT=DYNAMIC;"; + $DB->doQueryOrDie($query, "Error al crear glpi_plugin_barcode_configs"); + + $DB->doQueryOrDie( + "INSERT INTO `glpi_plugin_barcode_configs` (`id`, `type`) VALUES (1, 'code128')", + "Error al poblar glpi_plugin_barcode_configs" + ); } + // Renombrar tabla de tipos legacy si existe $migration->renameTable("glpi_plugin_barcode_config_type", "glpi_plugin_barcode_configs_types"); + + // Crear tabla de configuración por tipo si no existe if (!$DB->tableExists("glpi_plugin_barcode_configs_types")) { $query = "CREATE TABLE `glpi_plugin_barcode_configs_types` ( - `id` int NOT NULL auto_increment, - `type` varchar(20) default NULL, - `size` varchar(20) default NULL, - `orientation` varchar(9) default NULL, - `marginTop` int NULL, - `marginBottom` int NULL, - `marginLeft` int NULL, - `marginRight` int NULL, - `marginHorizontal` int NULL, - `marginVertical` int NULL, - `maxCodeWidth` int NULL, - `maxCodeHeight` int NULL, - `txtSize` int NULL, - `txtSpacing` int NULL, - PRIMARY KEY (`ID`), - UNIQUE (`type`) - ) ENGINE=InnoDB DEFAULT CHARSET={$default_charset} COLLATE={$default_collation} ROW_FORMAT=DYNAMIC;"; - $DB->query($query) or die("error creating glpi_plugin_barcode_configs_types ". $DB->error()); - - $query = "INSERT INTO `glpi_plugin_barcode_configs_types` - (`type`, `size`, `orientation`, - `marginTop`, `marginBottom`, `marginLeft`, `marginRight`, - `marginHorizontal`, `marginVertical`, `maxCodeWidth`, `maxCodeHeight`, `txtSize`, `txtSpacing`) - VALUES - ('Code39', 'A4', 'Portrait', - '30', '30', '30', '30', - '25', '30', '128', '50', - '8','3'), - ('code128', 'A4', 'Portrait', - '30', '30', '30', '30', - '25', '30', '110', '70', - '8','3'), - ('ean13', 'A4', 'Portrait', - '30', '30', '30', '30', - '25', '30', '110', '70', - '8','3'), - ('int25', 'A4', 'Portrait', - '30', '30', '30', '30', - '25', '30', '110', '70', - '8','3'), - ('postnet', 'A4', 'Portrait', - '30', '30', '30', '30', - '25', '30', '110', '70', - '8','3'), - ('upca', 'A4', 'Portrait', - '30', '30', '30', '30', - '25', '30', '110', '70', - '8','3'), - ('QRcode', 'A4', 'Portrait', - '30', '30', '30', '30', - '25', '30', '110', '100', - '8','3')"; - $DB->query($query) or die("error populate glpi_plugin_barcode_configs_types ". $DB->error()); + `id` int NOT NULL AUTO_INCREMENT, + `type` varchar(20) DEFAULT NULL, + `size` varchar(20) DEFAULT NULL, + `orientation` varchar(9) DEFAULT NULL, + `marginTop` int DEFAULT NULL, + `marginBottom` int DEFAULT NULL, + `marginLeft` int DEFAULT NULL, + `marginRight` int DEFAULT NULL, + `marginHorizontal` int DEFAULT NULL, + `marginVertical` int DEFAULT NULL, + `maxCodeWidth` int DEFAULT NULL, + `maxCodeHeight` int DEFAULT NULL, + `txtSize` int DEFAULT NULL, + `txtSpacing` int DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `type` (`type`) + ) ENGINE=InnoDB + DEFAULT CHARSET={$default_charset} + COLLATE={$default_collation} + ROW_FORMAT=DYNAMIC;"; + $DB->doQueryOrDie($query, "Error al crear glpi_plugin_barcode_configs_types"); + + $insert_query = "INSERT INTO `glpi_plugin_barcode_configs_types` + (`type`, `size`, `orientation`, + `marginTop`, `marginBottom`, `marginLeft`, `marginRight`, + `marginHorizontal`, `marginVertical`, + `maxCodeWidth`, `maxCodeHeight`, + `txtSize`, `txtSpacing`) + VALUES + ('Code39', 'A4', 'Portrait', 30, 30, 30, 30, 25, 30, 128, 50, 8, 3), + ('code128', 'A4', 'Portrait', 30, 30, 30, 30, 25, 30, 110, 70, 8, 3), + ('ean13', 'A4', 'Portrait', 30, 30, 30, 30, 25, 30, 110, 70, 8, 3), + ('int25', 'A4', 'Portrait', 30, 30, 30, 30, 25, 30, 110, 70, 8, 3), + ('postnet', 'A4', 'Portrait', 30, 30, 30, 30, 25, 30, 110, 70, 8, 3), + ('upca', 'A4', 'Portrait', 30, 30, 30, 30, 25, 30, 110, 70, 8, 3), + ('QRcode', 'A4', 'Portrait', 30, 30, 30, 30, 25, 30, 110, 100, 8, 3)"; + $DB->doQueryOrDie($insert_query, "Error al poblar glpi_plugin_barcode_configs_types"); } + // Agregar campos faltantes si la tabla ya existía sin ellos (migración de versión anterior) if ($DB->tableExists("glpi_plugin_barcode_configs_types") && !$DB->fieldExists("glpi_plugin_barcode_configs_types", "txtSize") - && !$DB->fieldExists("glpi_plugin_barcode_configs_types", "txtSpacing") - ) { - $migration->addField("glpi_plugin_barcode_configs_types", "txtSize", "integer"); + && !$DB->fieldExists("glpi_plugin_barcode_configs_types", "txtSpacing")) { + $migration->addField("glpi_plugin_barcode_configs_types", "txtSize", "integer"); $migration->addField("glpi_plugin_barcode_configs_types", "txtSpacing", "integer"); $migration->executeMigration(); } + // Insertar configuración de QRcode si no existe if (!countElementsInTable("glpi_plugin_barcode_configs_types", ['type' => 'QRcode'])) { - $query = "INSERT INTO `glpi_plugin_barcode_configs_types` - (`type`, `size`, `orientation`, - `marginTop`, `marginBottom`, `marginLeft`, `marginRight`, - `marginHorizontal`, `marginVertical`, `maxCodeWidth`, `maxCodeHeight`,`txtSize`, `txtSpacing`) - VALUES - ('QRcode', 'A4', 'Portrait', - '30', '30', '30', '30', - '25', '30', '110', '100', - '8','3')"; - $DB->query($query) or die("error populate glpi_plugin_barcode_configs_types ". $DB->error()); + $DB->doQueryOrDie( + "INSERT INTO `glpi_plugin_barcode_configs_types` + (`type`, `size`, `orientation`, + `marginTop`, `marginBottom`, `marginLeft`, `marginRight`, + `marginHorizontal`, `marginVertical`, + `maxCodeWidth`, `maxCodeHeight`, `txtSize`, `txtSpacing`) + VALUES + ('QRcode', 'A4', 'Portrait', 30, 30, 30, 30, 25, 30, 110, 100, 8, 3)", + "Error al insertar configuración QRcode" + ); } - include_once Plugin::getPhpDir('barcode').'/inc/profile.class.php'; - include_once Plugin::getPhpDir('barcode').'/inc/config.class.php'; + // Inicializar perfiles de derechos + include_once Plugin::getPhpDir('barcode') . '/inc/profile.class.php'; + include_once Plugin::getPhpDir('barcode') . '/inc/config.class.php'; PluginBarcodeProfile::initProfile(); + + // Eliminar tabla de perfiles legacy si existe if ($DB->tableExists("glpi_plugin_barcode_profiles")) { - $query = "DROP TABLE `glpi_plugin_barcode_profiles`"; - $DB->query($query) or die("error deleting glpi_plugin_barcode_profiles"); + $DB->doQueryOrDie( + "DROP TABLE `glpi_plugin_barcode_profiles`", + "Error al eliminar glpi_plugin_barcode_profiles" + ); } + return true; } - -// Uninstall process for plugin : need to return true if succeeded +/** + * Desinstalación del plugin - debe retornar true si fue exitoso + */ function plugin_barcode_uninstall() { global $DB; - if ($DB->tableExists("glpi_plugin_barcode_configs")) { - $query = "DROP TABLE `glpi_plugin_barcode_configs`"; - $DB->query($query) or die("error deleting glpi_plugin_barcode_configs"); - } - if ($DB->tableExists("glpi_plugin_barcode_configs_types")) { - $query = "DROP TABLE `glpi_plugin_barcode_configs_types`"; - $DB->query($query) or die("error deleting glpi_plugin_barcode_configs_types"); - } - if ($DB->tableExists("glpi_plugin_barcode_profiles")) { - $query = "DROP TABLE `glpi_plugin_barcode_profiles`"; - $DB->query($query) or die("error deleting glpi_plugin_barcode_profiles"); + $tables = [ + 'glpi_plugin_barcode_configs', + 'glpi_plugin_barcode_configs_types', + 'glpi_plugin_barcode_profiles', + ]; + + foreach ($tables as $table) { + if ($DB->tableExists($table)) { + $DB->doQueryOrDie( + "DROP TABLE `{$table}`", + "Error al eliminar {$table}" + ); + } } - include_once Plugin::getPhpDir('barcode').'/inc/profile.class.php'; + include_once Plugin::getPhpDir('barcode') . '/inc/profile.class.php'; PluginBarcodeProfile::removeRights(); return true; diff --git a/inc/barcode.class.php b/inc/barcode.class.php index c599578..5730d45 100644 --- a/inc/barcode.class.php +++ b/inc/barcode.class.php @@ -2,196 +2,170 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode + Barcode - Plugin para GLPI + Migrado a GLPI 11.x por Dawing S.A.S. + Original: Copyright (C) 2009-2016 by the Barcode plugin Development Team. ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - - ------------------------------------------------------------------------ - - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ */ if (!defined('GLPI_ROOT')) { - die("Sorry. You can't access directly to this file"); + die("Sorry. You can't access directly to this file"); } /** - * Class to generate barcodes using PEAR Image_Barcode - **/ + * Clase principal para generar códigos de barras (tipos lineales) + * y exportar PDFs usando rospdf/Cezpdf + */ class PluginBarcodeBarcode { + + /** @var string Ruta al directorio de documentos del plugin */ private $docsPath; static $rightname = 'plugin_barcode_barcode'; - /** - * Constructor - **/ + * Constructor + */ function __construct() { - $this->docsPath = GLPI_PLUGIN_DOC_DIR.'/barcode/'; + $this->docsPath = GLPI_PLUGIN_DOC_DIR . '/barcode/'; } - - + /** + * Retorna la lista de tipos de código disponibles + * + * @return array + */ function getCodeTypes() { - $types = ['Code39', 'code128', 'ean13', 'int25', 'postnet', 'upca', - 'QRcode' - ]; - return $types; + return ['Code39', 'code128', 'ean13', 'int25', 'postnet', 'upca', 'QRcode']; } - - + /** + * Muestra un selector de tamaño de página + * + * @param string|null $p_size Valor por defecto + */ function showSizeSelect($p_size = null) { - //TODO : utiliser fonction du coeur - - Dropdown::showFromArray("size", - ['4A0' => __('4A0', 'barcode'), - '2A0' => __('2A0', 'barcode'), - 'A0' => __('A0', 'barcode'), - 'A1' => __('A1', 'barcode'), - 'A2' => __('A2', 'barcode'), - 'A3' => __('A3', 'barcode'), - 'A4' => __('A4', 'barcode'), - 'A5' => __('A5', 'barcode'), - 'A6' => __('A6', 'barcode'), - 'A7' => __('A7', 'barcode'), - 'A8' => __('A8', 'barcode'), - 'A9' => __('A9', 'barcode'), - 'A10' => __('A10', 'barcode'), - 'B0' => __('B0', 'barcode'), - 'B1' => __('B1', 'barcode'), - 'B2' => __('B2', 'barcode'), - 'B3' => __('B3', 'barcode'), - 'B4' => __('B4', 'barcode'), - 'B5' => __('B5', 'barcode'), - 'B6' => __('B6', 'barcode'), - 'B7' => __('B7', 'barcode'), - 'B8' => __('B8', 'barcode'), - 'B9' => __('B9', 'barcode'), - 'B10' => __('B10', 'barcode'), - 'C0' => __('C0', 'barcode'), - 'C1' => __('C1', 'barcode'), - 'C2' => __('C2', 'barcode'), - 'C3' => __('C3', 'barcode'), - 'C4' => __('C4', 'barcode'), - 'C5' => __('C5', 'barcode'), - 'C6' => __('C6', 'barcode'), - 'C7' => __('C7', 'barcode'), - 'C8' => __('C8', 'barcode'), - 'C9' => __('C9', 'barcode'), - 'C10' => __('C10', 'barcode'), - 'RA0' => __('RA0', 'barcode'), - 'RA1' => __('RA1', 'barcode'), - 'RA2' => __('RA2', 'barcode'), - 'RA3' => __('RA3', 'barcode'), - 'RA4' => __('RA4', 'barcode'), - 'SRA0' => __('SRA0', 'barcode'), - 'SRA1' => __('SRA1', 'barcode'), - 'SRA2' => __('SRA2', 'barcode'), - 'SRA3' => __('SRA3', 'barcode'), - 'SRA4' => __('SRA4', 'barcode'), - 'LETTER' => __('LETTER', 'barcode'), - 'LEGAL' => __('LEGAL', 'barcode'), - 'EXECUTIVE' => __('EXECUTIVE', 'barcode'), - 'FOLIO' => __('FOLIO', 'barcode')], - (is_null($p_size)?['width' => '100']:['value' => $p_size, 'width' => '100'])); + $sizes = [ + '4A0' => '4A0', '2A0' => '2A0', + 'A0' => 'A0', 'A1' => 'A1', 'A2' => 'A2', + 'A3' => 'A3', 'A4' => 'A4', 'A5' => 'A5', + 'A6' => 'A6', 'A7' => 'A7', 'A8' => 'A8', + 'A9' => 'A9', 'A10' => 'A10', + 'B0' => 'B0', 'B1' => 'B1', 'B2' => 'B2', + 'B3' => 'B3', 'B4' => 'B4', 'B5' => 'B5', + 'B6' => 'B6', 'B7' => 'B7', 'B8' => 'B8', + 'B9' => 'B9', 'B10' => 'B10', + 'C0' => 'C0', 'C1' => 'C1', 'C2' => 'C2', + 'C3' => 'C3', 'C4' => 'C4', 'C5' => 'C5', + 'C6' => 'C6', 'C7' => 'C7', 'C8' => 'C8', + 'C9' => 'C9', 'C10' => 'C10', + 'RA0' => 'RA0', 'RA1' => 'RA1', 'RA2' => 'RA2', + 'RA3' => 'RA3', 'RA4' => 'RA4', + 'SRA0' => 'SRA0', 'SRA1' => 'SRA1', 'SRA2' => 'SRA2', + 'SRA3' => 'SRA3', 'SRA4' => 'SRA4', + 'LETTER' => 'LETTER', + 'LEGAL' => 'LEGAL', + 'EXECUTIVE' => 'EXECUTIVE', + 'FOLIO' => 'FOLIO', + ]; + + $opts = ['width' => '100']; + if (!is_null($p_size)) { + $opts['value'] = $p_size; + } + Dropdown::showFromArray("size", $sizes, $opts); } - - + /** + * Muestra un selector de orientación de página + * + * @param string|null $p_orientation Valor por defecto + */ function showOrientationSelect($p_orientation = null) { - //TODO : utiliser fonction du coeur - - Dropdown::showFromArray("orientation", - ['Portrait' => __('Portrait', 'barcode'), - 'Landscape' => __('Landscape', 'barcode')], - (is_null($p_orientation)?['width' => '100']:['value' => $p_orientation, 'width' => '100'])); + $opts = ['width' => '100']; + if (!is_null($p_orientation)) { + $opts['value'] = $p_orientation; + } + Dropdown::showFromArray( + "orientation", + [ + 'Portrait' => __('Portrait', 'barcode'), + 'Landscape' => __('Landscape', 'barcode'), + ], + $opts + ); } - - + /** + * Muestra el formulario de generación de un código de barras individual + * + * @param string $p_type Tipo de objeto GLPI (ej: 'Computer') + * @param int $p_ID ID del objeto + */ function showForm($p_type, $p_ID) { - global $CFG_GLPI; - $config = $this->getConfigType(); - $ci = new $p_type(); + $pbConfig = new PluginBarcodeConfig(); + $config = $pbConfig->getConfigType(); + $ci = new $p_type(); $ci->getFromDB($p_ID); - if ($ci->isField('otherserial')) { - $code = $ci->getField('otherserial'); - } else { - $code = ''; - } - echo ""; - echo "
"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo "
".__('Generation', 'barcode')."
".__('Code', 'barcode').""; - echo ""; - echo "".__('Type', 'barcode').""; - $this->showTypeSelect($config['type']); - echo "
".__('Page size', 'barcode').""; - $this->showSizeSelect($config['size']); - echo "".__('Orientation', 'barcode').""; - $this->showOrientationSelect($config['orientation']); - echo "
".__('Number of copies', 'barcode')."
-
"; - echo "
"; - Html::closeForm(); - } - + // Intentar obtener el número de inventario (otherserial) + $code = ($ci->isField('otherserial')) ? $ci->getField('otherserial') : ''; + + // Ruta compatible con GLPI 11 + $action_url = '/plugins/barcode/front/barcode.form.php'; + + echo ""; + echo "
"; + echo ""; + echo ""; + + echo ""; + echo ""; + echo ""; + echo ""; + + echo ""; + echo ""; + echo ""; + echo ""; + + echo ""; + echo ""; + echo ""; + echo ""; + echo ""; + + echo ""; + echo "
" . __('Generation', 'barcode') . "
" . __('Code', 'barcode') . ""; + echo ""; + echo "" . __('Type', 'barcode') . ""; + $pbConfig->showTypeSelect($config['type']); + echo "
" . __('Page size', 'barcode') . ""; + $this->showSizeSelect($config['size']); + echo "" . __('Orientation', 'barcode') . ""; + $this->showOrientationSelect($config['orientation']); + echo "
" . __('Number of copies', 'barcode') . "
"; + echo Html::submit(__('Create', 'barcode'), ['name' => 'generate']); + echo "
"; + echo "
"; + Html::closeForm(); + } + /** + * Muestra el formulario de acción masiva para barcodes lineales + * + * @param MassiveAction $ma Objeto de acción masiva + */ function showFormMassiveAction(MassiveAction $ma) { $pbConfig = new PluginBarcodeConfig(); echo '
'; echo ''; - echo __('It will generate only elements have defined field:', 'barcode').' '; + echo __('It will generate only elements have defined field:', 'barcode') . ' '; if (key($ma->items) == 'Ticket') { echo __('Ticket number', 'barcode'); } else { @@ -202,8 +176,8 @@ function showFormMassiveAction(MassiveAction $ma) { echo ''; echo ''; $config = $pbConfig->getConfigType(); - echo __('Type', 'barcode')." : "; - $pbConfig->showTypeSelect($config['type'], ['QRcode' => 'QRcode']); + echo __('Type', 'barcode') . " : "; + $pbConfig->showTypeSelect($config['type'], ['QRcode' => 'QRcode']); echo ''; echo ''; echo ''; @@ -212,8 +186,10 @@ function showFormMassiveAction(MassiveAction $ma) { PluginBarcodeBarcode::commonShowMassiveAction(); } - - + /** + * Muestra las opciones comunes de acción masiva (tamaño, orientación, opciones de display) + * Reutilizado tanto por Barcode como por QRcode + */ static function commonShowMassiveAction() { $pbBarcode = new PluginBarcodeBarcode(); @@ -223,52 +199,55 @@ static function commonShowMassiveAction() { echo ''; echo ''; echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; + echo ''; echo ''; echo ''; echo ''; echo ''; echo '
'; - echo "
".__('Page size', 'barcode')." :
"; - $pbBarcode->showSizeSelect($config['size']); + echo "
" . __('Page size', 'barcode') . " :
"; + $pbBarcode->showSizeSelect($config['size']); echo ''; - echo __('Not use first xx barcodes', 'barcode')." : "; - Dropdown::showNumber("eliminate", ['width'=>'100']); + echo __('Not use first xx barcodes', 'barcode') . " : "; + Dropdown::showNumber("eliminate", ['width' => '100']); echo '
'; - echo "
".__('Orientation', 'barcode')." :
"; - $pbBarcode->showOrientationSelect($config['orientation']); + echo "
" . __('Orientation', 'barcode') . " :
"; + $pbBarcode->showOrientationSelect($config['orientation']); echo ''; - echo __('Display border', 'barcode')." : "; + echo __('Display border', 'barcode') . " : "; Dropdown::showYesNo("border", 1, -1, ['width' => '100']); echo '
  '; - echo __('Display labels', 'barcode')." : "; + echo __('Display labels', 'barcode') . " : "; Dropdown::showYesNo("displaylabels", 0, -1, ['width' => '100']); echo '
'; echo '
'; - //echo "
"; echo "
"; - echo Html::submit(__('Create', 'barcode'), ['value' => 'create']); + echo Html::submit(__('Create', 'barcode'), ['name' => 'massiveaction']); } - - + /** + * Genera el PDF con los códigos de barras y retorna la ruta relativa del archivo + * + * @param array $p_params Parámetros: type, size, orientation, codes, nb, border, displaylabels, displayData + * @return string|int Ruta relativa del PDF generado, o 0 si falla + */ function printPDF($p_params) { - $pbConfig = new PluginBarcodeConfig(); - - // create barcodes - $ext = 'png'; - $type = $p_params['type']; - $size = $p_params['size']; + $pbConfig = new PluginBarcodeConfig(); + $ext = 'png'; + $type = $p_params['type']; + $size = $p_params['size']; $orientation = $p_params['orientation']; - $codes = []; + $codes = []; $displayDataCollection = $p_params['displayData'] ?? []; @@ -276,63 +255,76 @@ function printPDF($p_params) { $codes = $p_params['codes']; } else { if (isset($p_params['code'])) { - if (isset($p_params['nb']) AND $p_params['nb']>1) { + $nb = isset($p_params['nb']) ? (int)$p_params['nb'] : 1; + if ($nb > 1) { $this->create($p_params['code'], $type, $ext); - for ($i=1; $i<=$p_params['nb']; $i++) { + for ($i = 1; $i <= $nb; $i++) { $codes[] = $p_params['code']; } } else { if (!$this->create($p_params['code'], $type, $ext)) { - Session::addMessageAfterRedirect(__('The generation of some barcodes produced errors.', 'barcode')); + Session::addMessageAfterRedirect( + __('The generation of some barcodes produced errors.', 'barcode') + ); } $codes[] = $p_params['code']; } - } else if (isset($p_params['codes'])) { + } elseif (isset($p_params['codes'])) { $codes = $p_params['codes']; foreach ($codes as $code) { - if ($code != '') { + if ($code !== '') { $this->create($code, $type, $ext); } } } else { - // TODO : erreur ? - // print_r($p_params); return 0; } } - // create pdf - // x is horizontal axis and y is vertical - // x=0 and y=0 in bottom left hand corner - $config = $pbConfig->getConfigType($type); - - $pdf= new Cezpdf($size, $orientation); - $pdf->tempPath = GLPI_TMP_DIR; - $pdf->selectFont(Plugin::getPhpDir('barcode')."/lib/ezpdf/fonts/Helvetica.afm"); - $pdf->ezSetMargins($config['marginTop'], $config['marginBottom'], $config['marginLeft'], $config['marginRight']); - $pdf->ezStartPageNumbers($pdf->ez['pageWidth']-30, 10, 10, 'left', '{PAGENUM} / {TOTALPAGENUM}'). - $width = $config['maxCodeWidth']; - $height = $config['maxCodeHeight']; - $marginH = $config['marginHorizontal']; - $marginV = $config['marginVertical']; - $txtSize = $config['txtSize']; + // Obtener configuración dimensional del tipo + $config = $pbConfig->getConfigType($type); + $width = $config['maxCodeWidth']; + $height = $config['maxCodeHeight']; + $marginH = $config['marginHorizontal']; + $marginV = $config['marginVertical']; + $txtSize = $config['txtSize']; $txtSpacing = $config['txtSpacing']; + // Crear el PDF con Cezpdf (rospdf/pdf-php) + $pdf = new Cezpdf($size, $orientation); + $pdf->tempPath = GLPI_TMP_DIR; + $pdf->selectFont(Plugin::getPhpDir('barcode') . "/lib/ezpdf/fonts/Helvetica.afm"); + $pdf->ezSetMargins( + $config['marginTop'], + $config['marginBottom'], + $config['marginLeft'], + $config['marginRight'] + ); + $pdf->ezStartPageNumbers( + $pdf->ez['pageWidth'] - 30, + 10, 10, 'left', + '{PAGENUM} / {TOTALPAGENUM}' + ); + + // Detectar si hay logo y calcular alturas $heightimage = $height; + $logoWidth = 0; + $logoHeight = 0; + $heightyposText = $height; - if (file_exists(GLPI_PLUGIN_DOC_DIR.'/barcode/logo.png')) { - // Add logo to barcode + if (file_exists(GLPI_PLUGIN_DOC_DIR . '/barcode/logo.png')) { $heightLogomax = 20; - $imgSize = getimagesize(GLPI_PLUGIN_DOC_DIR.'/barcode/logo.png'); + $imgSize = getimagesize(GLPI_PLUGIN_DOC_DIR . '/barcode/logo.png'); $logoWidth = $imgSize[0]; $logoHeight = $imgSize[1]; + if ($logoHeight > $heightLogomax) { - $ratio = (100 * $heightLogomax ) / $logoHeight; + $ratio = (100 * $heightLogomax) / $logoHeight; $logoHeight = $heightLogomax; $logoWidth = $logoWidth * ($ratio / 100); } if ($logoWidth > $width) { - $ratio = (100 * $width ) / $logoWidth; + $ratio = (100 * $width) / $logoWidth; $logoWidth = $width; $logoHeight = $logoHeight * ($ratio / 100); } @@ -340,18 +332,23 @@ function printPDF($p_params) { $heightimage = $heightyposText; } - $first=true; - for ($ia = 0; $ia < count($codes); $ia++) { - $code = $codes[$ia]; + // Posicionamiento y renderizado de cada código + $first = true; + $count = count($codes); + for ($ia = 0; $ia < $count; $ia++) { + $code = $codes[$ia]; $displayData = $displayDataCollection[$ia] ?? []; + if ($first) { - $x = $pdf->ez['leftMargin']; - $y = $pdf->ez['pageHeight'] - $pdf->ez['topMargin'] - $height; + $x = $pdf->ez['leftMargin']; + $y = $pdf->ez['pageHeight'] - $pdf->ez['topMargin'] - $height; $first = false; } else { - if ($x + $width + $marginH > $pdf->ez['pageWidth']) { // new line + if ($x + $width + $marginH > $pdf->ez['pageWidth']) { + // Nueva fila $x = $pdf->ez['leftMargin']; - if ($y - $height - $marginV < $pdf->ez['bottomMargin']) { // new page + if ($y - $height - $marginV < $pdf->ez['bottomMargin']) { + // Nueva página $pdf->ezNewPage(); $y = $pdf->ez['pageHeight'] - $pdf->ez['topMargin'] - $height; } else { @@ -359,168 +356,194 @@ function printPDF($p_params) { } } } - if ($code != '') { - if ($type == 'QRcode') { - $imgFile = $code; - } else { - $imgFile = $this->docsPath.$code.'_'.$type.'.'.$ext; - } + + if ($code !== '') { + $imgFile = ($type == 'QRcode') + ? $code + : $this->docsPath . $code . '_' . $type . '.' . $ext; + if (file_exists($imgFile)) { $imgSize = getimagesize($imgFile); $imgWidth = $imgSize[0]; $imgHeight = $imgSize[1]; + + // Escalar manteniendo proporciones if ($imgWidth > $width) { - $ratio = (100 * $width ) / $imgWidth; + $ratio = (100 * $width) / $imgWidth; $imgWidth = $width; $imgHeight = $imgHeight * ($ratio / 100); } if ($imgHeight > $heightimage) { - $ratio = (100 * $heightimage ) / $imgHeight; + $ratio = (100 * $heightimage) / $imgHeight; $imgHeight = $heightimage; $imgWidth = $imgWidth * ($ratio / 100); } $image = imagecreatefrompng($imgFile); - if ($imgWidth < $width) { - $pdf->addImage($image, - $x + (($width - $imgWidth) / 2), - $y, - $imgWidth, - $imgHeight); - } else { - $pdf->addImage($image, - $x, - $y, - $imgWidth, - $imgHeight); - } - if (file_exists(GLPI_PLUGIN_DOC_DIR.'/barcode/logo.png')) { - $logoimg = imagecreatefrompng(GLPI_PLUGIN_DOC_DIR.'/barcode/logo.png'); - $pdf->addImage($logoimg, - $x + (($width - $logoWidth) / 2), - $y + $heightyposText, - $logoWidth, - $logoHeight); + $xOffset = ($imgWidth < $width) ? $x + (($width - $imgWidth) / 2) : $x; + $pdf->addImage($image, $xOffset, $y, $imgWidth, $imgHeight); + + // Agregar logo si existe + if (file_exists(GLPI_PLUGIN_DOC_DIR . '/barcode/logo.png')) { + $logoimg = imagecreatefrompng(GLPI_PLUGIN_DOC_DIR . '/barcode/logo.png'); + $pdf->addImage( + $logoimg, + $x + (($width - $logoWidth) / 2), + $y + $heightyposText, + $logoWidth, + $logoHeight + ); } + + // Agregar texto bajo el código $txtHeight = 0; - for ($i = 0; $i < count($displayData); $i++) { - $pdf->addTextWrap( - $x, - $y - ($txtSpacing + $txtHeight), - $txtSize, - $displayData[$i], - $width, - 'center'); - $txtHeight += $txtSpacing/2 + $txtSize; + $displayCount = is_array($displayData) ? count($displayData) : 0; + for ($i = 0; $i < $displayCount; $i++) { + $pdf->addTextWrap( + $x, + $y - ($txtSpacing + $txtHeight), + $txtSize, + $displayData[$i], + $width, + 'center' + ); + $txtHeight += $txtSpacing / 2 + $txtSize; } - if ($p_params['border']) { - $pdf->Rectangle($x, $y - ($txtHeight + $txtSpacing*2), - $width, $height + ($txtHeight + $txtSpacing*2)); + + // Dibujar borde si se solicitó + if (!empty($p_params['border'])) { + $pdf->Rectangle( + $x, + $y - ($txtHeight + $txtSpacing * 2), + $width, + $height + ($txtHeight + $txtSpacing * 2) + ); } } } + $x += $width + $marginH; - $y -= 0; } - $file = $pdf->ezOutput(); - $pdfFile = $_SESSION['glpiID'].'_'.$type.'.pdf'; - file_put_contents($this->docsPath.$pdfFile, $file); - return '/files/_plugins/barcode/'.$pdfFile; - } + // Guardar el PDF en disco + $file = $pdf->ezOutput(); + $pdfFile = $_SESSION['glpiID'] . '_' . $type . '.pdf'; + file_put_contents($this->docsPath . $pdfFile, $file); + return '/files/_plugins/barcode/' . $pdfFile; + } + /** + * Genera la imagen PNG de un código de barras lineal + * + * @param string $p_code Valor a codificar + * @param string $p_type Tipo de código (Code39, code128, etc.) + * @param string $p_ext Extensión de la imagen (png) + * @return bool true si se generó correctamente + */ function create($p_code, $p_type, $p_ext) { - //TODO : filtre sur le type - if (!file_exists($this->docsPath.$p_code.'_'.$p_type.'.'.$p_ext)) { - ob_start(); - $barcode = new Image_Barcode(); - $resImg = @imagepng( - @$barcode->draw($p_code, $p_type, $p_ext, false) - ); - $img = ob_get_clean(); - file_put_contents($this->docsPath.$p_code.'_'.$p_type.'.'.$p_ext, $img); - if (!$resImg) { - return false; - } + $filePath = $this->docsPath . $p_code . '_' . $p_type . '.' . $p_ext; + + // Si ya existe en caché, no regenerar + if (file_exists($filePath)) { + return true; } - return true; - } + ob_start(); + $barcode = new Image_Barcode(); + $resImg = @imagepng( + @$barcode->draw($p_code, $p_type, $p_ext, false) + ); + $img = ob_get_clean(); + + file_put_contents($filePath, $img); + return $resImg !== false; + } + /** + * Retorna un array vacío (sin acciones masivas específicas en el item) + */ function getSpecificMassiveActions($checkitem = null) { return []; } - - /** - * @since version 0.85 + * Muestra el subformulario de la acción masiva * - * @see CommonDBTM::showMassiveActionsSubForm() - **/ + * @param MassiveAction $ma + * @return bool + */ static function showMassiveActionsSubForm(MassiveAction $ma) { switch ($ma->getAction()) { case 'Generate': $barcode = new self(); $barcode->showFormMassiveAction($ma); return true; - } return false; } - - - static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBTM $item, array $ids) { - global $CFG_GLPI; - + /** + * Procesa la acción masiva de generación de códigos de barras para cada item + * + * @param MassiveAction $ma + * @param CommonDBTM $item + * @param array $ids IDs de los items seleccionados + */ + static function processMassiveActionsForOneItemtype( + MassiveAction $ma, + CommonDBTM $item, + array $ids + ) { switch ($ma->getAction()) { - case 'Generate' : + case 'Generate': $pbQRcode = new PluginBarcodeQRcode(); $rand = mt_rand(); $number = 0; $codes = []; - if ($ma->POST['eliminate'] > 0) { - for ($nb=0; $nb < $ma->POST['eliminate']; $nb++) { - $codes[] = ''; - } + + // Agregar celdas vacías para desplazamiento si se solicitó + $eliminate = (int)($ma->POST['eliminate'] ?? 0); + for ($nb = 0; $nb < $eliminate; $nb++) { + $codes[] = ''; } + foreach ($ids as $key) { $item->getFromDB($key); - if (key($ma->items) == 'CommonITILObject') { - $codes[] = $item->getField('id'); - } else if ($item->isField('otherserial')) { + if (key($ma->items) === 'CommonITILObject' || is_a($item, CommonITILObject::class)) { + $codes[] = (string)$item->getField('id'); + } elseif ($item->isField('otherserial')) { $codes[] = $item->getField('otherserial'); } } + if (count($codes) > 0) { - $params['codes'] = $codes; - $params['type'] = $ma->POST['type']; - $params['size'] = $ma->POST['size']; - $params['border'] = $ma->POST['border']; - $params['orientation'] = $ma->POST['orientation']; - $params['displaylabels'] = $ma->POST['displaylabels']; + $params = [ + 'codes' => $codes, + 'type' => $ma->POST['type'], + 'size' => $ma->POST['size'], + 'border' => $ma->POST['border'], + 'orientation' => $ma->POST['orientation'], + 'displaylabels' => $ma->POST['displaylabels'], + ]; $barcode = new PluginBarcodeBarcode(); $file = $barcode->printPDF($params); $filePath = explode('/', $file); - $filename = $filePath[count($filePath)-1]; + $filename = end($filePath); - $msg = "".__('Generated file', 'barcode').""; + $msg = "" + . __('Generated file', 'barcode') . ""; Session::addMessageAfterRedirect($msg); $pbQRcode->cleanQRcodefiles($rand, $number); } + $ma->itemDone($item->getType(), 0, MassiveAction::ACTION_OK); return; - } - return; } - } diff --git a/inc/config.class.php b/inc/config.class.php index 2996bf1..a13e59a 100644 --- a/inc/config.class.php +++ b/inc/config.class.php @@ -2,128 +2,132 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode - ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - + Barcode - Plugin para GLPI + Migrado a GLPI 11.x por Dawing S.A.S. + Original: Copyright (C) 2009-2016 by the Barcode plugin Development Team. ------------------------------------------------------------------------ - - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ */ if (!defined('GLPI_ROOT')) { - die("Sorry. You can't access directly to this file"); + die("Sorry. You can't access directly to this file"); } class PluginBarcodeConfig extends CommonDBTM { static $rightname = 'plugin_barcode_config'; + /** + * Nombre del tipo + */ + static function getTypeName($nb = 0) { + return __('Barcode configuration', 'barcode'); + } + + /** + * Formulario de configuración general + configuración por tipo + * + * @param int $ID ID del registro (no usado actualmente) + * @param array $options Opciones adicionales + */ function showForm($ID, array $options = []) { - global $CFG_GLPI; $pbBarcode = new PluginBarcodeBarcode(); $defaultType = $this->getConfig(); + + // Ruta base del plugin compatible con GLPI 11 + $action_url = '/plugins/barcode/front/config.form.php'; + echo ""; echo "
"; echo ""; - echo ""; + echo ""; echo "
".__('Barcode plugin configuration', 'barcode')."
" . __('Barcode plugin configuration', 'barcode') . "

"; + // --- Configuración general --- echo ""; echo ""; - echo ""; + echo ""; echo ""; echo ""; - echo ""; + echo ""; echo ""; - echo ""; + echo ""; echo ""; echo ""; - echo ""; + echo ""; echo ""; + // --- Logo de empresa --- echo ""; - echo ""; + echo ""; echo ""; - if (file_exists(GLPI_PLUGIN_DOC_DIR.'/barcode/logo.png')) { + if (file_exists(GLPI_PLUGIN_DOC_DIR . '/barcode/logo.png')) { echo ""; echo ""; echo ""; echo ""; - echo ""; + echo ""; echo ""; } echo ""; echo ""; - echo ""; + echo ""; echo ""; echo "
".__('General configuration', 'barcode')."" . __('General configuration', 'barcode') . "
".__('Type', 'barcode')."" . __('Type', 'barcode') . ""; $this->showTypeSelect($defaultType); echo ""; + echo Html::submit(__('Save'), ['name' => 'update_type']); + echo "
"; + echo Html::submit(__('Empty the cache', 'barcode'), ['name' => 'dropCache']); + echo "
".__('Company logo', 'barcode')."" . __('Company logo', 'barcode') . "
"; - echo ""; echo "
"; + echo Html::submit(__('Delete the logo', 'barcode'), ['name' => 'dropLogo']); + echo "
"; + echo Html::submit(__('Save'), ['name' => 'upload_logo']); + echo "
"; echo "
"; Html::closeForm(); + // --- Formulario por cada tipo de código --- foreach ($pbBarcode->getCodeTypes() as $type) { echo '
'; $this->showFormConfigType($type); } } + /** + * Obtiene el tipo de código predeterminado desde la BD + * + * @return string Tipo de código (p.ej. 'code128') + */ function getConfig() { $pbconf = new PluginBarcodeConfig(); if ($pbconf->getFromDB(1)) { - $type = $pbconf->fields['type']; - } else { - $type = 'code128'; + return $pbconf->fields['type']; } - return $type; + return 'code128'; } - - + /** + * Formulario de configuración para un tipo específico de código + * + * @param string|null $p_type Tipo de código (Code39, code128, QRcode, etc.) + */ function showFormConfigType($p_type = null) { - global $CFG_GLPI; $pbBarcode = new PluginBarcodeBarcode(); @@ -134,140 +138,168 @@ function showFormConfigType($p_type = null) { } $config = $this->getConfigType($type); + + $action_url = '/plugins/barcode/front/config_type.form.php'; + echo ""; - echo ""; + action='" . htmlspecialchars($action_url) . "'>"; + echo ""; echo "
"; - echo ""; + echo "
"; + + echo ""; - echo ""; + // Tamaño y orientación de página echo ""; - echo ""; - echo ""; echo ""; - echo ""; + + // Márgenes externos + echo ""; echo ""; - echo ""; - echo ""; echo ""; + echo ""; - echo ""; - echo ""; echo ""; + + // Márgenes internos echo ""; - echo ""; - echo ""; echo ""; - echo ""; + + // Dimensiones del código + echo ""; echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; echo ""; - echo ""; + // Opciones de texto bajo el código + echo ""; echo ""; - echo ""; - echo ""; echo ""; - echo ""; + echo ""; + echo ""; echo "
" . htmlspecialchars($type) . "
".$type."
".__('Page size', 'barcode').""; + echo "" . __('Page size', 'barcode') . ""; $pbBarcode->showSizeSelect($config['size']); echo "".__('Orientation', 'barcode').""; + echo "" . __('Orientation', 'barcode') . ""; $pbBarcode->showOrientationSelect($config['orientation']); echo "
".__('Margins', 'barcode')."
" . __('Margins', 'barcode') . "
".__('Top', 'barcode').""; - echo ""; + echo "" . __('Top', 'barcode') . ""; + echo ""; echo "".__('Bottom', 'barcode').""; - echo ""; + echo "" . __('Bottom', 'barcode') . ""; + echo ""; echo "
".__('Left', 'barcode').""; - echo ""; + echo "" . __('Left', 'barcode') . ""; + echo ""; echo "".__('Right', 'barcode').""; - echo ""; + echo "" . __('Right', 'barcode') . ""; + echo ""; echo "
".__('Inner horizontal', 'barcode').""; - echo ""; + echo "" . __('Inner horizontal', 'barcode') . ""; + echo ""; echo "".__('Inner vertical', 'barcode').""; - echo ""; + echo "" . __('Inner vertical', 'barcode') . ""; + echo ""; echo "
".__('Barcodes sizes', 'barcode')."
" . __('Barcodes sizes', 'barcode') . "
".__('Maximum width', 'barcode').""; - echo ""; - echo "".__('Maximum height', 'barcode').""; - echo ""; - echo ""; + echo "" . __('Maximum width', 'barcode') . ""; + echo ""; echo "
" . __('URL', 'barcode') . ""; - echo ""; + echo "" . __('Maximum height', 'barcode') . ""; + echo ""; echo "
".__('Text display options', 'barcode')."
" . __('Text display options', 'barcode') . "
".__('Text size', 'barcode').""; - echo ""; + echo "" . __('Text size', 'barcode') . ""; + echo ""; echo "".__('Text spacing between lines', 'barcode').""; - echo ""; + echo "" . __('Text spacing between lines', 'barcode') . ""; + echo ""; echo "
"; + echo Html::submit(__('Save'), ['name' => 'update']); + echo "
"; echo "
"; Html::closeForm(); } + /** + * Obtiene la configuración de un tipo de código específico + * + * @param string|null $p_type Tipo de código + * @return array Array con todos los parámetros de configuración + */ function getConfigType($p_type = null) { if (is_null($p_type)) { - $p_type=$this->getConfig(); + $p_type = $this->getConfig(); } + $pbcconf = new PluginBarcodeConfig_Type(); - if ($res = array_keys($pbcconf->find(['type' => $p_type]))) { - $id = $res[0]; + + // API GLPI 11: usar find() con array estructurado + $results = $pbcconf->find(['type' => $p_type]); + + if (!empty($results)) { + $id = array_key_first($results); $pbcconf->getFromDB($id); - $config['type'] = $pbcconf->fields['type']; - $config['size'] = $pbcconf->fields['size']; - $config['orientation'] = $pbcconf->fields['orientation']; - $config['marginTop'] = $pbcconf->fields['marginTop']; - $config['marginBottom'] = $pbcconf->fields['marginBottom']; - $config['marginLeft'] = $pbcconf->fields['marginLeft']; - $config['marginRight'] = $pbcconf->fields['marginRight']; - $config['marginHorizontal'] = $pbcconf->fields['marginHorizontal']; - $config['marginVertical'] = $pbcconf->fields['marginVertical']; - $config['maxCodeWidth'] = $pbcconf->fields['maxCodeWidth']; - $config['maxCodeHeight'] = $pbcconf->fields['maxCodeHeight']; - $config['txtSize'] = $pbcconf->fields['txtSize']; - $config['txtSpacing'] = $pbcconf->fields['txtSpacing']; - } else { - $config['type'] = 'code128'; - $config['size'] = 'A4'; - $config['orientation'] = 'Portrait'; - $config['marginTop'] = 30; - $config['marginBottom'] = 30; - $config['marginLeft'] = 30; - $config['marginRight'] = 30; - $config['marginHorizontal'] = 25; - $config['marginVertical'] = 30; - $config['maxCodeWidth'] = 110; - $config['maxCodeHeight'] = 70; - $config['txtSize'] = 8; - $config['txtSpacing'] = 3; + return [ + 'type' => $pbcconf->fields['type'], + 'size' => $pbcconf->fields['size'], + 'orientation' => $pbcconf->fields['orientation'], + 'marginTop' => (int)$pbcconf->fields['marginTop'], + 'marginBottom' => (int)$pbcconf->fields['marginBottom'], + 'marginLeft' => (int)$pbcconf->fields['marginLeft'], + 'marginRight' => (int)$pbcconf->fields['marginRight'], + 'marginHorizontal' => (int)$pbcconf->fields['marginHorizontal'], + 'marginVertical' => (int)$pbcconf->fields['marginVertical'], + 'maxCodeWidth' => (int)$pbcconf->fields['maxCodeWidth'], + 'maxCodeHeight' => (int)$pbcconf->fields['maxCodeHeight'], + 'txtSize' => (int)$pbcconf->fields['txtSize'], + 'txtSpacing' => (int)$pbcconf->fields['txtSpacing'], + ]; } - return $config; - } - + // Valores por defecto si no hay configuración en BD + return [ + 'type' => 'code128', + 'size' => 'A4', + 'orientation' => 'Portrait', + 'marginTop' => 30, + 'marginBottom' => 30, + 'marginLeft' => 30, + 'marginRight' => 30, + 'marginHorizontal' => 25, + 'marginVertical' => 30, + 'maxCodeWidth' => 110, + 'maxCodeHeight' => 70, + 'txtSize' => 8, + 'txtSpacing' => 3, + ]; + } + /** + * Muestra un selector de tipo de código + * + * @param string|null $p_type Valor seleccionado actualmente + * @param array $used Tipos a excluir del dropdown + */ function showTypeSelect($p_type = null, $used = []) { - $options = [ - 'width' => '100', - 'used' => $used - ]; + 'width' => '100', + 'used' => $used, + ]; if (!is_null($p_type)) { $options['value'] = $p_type; } - Dropdown::showFromArray("type", - ['Code39' => __('code39', 'barcode'), - 'code128' => __('code128', 'barcode'), - 'ean13' => __('ean13', 'barcode'), - 'int25' => __('int25', 'barcode'), - 'postnet' => __('postnet', 'barcode'), - 'upca' => __('upca', 'barcode'), - 'QRcode' => __('QRcode', 'barcode')], - $options - ); + Dropdown::showFromArray( + "type", + [ + 'Code39' => __('code39', 'barcode'), + 'code128' => __('code128', 'barcode'), + 'ean13' => __('ean13', 'barcode'), + 'int25' => __('int25', 'barcode'), + 'postnet' => __('postnet', 'barcode'), + 'upca' => __('upca', 'barcode'), + 'QRcode' => __('QRcode', 'barcode'), + ], + $options + ); } } diff --git a/inc/config_type.class.php b/inc/config_type.class.php index 8807da5..c825a4f 100644 --- a/inc/config_type.class.php +++ b/inc/config_type.class.php @@ -2,48 +2,28 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode + Barcode - Plugin para GLPI + Migrado a GLPI 11.x por Dawing S.A.S. ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - - ------------------------------------------------------------------------ - - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ */ if (!defined('GLPI_ROOT')) { - die("Sorry. You can't access directly to this file"); + die("Sorry. You can't access directly to this file"); } +/** + * Clase de configuración por tipo de código de barras + */ class PluginBarcodeConfig_Type extends CommonDBTM { -} + static $rightname = 'plugin_barcode_config'; + /** + * Nombre del tipo de item + */ + static function getTypeName($nb = 0) { + return __('Barcode configuration type', 'barcode'); + } +} diff --git a/inc/profile.class.php b/inc/profile.class.php index 54a707d..ffd95de 100644 --- a/inc/profile.class.php +++ b/inc/profile.class.php @@ -2,40 +2,11 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode - ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - + Barcode - Plugin para GLPI + Migrado a GLPI 11.x por Dawing S.A.S. + Original: Copyright (C) 2009-2016 by the Barcode plugin Development Team. ------------------------------------------------------------------------ - - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ */ @@ -43,48 +14,52 @@ class PluginBarcodeProfile extends Profile { static $rightname = "config"; - + /** + * Nombre de la pestaña que se agrega al formulario de Perfil + */ function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) { if ($item->getID() > 0 && $item->fields['interface'] == 'central') { return self::createTabEntry(__('Barcode', 'barcode')); } + return ''; } - - + /** + * Contenido de la pestaña del perfil + */ static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) { $pfProfile = new self(); $pfProfile->showForm($item->getID()); return true; } - - - /** - * Show profile form - * - * @param $items_id integer id of the profile - * @param $target value url of target + /** + * Formulario de derechos del plugin en el perfil * - * @return nothing - **/ + * @param int $ID ID del perfil + * @param array $options Opciones adicionales + */ function showForm($ID, array $options = []) { echo "
"; - if (($canedit = Session::haveRightsOr(self::$rightname, [CREATE, UPDATE, PURGE]))) { + $canedit = Session::haveRightsOr(self::$rightname, [CREATE, UPDATE, PURGE]); + + if ($canedit) { $profile = new Profile(); - echo ""; + echo ""; } $profile = new Profile(); $profile->getFromDB($ID); $rights = $this->getAllRights(); - $profile->displayRightsChoiceMatrix($rights, ['canedit' => $canedit, - 'default_class' => 'tab_bg_2', - 'title' => __('Barcode', 'barcode') - ]); + $profile->displayRightsChoiceMatrix($rights, [ + 'canedit' => $canedit, + 'default_class' => 'tab_bg_2', + 'title' => __('Barcode', 'barcode'), + ]); + if ($canedit) { echo "
"; echo Html::hidden('id', ['value' => $ID]); @@ -95,62 +70,76 @@ function showForm($ID, array $options = []) { echo "
"; } - - + /** + * Elimina los derechos del plugin (para uninstall) + */ static function uninstallProfile() { - $pfProfile = new self(); - $a_rights = $pfProfile->getAllRights(); + $pfProfile = new self(); + $a_rights = $pfProfile->getAllRights(); foreach ($a_rights as $data) { ProfileRight::deleteProfileRights([$data['field']]); } } - - + /** + * Lista de todos los derechos del plugin + * + * @return array + */ function getAllRights() { - $a_rights = [ - ['rights' => [UPDATE => __('Update')], - 'label' => __('Manage configuration', 'barcode'), - 'field' => 'plugin_barcode_config' - ], - ['rights' => [CREATE => __('Create')], - 'label' => __('Generation of barcode', 'barcode'), - 'field' => 'plugin_barcode_barcode' - ] + return [ + [ + 'rights' => [UPDATE => __('Update')], + 'label' => __('Manage configuration', 'barcode'), + 'field' => 'plugin_barcode_config', + ], + [ + 'rights' => [CREATE => __('Create')], + 'label' => __('Generation of barcode', 'barcode'), + 'field' => 'plugin_barcode_barcode', + ], ]; - return $a_rights; } - - + /** + * Agrega derechos por defecto a un perfil + * + * @param int $profiles_id ID del perfil + * @param array $rights Mapa de derechos a agregar + */ static function addDefaultProfileInfos($profiles_id, $rights) { $profileRight = new ProfileRight(); foreach ($rights as $right => $value) { if (!countElementsInTable('glpi_profilerights', ['profiles_id' => $profiles_id, 'name' => $right])) { - $myright['profiles_id'] = $profiles_id; - $myright['name'] = $right; - $myright['rights'] = $value; + $myright = [ + 'profiles_id' => $profiles_id, + 'name' => $right, + 'rights' => $value, + ]; $profileRight->add($myright); - - //Add right to the current session + // Actualizar sesión activa $_SESSION['glpiactiveprofile'][$right] = $value; } } } /** - * @param $profiles_id integer + * Crea accesos completos para el primer perfil administrador + * + * @param int $profiles_id ID del perfil */ static function createFirstAccess($profiles_id) { - include_once(Plugin::getPhpDir('barcode')."/inc/profile.class.php"); + include_once(Plugin::getPhpDir('barcode') . "/inc/profile.class.php"); $profile = new self(); foreach ($profile->getAllRights() as $right) { - self::addDefaultProfileInfos($profiles_id, - [$right['field'] => ALLSTANDARDRIGHT]); + self::addDefaultProfileInfos($profiles_id, [$right['field'] => ALLSTANDARDRIGHT]); } } + /** + * Elimina los derechos del plugin de todos los perfiles y de la sesión + */ static function removeRights() { $profile = new self(); foreach ($profile->getAllRights() as $right) { @@ -161,51 +150,11 @@ static function removeRights() { } } - static function migrateProfiles() { - //Get all rights from the old table - $profiles = getAllDataFromTable(getTableForItemType(__CLASS__)); - - //Load mapping of old rights to their new equivalent - $oldrights = self::getOldRightsMappings(); - - //For each old profile : translate old right the new one - foreach ($profiles as $id => $profile) { - switch ($profile['right']) { - case 'r' : - $value = READ; - break; - case 'w': - $value = ALLSTANDARDRIGHT; - break; - case 0: - default: - $value = 0; - break; - } - //Write in glpi_profilerights the new fusioninventory right - if (isset($oldrights[$profile['type']])) { - //There's one new right corresponding to the old one - if (!is_array($oldrights[$profile['type']])) { - self::addDefaultProfileInfos($profile['profiles_id'], - [$oldrights[$profile['type']] => $value]); - } else { - //One old right has been splitted into serveral new ones - foreach ($oldrights[$profile['type']] as $newtype) { - self::addDefaultProfileInfos($profile['profiles_id'], - [$newtype => $value]); - } - } - } - } - } - - - /** - * Init profiles during installation : - * - add rights in profile table for the current user's profile - * - current profile has all rights on the plugin - */ + * Inicializa los perfiles del plugin durante la instalación + * - Registra los derechos en glpi_profilerights + * - El perfil activo del usuario instalador recibe todos los derechos + */ static function initProfile() { $pfProfile = new self(); $profile = new Profile(); @@ -218,28 +167,40 @@ static function initProfile() { } } - // Add all rights to current profile of the user + // Asignar todos los derechos al perfil activo del usuario instalador if (isset($_SESSION['glpiactiveprofile'])) { $dataprofile = []; $dataprofile['id'] = $_SESSION['glpiactiveprofile']['id']; $profile->getFromDB($_SESSION['glpiactiveprofile']['id']); + foreach ($a_rights as $info) { if (is_array($info) - && ((!empty($info['itemtype'])) || (!empty($info['rights']))) - && (!empty($info['label'])) && (!empty($info['field']))) { + && (!empty($info['itemtype']) || !empty($info['rights'])) + && !empty($info['label']) + && !empty($info['field'])) { + + $rights = isset($info['rights']) + ? $info['rights'] + : $profile->getRightsFor($info['itemtype']); - if (isset($info['rights'])) { - $rights = $info['rights']; - } else { - $rights = $profile->getRightsFor($info['itemtype']); - } foreach (array_keys($rights) as $right) { - $dataprofile['_'.$info['field']][$right] = 1; - $_SESSION['glpiactiveprofile'][$data['field']] = $right; + $dataprofile['_' . $info['field']][$right] = 1; + $_SESSION['glpiactiveprofile'][$info['field']] = $right; } } } $profile->update($dataprofile); } } + + /** + * Limpia los perfiles al purgar un perfil GLPI + * (Callback del hook pre_item_purge) + * + * @param Profile $item Objeto Profile que se está purgando + */ + static function cleanProfiles(Profile $item) { + // No hay tabla local de perfiles en esta versión + // Los derechos están en glpi_profilerights manejados por GLPI core + } } diff --git a/inc/qrcode.class.php b/inc/qrcode.class.php index b1df745..79177aa 100644 --- a/inc/qrcode.class.php +++ b/inc/qrcode.class.php @@ -1,46 +1,7 @@ . - - ------------------------------------------------------------------------ - - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2013 - - ------------------------------------------------------------------------ - */ - if (!defined('GLPI_ROOT')) { - die("Sorry. You can't access directly to this file"); + die("Sorry. You can't access directly to this file"); } require_once __DIR__ . '/../vendor/deltalab/phpqrcode/phpqrcode.php'; @@ -50,132 +11,99 @@ class PluginBarcodeQRcode { function generateQRcode($itemtype, $items_id, $rand, $number, $data) { global $CFG_GLPI; - /** @var CommonDBTM $item */ $item = new $itemtype(); $item->getFromDB($items_id); - $itemByInvNumber = $item->fields['otherserial']; - $URLById= 'URL = ' . $CFG_GLPI['url_base'] . $itemtype::getFormURLWithID($items_id, false); - $URLByInvNumber = 'URL = ' . Plugin::getWebDir('barcode', true, true) . '/front/checkItemByInv.php?inventoryNumber='. $itemByInvNumber . '&itemtype=' . $itemtype; - $a_content = []; + $itemByInvNumber = $item->fields['otherserial'] ?? ''; + + $URLById = 'URL = ' . $CFG_GLPI['url_base'] . $itemtype::getFormURLWithID($items_id, false); + $URLByInvNumber = 'URL = ' . $CFG_GLPI['url_base'] + . '/plugins/barcode/front/checkItemByInv.php?inventoryNumber=' + . urlencode($itemByInvNumber) + . '&itemtype=' . urlencode($itemtype); + + $a_content = []; $b_content = []; - $have_content = false; - if ($data['serialnumber']) { - if ($item->fields['serial'] != '') { - $have_content = true; - } - $a_content[] = __("Serial number").' = '.$item->fields['serial']; - if ($data['displayserialnumber']) { - $label = ''; - if ($data['displaylabels']) { - $label = __("Serial number").': '; - } - $b_content[] = $label.$item->fields['serial']; + + if (!empty($data['serialnumber']) && isset($item->fields['serial'])) { + $a_content[] = 'Serial number = ' . $item->fields['serial']; + if (!empty($data['displayserialnumber'])) { + $label = !empty($data['displaylabels']) ? 'Serial: ' : ''; + $b_content[] = $label . $item->fields['serial']; } } - if ($data['inventorynumber']) { - if ($item->fields['otherserial'] != '') { - $have_content = true; - } - $a_content[] = __('Inventory number').' = '.$item->fields['otherserial']; - if ($data['displayinventorynumber']) { - $label = ''; - if ($data['displaylabels']) { - $label = __('Inventory number').': '; - } - $b_content[] = $label.$item->fields['otherserial']; + + if (!empty($data['inventorynumber']) && isset($item->fields['otherserial'])) { + $a_content[] = 'Inventory number = ' . $item->fields['otherserial']; + if (!empty($data['displayinventorynumber'])) { + $label = !empty($data['displaylabels']) ? 'Inventario: ' : ''; + $b_content[] = $label . $item->fields['otherserial']; } } - if ($data['id']) { - if ($item->fields['id'] != '') { - $have_content = true; - } - $a_content[] = __('ID').' = '.$item->fields['id']; - if ($data['displayid']) { - $label = ''; - if ($data['displaylabels']) { - $label = __('ID').': '; - } - $b_content[] = $label.$item->fields['id']; + + if (!empty($data['id'])) { + $a_content[] = 'ID = ' . $item->fields['id']; + if (!empty($data['displayid'])) { + $label = !empty($data['displaylabels']) ? 'ID: ' : ''; + $b_content[] = $label . $item->fields['id']; } } - if (isset($data['uuid']) && $data['uuid']) { - if (isset($item->fields['uuid'])) { - if ($item->fields['uuid'] != '') { - $have_content = true; - } - $a_content[] = __('UUID').' = '.$item->fields['uuid']; - if ($data['displayuuid']) { - $label = ''; - if ($data['displaylabels']) { - $label = __('UUID').': '; - } - $b_content[] = $label.$item->fields['uuid']; - } + + if (!empty($data['uuid']) && isset($item->fields['uuid'])) { + $a_content[] = 'UUID = ' . $item->fields['uuid']; + if (!empty($data['displayuuid'])) { + $label = !empty($data['displaylabels']) ? 'UUID: ' : ''; + $b_content[] = $label . $item->fields['uuid']; } } - if ($data['name']) { - if ($item->fields['name'] != '') { - $have_content = true; - } - $a_content[] = __('Item Name').' = '.$item->fields['name']; - if ($data['displayname']) { - $label = ''; - if ($data['displaylabels']) { - $label = __('Item Name').': '; - } - $b_content[] = $label.$item->fields['name']; + + if (!empty($data['name']) && isset($item->fields['name'])) { + $a_content[] = 'Name = ' . $item->fields['name']; + if (!empty($data['displayname'])) { + $label = !empty($data['displaylabels']) ? 'Nombre: ' : ''; + $b_content[] = $label . $item->fields['name']; } } - if ($data['url'] && !$item->no_form_page) { - if ($data['inventorynumberURL']) { - $a_content[] = $URLByInvNumber; - } else { - $a_content[] = $URLById; - } - if ($data['displayurl']) { - $label = ''; - if ($data['displaylabels']) { - $label = __('Item URL').': '; - } - if ($data['inventorynumberURL']) { - $b_content[] = $label.$URLByInvNumber; - } else { - $b_content[] = $label.$URLById; - } + + if (!empty($data['url']) && !$item->no_form_page) { + $urlValue = !empty($data['inventorynumberURL']) ? $URLByInvNumber : $URLById; + $a_content[] = $urlValue; + if (!empty($data['displayurl'])) { + $label = !empty($data['displaylabels']) ? 'URL: ' : ''; + $b_content[] = $label . $urlValue; } } - if ($data['qrcodedate']) { - $a_content[] = 'QRcode date = '.date('Y-m-d'); - if ($data['displayqrcodedate']) { - $label = ''; - if ($data['displaylabels']) { - $label = __('Date').': '; - } - $b_content[] = $label.date('Y-m-d'); + + if (!empty($data['qrcodedate'])) { + $dateStr = date('Y-m-d'); + $a_content[] = 'QRcode date = ' . $dateStr; + if (!empty($data['displayqrcodedate'])) { + $label = !empty($data['displaylabels']) ? 'Fecha: ' : ''; + $b_content[] = $label . $dateStr; } } - if (count($a_content) > 0) { - $codeContents = implode("\n", $a_content); - QRcode::png($codeContents, - GLPI_PLUGIN_DOC_DIR.'/barcode/_tmp_'.$rand.'-'.$number.'.png', - QR_ECLEVEL_L, - 4); - return [GLPI_PLUGIN_DOC_DIR.'/barcode/_tmp_'.$rand.'-'.$number.'.png',$b_content]; + if (count($a_content) === 0) { + return false; } - return false; - } + $codeContents = implode("\n", $a_content); + $outputPath = GLPI_PLUGIN_DOC_DIR . '/barcode/_tmp_' . $rand . '-' . $number . '.png'; + QRcode::png($codeContents, $outputPath, QR_ECLEVEL_L, 4); + + return [$outputPath, $b_content]; + } function cleanQRcodefiles($rand, $number) { for ($i = 0; $i < $number; $i++) { - unlink(GLPI_PLUGIN_DOC_DIR.'/barcode/_tmp_'.$rand.'-'.$i.'.png'); + $tmpFile = GLPI_PLUGIN_DOC_DIR . '/barcode/_tmp_' . $rand . '-' . $i . '.png'; + if (file_exists($tmpFile)) { + @unlink($tmpFile); + } } } - function showFormMassiveAction(MassiveAction $ma) { $fields = []; @@ -183,10 +111,9 @@ function showFormMassiveAction(MassiveAction $ma) { $itemtype = $ma->getItemtype(false); if (is_a($itemtype, CommonDBTM::class, true)) { - /** @var CommonDBTM $item */ $item = new $itemtype(); $item->getEmpty(); - $fields = array_keys($item->fields); + $fields = array_keys($item->fields); $no_form_page = $item->no_form_page; } @@ -194,132 +121,100 @@ function showFormMassiveAction(MassiveAction $ma) { echo '
'; echo ''; - if (in_array('serial', $fields)) { + if (in_array('serial', $fields, true)) { echo ''; - echo ''; - echo ''; echo ''; } else { echo Html::hidden('serialnumber', ['value' => 0]); } - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; echo ''; } else { echo Html::hidden('inventorynumber', ['value' => 0]); } - echo ''; + echo ''; - echo ''; - echo ''; echo ''; - if (in_array('uuid', $fields)) { + if (in_array('uuid', $fields, true)) { echo ''; - echo ''; + echo ''; echo ''; } else { echo Html::hidden('uuid', ['value' => 0]); } - if (in_array('name', $fields)) { + if (in_array('name', $fields, true)) { echo ''; - echo ''; + echo ''; echo ''; } else { echo Html::hidden('name', ['value' => 0]); } + echo ''; - echo ''; echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; if (!$no_form_page) { echo ''; - echo ''; + echo ''; echo ''; } else { echo Html::hidden('url', ['value' => 0]); } echo ''; - echo ''; - echo ''; echo ''; + echo ''; - echo ''; - echo ''; - echo ''; + echo ''; echo ''; echo '
'; - echo __('Serial number')." : "; + echo 'Numero de serial : '; Dropdown::showYesNo("serialnumber", 1, -1, ['width' => '100']); echo ''; - echo __('Display serial number')." : "; + echo 'Mostrar en etiqueta : '; Dropdown::showYesNo("displayserialnumber", 0, -1, ['width' => '100']); echo '
'; - if (in_array('otherserial', $fields)) { + + if (in_array('otherserial', $fields, true)) { echo '
'; - echo __('Inventory number')." : "; + echo 'Numero de inventario : '; Dropdown::showYesNo("inventorynumber", 1, -1, ['width' => '100']); echo ''; - echo __('Display inventory number')." : "; + echo 'Mostrar en etiqueta : '; Dropdown::showYesNo("displayinventorynumber", 1, -1, ['width' => '100']); echo '
'; - echo __('ID')." : "; + echo 'ID : '; Dropdown::showYesNo("id", 1, -1, ['width' => '100']); echo ''; - echo __('Display ID')." : "; + echo 'Mostrar en etiqueta : '; Dropdown::showYesNo("displayid", 0, -1, ['width' => '100']); echo '
'; - echo __('UUID')." : "; + echo 'UUID : '; Dropdown::showYesNo("uuid", 1, -1, ['width' => '100']); echo 'Mostrar en etiqueta : '; + Dropdown::showYesNo("displayuuid", 0, -1, ['width' => '100']); + echo '
'; - echo __('Name')." : "; + echo 'Nombre : '; Dropdown::showYesNo("name", 1, -1, ['width' => '100']); echo 'Mostrar en etiqueta : '; + Dropdown::showYesNo("displayname", 1, -1, ['width' => '100']); + echo '
'; - echo __('URL by inventory number') . " : "; + echo 'URL por numero de inventario : '; Dropdown::showYesNo("inventorynumberURL", 1, -1, ['width' => '100']); echo '
'; - echo __('UUID')." : "; - Dropdown::showYesNo("uuid", 1, -1, ['width' => '100']); - echo ''; - echo __('Display UUID')." : "; - Dropdown::showYesNo("displayuuid", 0, -1, ['width' => '100']); - echo '
'; - echo __('Name')." : "; - Dropdown::showYesNo("name", 1, -1, ['width' => '100']); - echo ''; - echo __('Display name')." : "; - Dropdown::showYesNo("displayname", 1, -1, ['width' => '100']); - echo '
'; - echo __('Web page of the device')." : "; - Dropdown::showYesNo("url", 1, -1, ['width' => '100']); - echo ''; - echo __('Display web page of the device')." : "; - Dropdown::showYesNo("displayurl", 0, -1, ['width' => '100']); - echo '
'; - echo __('Web page of the item')." : "; + echo 'Pagina web del dispositivo : '; Dropdown::showYesNo("url", 1, -1, ['width' => '100']); echo 'Mostrar en etiqueta : '; + Dropdown::showYesNo("displayurl", 0, -1, ['width' => '100']); + echo '
'; - echo __('Date QRcode')." (".date('Y-m-d').") : "; + echo 'Fecha QRcode (' . date('Y-m-d') . ') : '; Dropdown::showYesNo("qrcodedate", 1, -1, ['width' => '100']); echo ''; - echo __('Display date QRcode')." (".date('Y-m-d').") : "; + echo 'Mostrar en etiqueta : '; Dropdown::showYesNo("displayqrcodedate", 0, -1, ['width' => '100']); echo '
  '.__('Note: Currently supporting only up to 2 lines.').''; + echo 'Columna izquierda: incluir dato en el QR code. '; + echo 'Mostrar en etiqueta: mostrar texto visible bajo el codigo.'; + echo '
'; @@ -328,63 +223,47 @@ function showFormMassiveAction(MassiveAction $ma) { PluginBarcodeBarcode::commonShowMassiveAction(); } - - function getSpecificMassiveActions($checkitem = null) { return []; } - - - /** - * @since version 0.85 - * - * @see CommonDBTM::showMassiveActionsSubForm() - **/ static function showMassiveActionsSubForm(MassiveAction $ma) { - switch ($ma->getAction()) { - case 'Generate': $pbQRcode = new self(); $pbQRcode->showFormMassiveAction($ma); return true; - } return false; } - - - static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBTM $item, array $ids) { - global $CFG_GLPI; - + static function processMassiveActionsForOneItemtype( + MassiveAction $ma, + CommonDBTM $item, + array $ids + ) { switch ($ma->getAction()) { - - case 'Generate' : + case 'Generate': $pbQRcode = new PluginBarcodeQRcode(); $rand = mt_rand(); $number = 0; $codes = []; $displayDataCollection = []; - if ($ma->POST['eliminate'] > 0) { - for ($nb=0; $nb < $ma->POST['eliminate']; $nb++) { - $codes[] = ''; - $displayDataCollection[] = ''; - } + + $eliminate = (int)($ma->POST['eliminate'] ?? 0); + for ($nb = 0; $nb < $eliminate; $nb++) { + $codes[] = ''; + $displayDataCollection[] = []; } - if ($ma->POST['type'] == 'QRcode') { - if ($item->isField('inventotynumberURL')) { - $URLtype = 'inventoryURL'; - } else { - $URLtype = 'idURL'; - } + + if ($ma->POST['type'] === 'QRcode') { foreach ($ids as $key) { - $values = $pbQRcode->generateQRcode($item->getType(), $key, $rand, $number, $ma->POST); - $filename = $values[0]; - $displayData = $values[1]; - if ($filename) { - $codes[] = $filename; + $values = $pbQRcode->generateQRcode( + $item->getType(), $key, $rand, $number, $ma->POST + ); + if ($values !== false) { + [$filename, $displayData] = $values; + $codes[] = $filename; $displayDataCollection[] = $displayData; $number++; } @@ -393,33 +272,37 @@ static function processMassiveActionsForOneItemtype(MassiveAction $ma, CommonDBT foreach ($ids as $key) { $item->getFromDB($key); if ($item->isField('otherserial')) { - $codes[] = $item->getField('otherserial'); + $codes[] = $item->getField('otherserial'); + $displayDataCollection[] = []; } } } + if (count($codes) > 0) { - $params['codes'] = $codes; - $params['displayData'] = $displayDataCollection; - $params['type'] = $ma->POST['type']; - $params['size'] = $ma->POST['size']; - $params['border'] = $ma->POST['border']; - $params['orientation'] = $ma->POST['orientation']; - $params['displaylabels'] = $ma->POST['displaylabels']; - $barcode = new PluginBarcodeBarcode(); - $file = $barcode->printPDF($params); - $filePath = explode('/', $file); - $filename = $filePath[count($filePath)-1]; - - $msg = "".__('Generated file', 'barcode').""; + $params = [ + 'codes' => $codes, + 'displayData' => $displayDataCollection, + 'type' => $ma->POST['type'], + 'size' => $ma->POST['size'], + 'border' => $ma->POST['border'], + 'orientation' => $ma->POST['orientation'], + 'displaylabels' => $ma->POST['displaylabels'], + ]; + + $barcode = new PluginBarcodeBarcode(); + $file = $barcode->printPDF($params); + $filePath = explode('/', $file); + $filename = end($filePath); + + $msg = "" + . __('Generated file', 'barcode') . ""; + Session::addMessageAfterRedirect($msg); $pbQRcode->cleanQRcodefiles($rand, $number); } + $ma->itemDone($item->getType(), 0, MassiveAction::ACTION_OK); return; - } - return; } - - } diff --git a/setup.php b/setup.php index c716d21..ea08b8f 100644 --- a/setup.php +++ b/setup.php @@ -2,107 +2,111 @@ /* ------------------------------------------------------------------------ - Barcode - Copyright (C) 2009-2016 by the Barcode plugin Development Team. - - https://forge.indepnet.net/projects/barscode - ------------------------------------------------------------------------ - - LICENSE - - This file is part of barcode plugin project. - - Plugin Barcode is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Plugin Barcode is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Plugin Barcode. If not, see . - + Barcode - Plugin para GLPI + Migrado a GLPI 11.x por Dawing S.A.S. + Original: Copyright (C) 2009-2016 by the Barcode plugin Development Team. ------------------------------------------------------------------------ - @package Plugin Barcode - @author David Durieux - @co-author - @copyright Copyright (c) 2009-2016 Barcode plugin Development team - @license AGPL License 3.0 or (at your option) any later version - http://www.gnu.org/licenses/agpl-3.0-standalone.html - @link https://forge.indepnet.net/projects/barscode - @since 2009 - + LICENSE: AGPL License 3.0 or (at your option) any later version ------------------------------------------------------------------------ */ -define ("PLUGIN_BARCODE_VERSION", "2.7.1"); +define("PLUGIN_BARCODE_VERSION", "3.0.0"); -// Minimal GLPI version, inclusive -define('PLUGIN_BARCODE_MIN_GLPI', '10.0.0'); -// Maximum GLPI version, exclusive -define('PLUGIN_BARCODE_MAX_GLPI', '10.0.99'); +// Versión mínima de GLPI requerida (inclusive) +define('PLUGIN_BARCODE_MIN_GLPI', '11.0.0'); +// Versión máxima de GLPI soportada (exclusiva) +define('PLUGIN_BARCODE_MAX_GLPI', '11.0.99'); -// Init the hooks of the plugins -Needed +/** + * Inicialización de los hooks del plugin - Requerido + */ function plugin_init_barcode() { global $PLUGIN_HOOKS; - require_once(__DIR__ . '/vendor/autoload.php'); + // Cargar el autoloader de Composer + if (file_exists(__DIR__ . '/vendor/autoload.php')) { + require_once(__DIR__ . '/vendor/autoload.php'); + } - $PLUGIN_HOOKS['csrf_compliant']['barcode'] = true; + // NOTA: csrf_compliant fue deprecado en GLPI 11 - eliminado intencionalmente Plugin::registerClass('PluginBarcodeDropdown'); Plugin::registerClass('PluginBarcodeProfile', ['addtabon' => ['Profile']]); - Plugin::registerClass('PluginBarcode'); - - // Display a menu entry ? + Plugin::registerClass('PluginBarcodeBarcode'); if (Session::haveRight('plugin_barcode_barcode', CREATE) || Session::haveRight('plugin_barcode_config', UPDATE)) { + $PLUGIN_HOOKS['pre_item_purge']['barcode'] - = ['Profile' => ['PluginBarcodeProfile','cleanProfiles']]; + = ['Profile' => ['PluginBarcodeProfile', 'cleanProfiles']]; - // Massive Action definition + // Acción masiva habilitada $PLUGIN_HOOKS['use_massive_action']['barcode'] = 1; - $web_dir = '/' . Plugin::getWebDir('barcode', false); - $PLUGIN_HOOKS['submenu_entry']['barcode']['options']['optionname']['title'] = "Search"; - $PLUGIN_HOOKS['submenu_entry']['barcode']['options']['optionname']['page'] = $web_dir . '/front/barcode.php'; - $PLUGIN_HOOKS['submenu_entry']['barcode']['options']['optionname']['links']['search'] = $web_dir. '/front/barcode.php'; - $PLUGIN_HOOKS['submenu_entry']['barcode']['options']['optionname']['links']['add'] = $web_dir. '/front/barcode.form.php'; - $PLUGIN_HOOKS['submenu_entry']['barcode']['options']['optionname']['links']['config'] = $web_dir. '/index.php'; + // Ruta base del plugin (sin Plugin::getWebDir - deprecado en GLPI 11) + $web_dir = '/plugins/barcode'; + + $PLUGIN_HOOKS['submenu_entry']['barcode']['options']['optionname']['title'] = __('Search'); + $PLUGIN_HOOKS['submenu_entry']['barcode']['options']['optionname']['page'] = $web_dir . '/front/barcode.php'; + $PLUGIN_HOOKS['submenu_entry']['barcode']['options']['optionname']['links']['search'] = $web_dir . '/front/barcode.php'; + $PLUGIN_HOOKS['submenu_entry']['barcode']['options']['optionname']['links']['add'] = $web_dir . '/front/barcode.form.php'; + $PLUGIN_HOOKS['submenu_entry']['barcode']['options']['optionname']['links']['config'] = $web_dir . '/index.php'; - $PLUGIN_HOOKS["helpdesk_menu_entry"]['barcode'] = true; + $PLUGIN_HOOKS['helpdesk_menu_entry']['barcode'] = true; } - // Config page + // Página de configuración if (Session::haveRight('config', UPDATE)) { $PLUGIN_HOOKS['config_page']['barcode'] = 'front/config.php'; } - //Redirect code - //http://localhost/glpi/index.php?redirect=plugin_barcode_2 to form ID 2 + // Redirección por ID: /index.php?redirect=plugin_barcode_2 $PLUGIN_HOOKS['redirect_page']['barcode'] = 'barcode.form.php'; } +/** + * Versión e información del plugin - Requerido + */ function plugin_version_barcode() { - return [ 'name' => 'Barcode', 'shortname' => 'barcode', 'version' => PLUGIN_BARCODE_VERSION, 'license' => 'AGPLv3+', - 'author' => 'David DURIEUX & - Jean Marc GRISARD & Vincent MAZZONI', + 'author' => 'David DURIEUX & + Jean Marc GRISARD & Vincent MAZZONI + (Migrado a GLPI 11 por Dawing S.A.S.)', 'homepage' => 'https://github.com/pluginsGLPI/barcode', 'requirements' => [ 'glpi' => [ 'min' => PLUGIN_BARCODE_MIN_GLPI, 'max' => PLUGIN_BARCODE_MAX_GLPI, - ] + ], + 'php' => [ + 'min' => '8.1', + ], ] ]; } + +/** + * Verificación de prerequisitos antes de instalar + */ +function plugin_barcode_check_prerequisites() { + if (version_compare(GLPI_VERSION, PLUGIN_BARCODE_MIN_GLPI, 'lt') + || version_compare(GLPI_VERSION, PLUGIN_BARCODE_MAX_GLPI, 'gt')) { + if (method_exists('Plugin', 'messageIncompatible')) { + Plugin::messageIncompatible('core', PLUGIN_BARCODE_MIN_GLPI, PLUGIN_BARCODE_MAX_GLPI); + } + return false; + } + return true; +} + +/** + * Verificación de configuración + */ +function plugin_barcode_check_config($verbose = false) { + return true; +}