diff --git a/VERSION b/VERSION index 834f2629..860487ca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.8.0 +2.7.1 diff --git a/assets/commands/kicad_populate_default_mappings.json b/assets/commands/kicad_populate_default_mappings.json deleted file mode 100644 index a942667c..00000000 --- a/assets/commands/kicad_populate_default_mappings.json +++ /dev/null @@ -1,206 +0,0 @@ -{ - "_comment": "Default KiCad footprint/symbol mappings for partdb:kicad:populate command. Based on KiCad 9.x standard libraries. Use --mapping-file to override or extend these mappings.", - "footprints": { - "SOT-23": "Package_TO_SOT_SMD:SOT-23", - "SOT-23-3": "Package_TO_SOT_SMD:SOT-23", - "SOT-23-5": "Package_TO_SOT_SMD:SOT-23-5", - "SOT-23-6": "Package_TO_SOT_SMD:SOT-23-6", - "SOT-223": "Package_TO_SOT_SMD:SOT-223-3_TabPin2", - "SOT-223-3": "Package_TO_SOT_SMD:SOT-223-3_TabPin2", - "SOT-89": "Package_TO_SOT_SMD:SOT-89-3", - "SOT-89-3": "Package_TO_SOT_SMD:SOT-89-3", - "SOT-323": "Package_TO_SOT_SMD:SOT-323_SC-70", - "SOT-363": "Package_TO_SOT_SMD:SOT-363_SC-70-6", - "TSOT-25": "Package_TO_SOT_SMD:SOT-23-5", - "SC-70-5": "Package_TO_SOT_SMD:SOT-353_SC-70-5", - "SC-70-6": "Package_TO_SOT_SMD:SOT-363_SC-70-6", - "TO-220": "Package_TO_SOT_THT:TO-220-3_Vertical", - "TO-220AB": "Package_TO_SOT_THT:TO-220-3_Vertical", - "TO-220AB-3": "Package_TO_SOT_THT:TO-220-3_Vertical", - "TO-220FP": "Package_TO_SOT_THT:TO-220F-3_Vertical", - "TO-247-3": "Package_TO_SOT_THT:TO-247-3_Vertical", - "TO-92": "Package_TO_SOT_THT:TO-92_Inline", - "TO-92-3": "Package_TO_SOT_THT:TO-92_Inline", - "TO-252": "Package_TO_SOT_SMD:TO-252-2", - "TO-252-2L": "Package_TO_SOT_SMD:TO-252-2", - "TO-252-3L": "Package_TO_SOT_SMD:TO-252-3", - "TO-263": "Package_TO_SOT_SMD:TO-263-2", - "TO-263-2": "Package_TO_SOT_SMD:TO-263-2", - "D2PAK": "Package_TO_SOT_SMD:TO-252-2", - "DPAK": "Package_TO_SOT_SMD:TO-252-2", - "SOIC-8": "Package_SO:SOIC-8_3.9x4.9mm_P1.27mm", - "ESOP-8": "Package_SO:SOIC-8_3.9x4.9mm_P1.27mm", - "SOIC-14": "Package_SO:SOIC-14_3.9x8.7mm_P1.27mm", - "SOIC-16": "Package_SO:SOIC-16_3.9x9.9mm_P1.27mm", - "TSSOP-8": "Package_SO:TSSOP-8_3x3mm_P0.65mm", - "TSSOP-14": "Package_SO:TSSOP-14_4.4x5mm_P0.65mm", - "TSSOP-16": "Package_SO:TSSOP-16_4.4x5mm_P0.65mm", - "TSSOP-16L": "Package_SO:TSSOP-16_4.4x5mm_P0.65mm", - "TSSOP-20": "Package_SO:TSSOP-20_4.4x6.5mm_P0.65mm", - "MSOP-8": "Package_SO:MSOP-8_3x3mm_P0.65mm", - "MSOP-10": "Package_SO:MSOP-10_3x3mm_P0.5mm", - "MSOP-16": "Package_SO:MSOP-16_3x4mm_P0.5mm", - "SO-5": "Package_TO_SOT_SMD:SOT-23-5", - "DIP-4": "Package_DIP:DIP-4_W7.62mm", - "DIP-6": "Package_DIP:DIP-6_W7.62mm", - "DIP-8": "Package_DIP:DIP-8_W7.62mm", - "DIP-14": "Package_DIP:DIP-14_W7.62mm", - "DIP-16": "Package_DIP:DIP-16_W7.62mm", - "DIP-18": "Package_DIP:DIP-18_W7.62mm", - "DIP-20": "Package_DIP:DIP-20_W7.62mm", - "DIP-24": "Package_DIP:DIP-24_W7.62mm", - "DIP-28": "Package_DIP:DIP-28_W7.62mm", - "DIP-40": "Package_DIP:DIP-40_W15.24mm", - "QFN-8": "Package_DFN_QFN:QFN-8-1EP_3x3mm_P0.65mm_EP1.55x1.55mm", - "QFN-12(3x3)": "Package_DFN_QFN:QFN-12-1EP_3x3mm_P0.5mm_EP1.65x1.65mm", - "QFN-16": "Package_DFN_QFN:QFN-16-1EP_3x3mm_P0.5mm_EP1.45x1.45mm", - "QFN-20": "Package_DFN_QFN:QFN-20-1EP_4x4mm_P0.5mm_EP2.5x2.5mm", - "QFN-24": "Package_DFN_QFN:QFN-24-1EP_4x4mm_P0.5mm_EP2.45x2.45mm", - "QFN-32": "Package_DFN_QFN:QFN-32-1EP_5x5mm_P0.5mm_EP3.45x3.45mm", - "QFN-48": "Package_DFN_QFN:QFN-48-1EP_7x7mm_P0.5mm_EP5.3x5.3mm", - "TQFP-32": "Package_QFP:TQFP-32_7x7mm_P0.8mm", - "TQFP-44": "Package_QFP:TQFP-44_10x10mm_P0.8mm", - "TQFP-48": "Package_QFP:TQFP-48_7x7mm_P0.5mm", - "TQFP-48(7x7)": "Package_QFP:TQFP-48_7x7mm_P0.5mm", - "TQFP-64": "Package_QFP:TQFP-64_10x10mm_P0.5mm", - "TQFP-100": "Package_QFP:TQFP-100_14x14mm_P0.5mm", - "LQFP-32": "Package_QFP:LQFP-32_7x7mm_P0.8mm", - "LQFP-48": "Package_QFP:LQFP-48_7x7mm_P0.5mm", - "LQFP-64": "Package_QFP:LQFP-64_10x10mm_P0.5mm", - "LQFP-100": "Package_QFP:LQFP-100_14x14mm_P0.5mm", - - "SOD-123": "Diode_SMD:D_SOD-123", - "SOD-123F": "Diode_SMD:D_SOD-123F", - "SOD-123FL": "Diode_SMD:D_SOD-123F", - "SOD-323": "Diode_SMD:D_SOD-323", - "SOD-523": "Diode_SMD:D_SOD-523", - "SOD-882": "Diode_SMD:D_SOD-882", - "SOD-882D": "Diode_SMD:D_SOD-882", - "SMA(DO-214AC)": "Diode_SMD:D_SMA", - "SMA": "Diode_SMD:D_SMA", - "SMB": "Diode_SMD:D_SMB", - "SMC": "Diode_SMD:D_SMC", - - "DO-35": "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal", - "DO-35(DO-204AH)": "Diode_THT:D_DO-35_SOD27_P7.62mm_Horizontal", - "DO-41": "Diode_THT:D_DO-41_SOD81_P10.16mm_Horizontal", - "DO-201": "Diode_THT:D_DO-201_P15.24mm_Horizontal", - - "DFN-2(0.6x1)": "Package_DFN_QFN:DFN-2-1EP_0.6x1.0mm_P0.65mm_EP0.2x0.55mm", - "DFN1006-2": "Package_DFN_QFN:DFN-2_1.0x0.6mm", - "DFN-6": "Package_DFN_QFN:DFN-6-1EP_2x2mm_P0.65mm_EP1x1.6mm", - "DFN-8": "Package_DFN_QFN:DFN-8-1EP_3x2mm_P0.5mm_EP1.3x1.5mm", - - "0201": "Resistor_SMD:R_0201_0603Metric", - "0402": "Resistor_SMD:R_0402_1005Metric", - "0603": "Resistor_SMD:R_0603_1608Metric", - "0805": "Resistor_SMD:R_0805_2012Metric", - "1206": "Resistor_SMD:R_1206_3216Metric", - "1210": "Resistor_SMD:R_1210_3225Metric", - "1812": "Resistor_SMD:R_1812_4532Metric", - "2010": "Resistor_SMD:R_2010_5025Metric", - "2512": "Resistor_SMD:R_2512_6332Metric", - "2917": "Resistor_SMD:R_2917_7343Metric", - "2920": "Resistor_SMD:R_2920_7350Metric", - - "CASE-A-3216-18(mm)": "Capacitor_Tantalum_SMD:CP_EIA-3216-18_Kemet-A", - "CASE-B-3528-21(mm)": "Capacitor_Tantalum_SMD:CP_EIA-3528-21_Kemet-B", - "CASE-C-6032-28(mm)": "Capacitor_Tantalum_SMD:CP_EIA-6032-28_Kemet-C", - "CASE-D-7343-31(mm)": "Capacitor_Tantalum_SMD:CP_EIA-7343-31_Kemet-D", - "CASE-E-7343-43(mm)": "Capacitor_Tantalum_SMD:CP_EIA-7343-43_Kemet-E", - - "SMD,D4xL5.4mm": "Capacitor_SMD:CP_Elec_4x5.4", - "SMD,D5xL5.4mm": "Capacitor_SMD:CP_Elec_5x5.4", - "SMD,D6.3xL5.4mm": "Capacitor_SMD:CP_Elec_6.3x5.4", - "SMD,D6.3xL7.7mm": "Capacitor_SMD:CP_Elec_6.3x7.7", - "SMD,D8xL6.5mm": "Capacitor_SMD:CP_Elec_8x6.5", - "SMD,D8xL10mm": "Capacitor_SMD:CP_Elec_8x10", - "SMD,D10xL10mm": "Capacitor_SMD:CP_Elec_10x10", - "SMD,D10xL10.5mm": "Capacitor_SMD:CP_Elec_10x10.5", - - "Through Hole,D5xL11mm": "Capacitor_THT:CP_Radial_D5.0mm_P2.00mm", - "Through Hole,D6.3xL11mm": "Capacitor_THT:CP_Radial_D6.3mm_P2.50mm", - "Through Hole,D8xL11mm": "Capacitor_THT:CP_Radial_D8.0mm_P3.50mm", - "Through Hole,D10xL16mm": "Capacitor_THT:CP_Radial_D10.0mm_P5.00mm", - "Through Hole,D10xL20mm": "Capacitor_THT:CP_Radial_D10.0mm_P5.00mm", - "Through Hole,D12.5xL20mm": "Capacitor_THT:CP_Radial_D12.5mm_P5.00mm", - - "LED 3mm": "LED_THT:LED_D3.0mm", - "LED 5mm": "LED_THT:LED_D5.0mm", - "LED 0603": "LED_SMD:LED_0603_1608Metric", - "LED 0805": "LED_SMD:LED_0805_2012Metric", - "SMD5050-4P": "LED_SMD:LED_WS2812B_PLCC4_5.0x5.0mm_P3.2mm", - "SMD5050-6P": "LED_SMD:LED_WS2812B_PLCC4_5.0x5.0mm_P3.2mm", - - "HC-49": "Crystal:Crystal_HC49-4H_Vertical", - "HC-49/U": "Crystal:Crystal_HC49-4H_Vertical", - "HC-49/S": "Crystal:Crystal_HC49-U_Vertical", - "HC-49/US": "Crystal:Crystal_HC49-U_Vertical", - - "USB-A": "Connector_USB:USB_A_Stewart_SS-52100-001_Horizontal", - "USB-B": "Connector_USB:USB_B_OST_USB-B1HSxx_Horizontal", - "USB-Mini-B": "Connector_USB:USB_Mini-B_Lumberg_2486_01_Horizontal", - "USB-Micro-B": "Connector_USB:USB_Micro-B_Molex-105017-0001", - "USB-C": "Connector_USB:USB_C_Receptacle_GCT_USB4085", - - "1x2 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_1x02_P2.54mm_Vertical", - "1x3 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_1x03_P2.54mm_Vertical", - "1x4 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_1x04_P2.54mm_Vertical", - "1x5 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_1x05_P2.54mm_Vertical", - "1x6 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_1x06_P2.54mm_Vertical", - "1x8 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_1x08_P2.54mm_Vertical", - "1x10 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_1x10_P2.54mm_Vertical", - "2x2 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_2x02_P2.54mm_Vertical", - "2x3 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_2x03_P2.54mm_Vertical", - "2x4 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_2x04_P2.54mm_Vertical", - "2x5 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_2x05_P2.54mm_Vertical", - "2x10 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_2x10_P2.54mm_Vertical", - "2x20 P2.54mm": "Connector_PinHeader_2.54mm:PinHeader_2x20_P2.54mm_Vertical", - "SIP-3-2.54mm": "Package_SIP:SIP-3_P2.54mm", - "SIP-4-2.54mm": "Package_SIP:SIP-4_P2.54mm", - "SIP-5-2.54mm": "Package_SIP:SIP-5_P2.54mm" - }, - "categories": { - "Electrolytic": "Device:C_Polarized", - "Polarized": "Device:C_Polarized", - "Tantalum": "Device:C_Polarized", - "Zener": "Device:D_Zener", - "Schottky": "Device:D_Schottky", - "TVS": "Device:D_TVS", - "LED": "Device:LED", - "NPN": "Device:Q_NPN_BCE", - "PNP": "Device:Q_PNP_BCE", - "N-MOSFET": "Device:Q_NMOS_GDS", - "NMOS": "Device:Q_NMOS_GDS", - "N-MOS": "Device:Q_NMOS_GDS", - "P-MOSFET": "Device:Q_PMOS_GDS", - "PMOS": "Device:Q_PMOS_GDS", - "P-MOS": "Device:Q_PMOS_GDS", - "MOSFET": "Device:Q_NMOS_GDS", - "JFET": "Device:Q_NJFET_DSG", - "Ferrite": "Device:Ferrite_Bead", - "Crystal": "Device:Crystal", - "Oscillator": "Oscillator:Oscillator_Crystal", - "Fuse": "Device:Fuse", - "Transformer": "Device:Transformer_1P_1S", - "Resistor": "Device:R", - "Capacitor": "Device:C", - "Inductor": "Device:L", - "Diode": "Device:D", - "Transistor": "Device:Q_NPN_BCE", - "Voltage Regulator": "Regulator_Linear:LM317_TO-220", - "LDO": "Regulator_Linear:AMS1117-3.3", - "Op-Amp": "Amplifier_Operational:LM358", - "Comparator": "Comparator:LM393", - "Optocoupler": "Isolator:PC817", - "Relay": "Relay:Relay_DPDT", - "Connector": "Connector:Conn_01x02", - "Switch": "Switch:SW_Push", - "Button": "Switch:SW_Push", - "Potentiometer": "Device:R_POT", - "Trimpot": "Device:R_POT", - "Thermistor": "Device:Thermistor", - "Varistor": "Device:Varistor", - "Photo": "Device:LED" - } -} diff --git a/assets/controllers/elements/nonprintable_char_input_controller.js b/assets/controllers/elements/nonprintable_char_input_controller.js deleted file mode 100644 index bd172f1b..00000000 --- a/assets/controllers/elements/nonprintable_char_input_controller.js +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony). - * - * Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics) - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -import {Controller} from "@hotwired/stimulus"; - -/** - * Purpose of this controller is to allow users to input non-printable characters like EOT, FS, etc. in a form field and submit them correctly with the form. - * The visible input field encodes non-printable characters via their Unicode Control picture representation, e.g. \n becomes ␊ and \t becomes ␉, so that they can be displayed in the input field without breaking the form submission. - * The actual value of the field, which is submitted with the form, is stored in a hidden input and contains the non-printable characters in their original form. - */ -export default class extends Controller { - - _hiddenInput; - - connect() { - this.element.addEventListener("input", this._update.bind(this)); - - // We use a hidden input to store the actual value of the field, which is submitted with the form. - // The visible input is just for user interaction and can contain non-printable characters, which are not allowed in the hidden input. - this._hiddenInput = document.createElement("input"); - this._hiddenInput.type = "hidden"; - this._hiddenInput.name = this.element.name; - this.element.removeAttribute("name"); - this.element.parentNode.insertBefore(this._hiddenInput, this.element.nextSibling); - - this.element.addEventListener("keypress", this._onKeyPress.bind(this)); - } - - /** - * Ensures that non-printable characters like EOT, FS, etc. gets added to the input value when the user types them - * @param event - * @private - */ - _onKeyPress(event) { - const ALLOWED_INPUT_CODES = [4, 28, 29, 30, 31]; //EOT, FS, GS, RS, US - - if (!ALLOWED_INPUT_CODES.includes(event.keyCode)) { - return; - } - - event.preventDefault(); - - const char = String.fromCharCode(event.keyCode); - this.element.value += char; - - this._update(); - - - } - - _update() { - //Chrome workaround: Remove a leading ∠ character (U+2220) that appears when the user types a non-printable character at the beginning of the input field. - if (this.element.value.startsWith("∠")) { - this.element.value = this.element.value.substring(1); - } - - // Remove non-printable characters from the input value and store them in the hidden input - const normalizedValue = this.decodeNonPrintableChars(this.element.value); - this._hiddenInput.value = normalizedValue; - - // Encode non-printable characters in the visible input to their Unicode Control picture representation - const encodedValue = this.encodeNonPrintableChars(normalizedValue); - if (encodedValue !== this.element.value) { - this.element.value = encodedValue; - } - } - - /** - * Encodes non-printable characters in the given string via their Unicode Control picture representation, e.g. \n becomes ␊ and \t becomes ␉. - * This allows us to display non-printable characters in the input field without breaking the form submission. - * @param str - */ - encodeNonPrintableChars(str) { - return str.replace(/[\x00-\x1F\x7F]/g, (char) => { - const code = char.charCodeAt(0); - return String.fromCharCode(0x2400 + code); - }); - } - - /** - * Decodes the Unicode Control picture representation of non-printable characters back to their original form, e.g. ␊ becomes \n and ␉ becomes \t. - * @param str - */ - decodeNonPrintableChars(str) { - return str.replace(/[\u2400-\u241F\u2421]/g, (char) => { - const code = char.charCodeAt(0) - 0x2400; - return String.fromCharCode(code); - }); - } -} diff --git a/assets/controllers/helpers/scan_special_char_controller.js b/assets/controllers/helpers/scan_special_char_controller.js deleted file mode 100644 index 154b2a94..00000000 --- a/assets/controllers/helpers/scan_special_char_controller.js +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony). - * - * Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics) - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -import { Controller } from "@hotwired/stimulus" - -/** - * This controller listens for a special non-printable character (SOH / ASCII 1) to be entered anywhere on the page, - * which is then used as a trigger to submit the following characters as a barcode / scan input. - */ -export default class extends Controller { - connect() { - // Optional: Log to confirm global attachment - console.log("Scanner listener active") - - this.isCapturing = false - this.buffer = "" - - window.addEventListener("keypress", this.handleKeydown.bind(this)) - } - - initialize() { - this.isCapturing = false - this.buffer = "" - this.timeoutId = null - } - - handleKeydown(event) { - - // Ignore if the user is typing in a form field - const isInput = ["INPUT", "TEXTAREA", "SELECT"].includes(event.target.tagName) || - event.target.isContentEditable; - if (isInput) return - - // 1. Detect Start of Header (SOH / Ctrl+A) - if (event.key === "\x01" || event.keyCode === 1) { - this.startCapturing(event) - return - } - - // 2. Process characters if in capture mode - if (this.isCapturing) { - this.resetTimeout() // Push the expiration back with every keypress - - if (event.key === "Enter" || event.keyCode === 13) { - - this.finishCapturing(event) - } else if (event.key.length === 1) { - this.buffer += event.key - } - } - } - - startCapturing(event) { - this.isCapturing = true - this.buffer = "" - this.resetTimeout() - event.preventDefault() - console.debug("Scan character detected. Capture started...") - } - - finishCapturing(event) { - event.preventDefault() - const data = this.buffer; - this.stopCapturing() - this.processCapture(data) - } - - stopCapturing() { - this.isCapturing = false - this.buffer = "" - if (this.timeoutId) clearTimeout(this.timeoutId) - console.debug("Capture cleared/finished.") - } - - resetTimeout() { - if (this.timeoutId) clearTimeout(this.timeoutId) - - this.timeoutId = setTimeout(() => { - if (this.isCapturing) { - console.warn("Capture timed out. Resetting buffer.") - this.stopCapturing() - } - }, 500) - } - - processCapture(data) { - if (!data) return - - console.debug("Captured scan data: " + data) - - const scanInput = document.getElementById("scan_dialog_input"); - if (scanInput) { //When we are on the scan dialog page, submit the form there - this._submitScanForm(data); - } else { //Otherwise use our own form (e.g. on the part list page) - this.element.querySelector("input[name='input']").value = data; - this.element.requestSubmit(); - } - - - } - - _submitScanForm(data) { - const scanInput = document.getElementById("scan_dialog_input"); - if (!scanInput) { - console.error("Scan input field not found!") - return; - } - - scanInput.value = data; - scanInput.dispatchEvent(new Event('input', { bubbles: true })); - - const form = document.getElementById("scan_dialog_form"); - if (!form) { - console.error("Scan form not found!") - return; - } - - form.requestSubmit(); - } -} diff --git a/assets/controllers/pages/barcode_scan_controller.js b/assets/controllers/pages/barcode_scan_controller.js index bdc9c78c..ae51e951 100644 --- a/assets/controllers/pages/barcode_scan_controller.js +++ b/assets/controllers/pages/barcode_scan_controller.js @@ -114,11 +114,7 @@ export default class extends Controller { // Mark as handled immediately (prevents spam even if callback fires repeatedly) this._lastDecodedText = normalized; - const input = document.getElementById('scan_dialog_input'); - input.value = decodedText; - //Trigger nonprintable char input controller to update the hidden input value - input.dispatchEvent(new Event('input', { bubbles: true })); - + document.getElementById('scan_dialog_input').value = decodedText; //Submit form document.getElementById('scan_dialog_form').requestSubmit(); } diff --git a/composer.lock b/composer.lock index 71af9169..1daf67b5 100644 --- a/composer.lock +++ b/composer.lock @@ -968,7 +968,7 @@ }, { "name": "api-platform/doctrine-common", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/doctrine-common.git", @@ -1052,22 +1052,22 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/doctrine-common/tree/v4.3.0-alpha.2" + "source": "https://github.com/api-platform/doctrine-common/tree/v4.3.0-alpha.1" }, "time": "2026-02-13T15:07:33+00:00" }, { "name": "api-platform/doctrine-orm", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/doctrine-orm.git", - "reference": "a7d4c255519ac0438f9293b3e97d2b3bd9ca43d7" + "reference": "99d8b8cdee4ca79fd3abb351991bda6b42696eee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/doctrine-orm/zipball/a7d4c255519ac0438f9293b3e97d2b3bd9ca43d7", - "reference": "a7d4c255519ac0438f9293b3e97d2b3bd9ca43d7", + "url": "https://api.github.com/repos/api-platform/doctrine-orm/zipball/99d8b8cdee4ca79fd3abb351991bda6b42696eee", + "reference": "99d8b8cdee4ca79fd3abb351991bda6b42696eee", "shasum": "" }, "require": { @@ -1139,13 +1139,13 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/doctrine-orm/tree/v4.2.19" + "source": "https://github.com/api-platform/doctrine-orm/tree/v4.2.17" }, - "time": "2026-02-25T15:52:40+00:00" + "time": "2026-02-13T17:30:49+00:00" }, { "name": "api-platform/documentation", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/documentation.git", @@ -1202,13 +1202,13 @@ ], "description": "API Platform documentation controller.", "support": { - "source": "https://github.com/api-platform/documentation/tree/v4.3.0-alpha.2" + "source": "https://github.com/api-platform/documentation/tree/v4.3.0-alpha.1" }, "time": "2025-12-27T22:15:57+00:00" }, { "name": "api-platform/http-cache", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/http-cache.git", @@ -1282,22 +1282,22 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/http-cache/tree/v4.3.0-alpha.2" + "source": "https://github.com/api-platform/http-cache/tree/v4.3.0-alpha.1" }, "time": "2026-02-13T15:07:33+00:00" }, { "name": "api-platform/hydra", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/hydra.git", - "reference": "3f2587cc3b98f46247ca458ba557c03f62e19905" + "reference": "392c44574a7746de03564d709c4eb5c652509440" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/hydra/zipball/3f2587cc3b98f46247ca458ba557c03f62e19905", - "reference": "3f2587cc3b98f46247ca458ba557c03f62e19905", + "url": "https://api.github.com/repos/api-platform/hydra/zipball/392c44574a7746de03564d709c4eb5c652509440", + "reference": "392c44574a7746de03564d709c4eb5c652509440", "shasum": "" }, "require": { @@ -1369,29 +1369,29 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/hydra/tree/v4.2.19" + "source": "https://github.com/api-platform/hydra/tree/v4.2.17" }, - "time": "2026-02-27T10:31:31+00:00" + "time": "2026-02-17T13:24:02+00:00" }, { "name": "api-platform/json-api", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/json-api.git", - "reference": "d28b51d78c50451e6714ed7a0c673ec6d9070900" + "reference": "6c5b5b83f693667371b7b31a65a50925e10c6d46" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/json-api/zipball/d28b51d78c50451e6714ed7a0c673ec6d9070900", - "reference": "d28b51d78c50451e6714ed7a0c673ec6d9070900", + "url": "https://api.github.com/repos/api-platform/json-api/zipball/6c5b5b83f693667371b7b31a65a50925e10c6d46", + "reference": "6c5b5b83f693667371b7b31a65a50925e10c6d46", "shasum": "" }, "require": { "api-platform/documentation": "^4.2", "api-platform/json-schema": "^4.2", "api-platform/metadata": "^4.2", - "api-platform/serializer": "^4.2.18", + "api-platform/serializer": "^4.2.4", "api-platform/state": "^4.2.4", "php": ">=8.2", "symfony/error-handler": "^6.4 || ^7.0 || ^8.0", @@ -1451,22 +1451,22 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/json-api/tree/v4.2.19" + "source": "https://github.com/api-platform/json-api/tree/v4.2.17" }, - "time": "2026-02-27T16:03:48+00:00" + "time": "2026-02-13T17:30:49+00:00" }, { "name": "api-platform/json-schema", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/json-schema.git", - "reference": "adc464d8240ac411ff8ed65ac8614b16d11f5544" + "reference": "de96f482b6dcf913a2849a71ae102d2e45a61b52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/json-schema/zipball/adc464d8240ac411ff8ed65ac8614b16d11f5544", - "reference": "adc464d8240ac411ff8ed65ac8614b16d11f5544", + "url": "https://api.github.com/repos/api-platform/json-schema/zipball/de96f482b6dcf913a2849a71ae102d2e45a61b52", + "reference": "de96f482b6dcf913a2849a71ae102d2e45a61b52", "shasum": "" }, "require": { @@ -1532,13 +1532,13 @@ "swagger" ], "support": { - "source": "https://github.com/api-platform/json-schema/tree/v4.2.19" + "source": "https://github.com/api-platform/json-schema/tree/v4.2.17" }, - "time": "2026-02-25T15:52:40+00:00" + "time": "2026-02-20T20:33:01+00:00" }, { "name": "api-platform/jsonld", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/jsonld.git", @@ -1612,22 +1612,22 @@ "rest" ], "support": { - "source": "https://github.com/api-platform/jsonld/tree/v4.2.19" + "source": "https://github.com/api-platform/jsonld/tree/v4.2.17" }, "time": "2026-02-13T17:30:49+00:00" }, { "name": "api-platform/metadata", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/metadata.git", - "reference": "af91b0d349b2aa8afffe100cce544b4d72add3eb" + "reference": "f90cd4258477821e0174788a6666507824c7c6b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/metadata/zipball/af91b0d349b2aa8afffe100cce544b4d72add3eb", - "reference": "af91b0d349b2aa8afffe100cce544b4d72add3eb", + "url": "https://api.github.com/repos/api-platform/metadata/zipball/f90cd4258477821e0174788a6666507824c7c6b9", + "reference": "f90cd4258477821e0174788a6666507824c7c6b9", "shasum": "" }, "require": { @@ -1710,13 +1710,13 @@ "swagger" ], "support": { - "source": "https://github.com/api-platform/metadata/tree/v4.2.19" + "source": "https://github.com/api-platform/metadata/tree/v4.2.17" }, - "time": "2026-02-25T15:52:40+00:00" + "time": "2026-02-13T15:07:33+00:00" }, { "name": "api-platform/openapi", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/openapi.git", @@ -1800,22 +1800,22 @@ "swagger" ], "support": { - "source": "https://github.com/api-platform/openapi/tree/v4.2.19" + "source": "https://github.com/api-platform/openapi/tree/v4.2.17" }, "time": "2026-01-26T15:38:30+00:00" }, { "name": "api-platform/serializer", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/serializer.git", - "reference": "bd627b86c0cb37bd2c2ca6b7f996d5301627f627" + "reference": "f021a31e6a409e8c3fd24bee1e5e183b995f9137" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/serializer/zipball/bd627b86c0cb37bd2c2ca6b7f996d5301627f627", - "reference": "bd627b86c0cb37bd2c2ca6b7f996d5301627f627", + "url": "https://api.github.com/repos/api-platform/serializer/zipball/f021a31e6a409e8c3fd24bee1e5e183b995f9137", + "reference": "f021a31e6a409e8c3fd24bee1e5e183b995f9137", "shasum": "" }, "require": { @@ -1893,13 +1893,13 @@ "serializer" ], "support": { - "source": "https://github.com/api-platform/serializer/tree/v4.2.19" + "source": "https://github.com/api-platform/serializer/tree/v4.2.17" }, - "time": "2026-02-27T16:03:48+00:00" + "time": "2026-02-20T09:35:37+00:00" }, { "name": "api-platform/state", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/state.git", @@ -1990,22 +1990,22 @@ "swagger" ], "support": { - "source": "https://github.com/api-platform/state/tree/v4.2.19" + "source": "https://github.com/api-platform/state/tree/v4.2.17" }, "time": "2026-02-17T09:18:17+00:00" }, { "name": "api-platform/symfony", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/symfony.git", - "reference": "3ed112cd9e278a5ba2d7b663df04861a3c4ba905" + "reference": "04052b61e26a1c059bb595b78670302ad4517b7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/symfony/zipball/3ed112cd9e278a5ba2d7b663df04861a3c4ba905", - "reference": "3ed112cd9e278a5ba2d7b663df04861a3c4ba905", + "url": "https://api.github.com/repos/api-platform/symfony/zipball/04052b61e26a1c059bb595b78670302ad4517b7f", + "reference": "04052b61e26a1c059bb595b78670302ad4517b7f", "shasum": "" }, "require": { @@ -2118,13 +2118,13 @@ "symfony" ], "support": { - "source": "https://github.com/api-platform/symfony/tree/v4.2.19" + "source": "https://github.com/api-platform/symfony/tree/v4.2.17" }, - "time": "2026-02-27T10:22:56+00:00" + "time": "2026-02-18T14:55:07+00:00" }, { "name": "api-platform/validator", - "version": "v4.2.19", + "version": "v4.2.17", "source": { "type": "git", "url": "https://github.com/api-platform/validator.git", @@ -2194,7 +2194,7 @@ "validator" ], "support": { - "source": "https://github.com/api-platform/validator/tree/v4.2.19" + "source": "https://github.com/api-platform/validator/tree/v4.2.17" }, "time": "2026-01-26T15:45:40+00:00" }, @@ -3103,16 +3103,16 @@ }, { "name": "doctrine/dbal", - "version": "4.4.2", + "version": "4.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "476f7f0fa6ea4aa5364926db7fabdf6049075722" + "reference": "3d544473fb93f5c25b483ea4f4ce99f8c4d9d44c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/476f7f0fa6ea4aa5364926db7fabdf6049075722", - "reference": "476f7f0fa6ea4aa5364926db7fabdf6049075722", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/3d544473fb93f5c25b483ea4f4ce99f8c4d9d44c", + "reference": "3d544473fb93f5c25b483ea4f4ce99f8c4d9d44c", "shasum": "" }, "require": { @@ -3128,9 +3128,9 @@ "phpstan/phpstan": "2.1.30", "phpstan/phpstan-phpunit": "2.0.7", "phpstan/phpstan-strict-rules": "^2", - "phpunit/phpunit": "11.5.50", - "slevomat/coding-standard": "8.27.1", - "squizlabs/php_codesniffer": "4.0.1", + "phpunit/phpunit": "11.5.23", + "slevomat/coding-standard": "8.24.0", + "squizlabs/php_codesniffer": "4.0.0", "symfony/cache": "^6.3.8|^7.0|^8.0", "symfony/console": "^5.4|^6.3|^7.0|^8.0" }, @@ -3189,7 +3189,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/4.4.2" + "source": "https://github.com/doctrine/dbal/tree/4.4.1" }, "funding": [ { @@ -3205,7 +3205,7 @@ "type": "tidelift" } ], - "time": "2026-02-26T12:12:19+00:00" + "time": "2025-12-04T10:11:03+00:00" }, { "name": "doctrine/deprecations", @@ -5108,16 +5108,16 @@ }, { "name": "jbtronics/settings-bundle", - "version": "v3.2.1", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/jbtronics/settings-bundle.git", - "reference": "9cce5f59482e66417166354072c7e24790495b9b" + "reference": "6a66c099460fd623d0d1ddbf9864b3173d416c3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jbtronics/settings-bundle/zipball/9cce5f59482e66417166354072c7e24790495b9b", - "reference": "9cce5f59482e66417166354072c7e24790495b9b", + "url": "https://api.github.com/repos/jbtronics/settings-bundle/zipball/6a66c099460fd623d0d1ddbf9864b3173d416c3b", + "reference": "6a66c099460fd623d0d1ddbf9864b3173d416c3b", "shasum": "" }, "require": { @@ -5130,7 +5130,7 @@ "symfony/translation": "^7.0|^6.4|^8.0", "symfony/translation-contracts": "^2.5|^3.0", "symfony/validator": "^6.4|^7.0|^8.0", - "symfony/var-exporter": "^6.4|^7.0|^8.0" + "symfony/var-exporter": "^6.4|^7.0" }, "require-dev": { "doctrine/doctrine-bundle": "^2.11", @@ -5178,7 +5178,7 @@ ], "support": { "issues": "https://github.com/jbtronics/settings-bundle/issues", - "source": "https://github.com/jbtronics/settings-bundle/tree/v3.2.1" + "source": "https://github.com/jbtronics/settings-bundle/tree/v3.2.0" }, "funding": [ { @@ -5190,7 +5190,7 @@ "type": "github" } ], - "time": "2026-02-28T16:30:47+00:00" + "time": "2026-02-03T20:13:02+00:00" }, { "name": "jfcherng/php-color-output", @@ -7163,16 +7163,16 @@ }, { "name": "nelmio/security-bundle", - "version": "v3.9.0", + "version": "v3.8.0", "source": { "type": "git", "url": "https://github.com/nelmio/NelmioSecurityBundle.git", - "reference": "86dd4d12bc729498cd6f52b95ab6b36a66c72fd2" + "reference": "2fafee1cdda1d5952554c44eef4c3c8566d56f40" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nelmio/NelmioSecurityBundle/zipball/86dd4d12bc729498cd6f52b95ab6b36a66c72fd2", - "reference": "86dd4d12bc729498cd6f52b95ab6b36a66c72fd2", + "url": "https://api.github.com/repos/nelmio/NelmioSecurityBundle/zipball/2fafee1cdda1d5952554c44eef4c3c8566d56f40", + "reference": "2fafee1cdda1d5952554c44eef4c3c8566d56f40", "shasum": "" }, "require": { @@ -7231,22 +7231,22 @@ ], "support": { "issues": "https://github.com/nelmio/NelmioSecurityBundle/issues", - "source": "https://github.com/nelmio/NelmioSecurityBundle/tree/v3.9.0" + "source": "https://github.com/nelmio/NelmioSecurityBundle/tree/v3.8.0" }, - "time": "2026-02-23T10:58:33+00:00" + "time": "2026-01-14T19:38:55+00:00" }, { "name": "nette/schema", - "version": "v1.3.5", + "version": "v1.3.4", "source": { "type": "git", "url": "https://github.com/nette/schema.git", - "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002" + "reference": "086497a2f34b82fede9b5a41cc8e131d087cd8f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/f0ab1a3cda782dbc5da270d28545236aa80c4002", - "reference": "f0ab1a3cda782dbc5da270d28545236aa80c4002", + "url": "https://api.github.com/repos/nette/schema/zipball/086497a2f34b82fede9b5a41cc8e131d087cd8f7", + "reference": "086497a2f34b82fede9b5a41cc8e131d087cd8f7", "shasum": "" }, "require": { @@ -7254,10 +7254,8 @@ "php": "8.1 - 8.5" }, "require-dev": { - "nette/phpstan-rules": "^1.0", "nette/tester": "^2.6", - "phpstan/extension-installer": "^1.4@stable", - "phpstan/phpstan": "^2.1.39@stable", + "phpstan/phpstan": "^2.0@stable", "tracy/tracy": "^2.8" }, "type": "library", @@ -7298,9 +7296,9 @@ ], "support": { "issues": "https://github.com/nette/schema/issues", - "source": "https://github.com/nette/schema/tree/v1.3.5" + "source": "https://github.com/nette/schema/tree/v1.3.4" }, - "time": "2026-02-23T03:47:12+00:00" + "time": "2026-02-08T02:54:00+00:00" }, { "name": "nette/utils", @@ -8463,16 +8461,16 @@ }, { "name": "phpoffice/phpspreadsheet", - "version": "5.5.0", + "version": "5.4.0", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "eecd31b885a1c8192f12738130f85bbc6e8906ba" + "reference": "48f2fe37d64c2dece0ef71fb2ac55497566782af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/eecd31b885a1c8192f12738130f85bbc6e8906ba", - "reference": "eecd31b885a1c8192f12738130f85bbc6e8906ba", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/48f2fe37d64c2dece0ef71fb2ac55497566782af", + "reference": "48f2fe37d64c2dece0ef71fb2ac55497566782af", "shasum": "" }, "require": { @@ -8566,9 +8564,9 @@ ], "support": { "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.5.0" + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.4.0" }, - "time": "2026-03-01T00:58:56+00:00" + "time": "2026-01-11T04:52:00+00:00" }, { "name": "phpstan/phpdoc-parser", @@ -10262,16 +10260,16 @@ }, { "name": "symfony/asset", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "d944ae87e4697af05aadeacfc5e603c3c18ef4fb" + "reference": "a6f49cf087a1fcfe7130b9b604a8a2b878b06c40" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/d944ae87e4697af05aadeacfc5e603c3c18ef4fb", - "reference": "d944ae87e4697af05aadeacfc5e603c3c18ef4fb", + "url": "https://api.github.com/repos/symfony/asset/zipball/a6f49cf087a1fcfe7130b9b604a8a2b878b06c40", + "reference": "a6f49cf087a1fcfe7130b9b604a8a2b878b06c40", "shasum": "" }, "require": { @@ -10311,7 +10309,7 @@ "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/asset/tree/v7.4.6" + "source": "https://github.com/symfony/asset/tree/v7.4.4" }, "funding": [ { @@ -10331,20 +10329,20 @@ "type": "tidelift" } ], - "time": "2026-02-09T09:33:46+00:00" + "time": "2026-01-13T10:40:19+00:00" }, { "name": "symfony/cache", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "1d06192e8f164e2729b0031e6807d72a6195b8bb" + "reference": "8dde98d5a4123b53877aca493f9be57b333f14bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/1d06192e8f164e2729b0031e6807d72a6195b8bb", - "reference": "1d06192e8f164e2729b0031e6807d72a6195b8bb", + "url": "https://api.github.com/repos/symfony/cache/zipball/8dde98d5a4123b53877aca493f9be57b333f14bd", + "reference": "8dde98d5a4123b53877aca493f9be57b333f14bd", "shasum": "" }, "require": { @@ -10415,7 +10413,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v7.4.6" + "source": "https://github.com/symfony/cache/tree/v7.4.5" }, "funding": [ { @@ -10435,7 +10433,7 @@ "type": "tidelift" } ], - "time": "2026-02-21T23:29:27+00:00" + "time": "2026-01-27T16:16:02+00:00" }, { "name": "symfony/cache-contracts", @@ -10593,16 +10591,16 @@ }, { "name": "symfony/config", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "9400e2f9226b3b64ebb0a8ae967ae84e54e39640" + "reference": "4275b53b8ab0cf37f48bf273dc2285c8178efdfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/9400e2f9226b3b64ebb0a8ae967ae84e54e39640", - "reference": "9400e2f9226b3b64ebb0a8ae967ae84e54e39640", + "url": "https://api.github.com/repos/symfony/config/zipball/4275b53b8ab0cf37f48bf273dc2285c8178efdfb", + "reference": "4275b53b8ab0cf37f48bf273dc2285c8178efdfb", "shasum": "" }, "require": { @@ -10648,7 +10646,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.4.6" + "source": "https://github.com/symfony/config/tree/v7.4.4" }, "funding": [ { @@ -10668,20 +10666,20 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2026-01-13T11:36:38+00:00" }, { "name": "symfony/console", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "6d643a93b47398599124022eb24d97c153c12f27" + "reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/6d643a93b47398599124022eb24d97c153c12f27", - "reference": "6d643a93b47398599124022eb24d97c153c12f27", + "url": "https://api.github.com/repos/symfony/console/zipball/41e38717ac1dd7a46b6bda7d6a82af2d98a78894", + "reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894", "shasum": "" }, "require": { @@ -10746,7 +10744,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.4.6" + "source": "https://github.com/symfony/console/tree/v7.4.4" }, "funding": [ { @@ -10766,20 +10764,20 @@ "type": "tidelift" } ], - "time": "2026-02-25T17:02:47+00:00" + "time": "2026-01-13T11:36:38+00:00" }, { "name": "symfony/css-selector", - "version": "v7.4.6", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "2e7c52c647b406e2107dd867db424a4dbac91864" + "reference": "ab862f478513e7ca2fe9ec117a6f01a8da6e1135" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/2e7c52c647b406e2107dd867db424a4dbac91864", - "reference": "2e7c52c647b406e2107dd867db424a4dbac91864", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/ab862f478513e7ca2fe9ec117a6f01a8da6e1135", + "reference": "ab862f478513e7ca2fe9ec117a6f01a8da6e1135", "shasum": "" }, "require": { @@ -10815,7 +10813,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.4.6" + "source": "https://github.com/symfony/css-selector/tree/v7.4.0" }, "funding": [ { @@ -10835,20 +10833,20 @@ "type": "tidelift" } ], - "time": "2026-02-17T07:53:42+00:00" + "time": "2025-10-30T13:39:42+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "a3f7d594ca53a34a7d39ae683fbca09408b0c598" + "reference": "76a02cddca45a5254479ad68f9fa274ead0a7ef2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/a3f7d594ca53a34a7d39ae683fbca09408b0c598", - "reference": "a3f7d594ca53a34a7d39ae683fbca09408b0c598", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/76a02cddca45a5254479ad68f9fa274ead0a7ef2", + "reference": "76a02cddca45a5254479ad68f9fa274ead0a7ef2", "shasum": "" }, "require": { @@ -10899,7 +10897,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.4.6" + "source": "https://github.com/symfony/dependency-injection/tree/v7.4.5" }, "funding": [ { @@ -10919,7 +10917,7 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2026-01-27T16:16:02+00:00" }, { "name": "symfony/deprecation-contracts", @@ -10990,16 +10988,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "710cb7313446aa5ce67e2da06c01f1640dfbdcc6" + "reference": "3408d9fb7bda6c8db9f3e4099863c9017bcbc62d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/710cb7313446aa5ce67e2da06c01f1640dfbdcc6", - "reference": "710cb7313446aa5ce67e2da06c01f1640dfbdcc6", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/3408d9fb7bda6c8db9f3e4099863c9017bcbc62d", + "reference": "3408d9fb7bda6c8db9f3e4099863c9017bcbc62d", "shasum": "" }, "require": { @@ -11079,7 +11077,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v7.4.6" + "source": "https://github.com/symfony/doctrine-bridge/tree/v7.4.4" }, "funding": [ { @@ -11099,20 +11097,20 @@ "type": "tidelift" } ], - "time": "2026-02-17T08:07:48+00:00" + "time": "2026-01-20T16:42:42+00:00" }, { "name": "symfony/dom-crawler", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "487ba8fa43da9a8e6503fe939b45ecd96875410e" + "reference": "71fd6a82fc357c8b5de22f78b228acfc43dee965" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/487ba8fa43da9a8e6503fe939b45ecd96875410e", - "reference": "487ba8fa43da9a8e6503fe939b45ecd96875410e", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/71fd6a82fc357c8b5de22f78b228acfc43dee965", + "reference": "71fd6a82fc357c8b5de22f78b228acfc43dee965", "shasum": "" }, "require": { @@ -11151,7 +11149,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v7.4.6" + "source": "https://github.com/symfony/dom-crawler/tree/v7.4.4" }, "funding": [ { @@ -11171,20 +11169,20 @@ "type": "tidelift" } ], - "time": "2026-02-17T07:53:42+00:00" + "time": "2026-01-05T08:47:25+00:00" }, { "name": "symfony/dotenv", - "version": "v7.4.6", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "db374255a1c99511d34d5e009dce5be75d0d9c23" + "reference": "1658a4d34df028f3d93bcdd8e81f04423925a364" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/db374255a1c99511d34d5e009dce5be75d0d9c23", - "reference": "db374255a1c99511d34d5e009dce5be75d0d9c23", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/1658a4d34df028f3d93bcdd8e81f04423925a364", + "reference": "1658a4d34df028f3d93bcdd8e81f04423925a364", "shasum": "" }, "require": { @@ -11229,7 +11227,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v7.4.6" + "source": "https://github.com/symfony/dotenv/tree/v7.4.0" }, "funding": [ { @@ -11249,7 +11247,7 @@ "type": "tidelift" } ], - "time": "2026-02-13T11:43:08+00:00" + "time": "2025-11-16T10:14:42+00:00" }, { "name": "symfony/error-handler", @@ -11564,16 +11562,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.4.6", + "version": "v7.4.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "3ebc794fa5315e59fd122561623c2e2e4280538e" + "reference": "d551b38811096d0be9c4691d406991b47c0c630a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/3ebc794fa5315e59fd122561623c2e2e4280538e", - "reference": "3ebc794fa5315e59fd122561623c2e2e4280538e", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/d551b38811096d0be9c4691d406991b47c0c630a", + "reference": "d551b38811096d0be9c4691d406991b47c0c630a", "shasum": "" }, "require": { @@ -11610,7 +11608,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.4.6" + "source": "https://github.com/symfony/filesystem/tree/v7.4.0" }, "funding": [ { @@ -11630,20 +11628,20 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2025-11-27T13:27:24+00:00" }, { "name": "symfony/finder", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "8655bf1076b7a3a346cb11413ffdabff50c7ffcf" + "reference": "ad4daa7c38668dcb031e63bc99ea9bd42196a2cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/8655bf1076b7a3a346cb11413ffdabff50c7ffcf", - "reference": "8655bf1076b7a3a346cb11413ffdabff50c7ffcf", + "url": "https://api.github.com/repos/symfony/finder/zipball/ad4daa7c38668dcb031e63bc99ea9bd42196a2cb", + "reference": "ad4daa7c38668dcb031e63bc99ea9bd42196a2cb", "shasum": "" }, "require": { @@ -11678,7 +11676,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.4.6" + "source": "https://github.com/symfony/finder/tree/v7.4.5" }, "funding": [ { @@ -11698,7 +11696,7 @@ "type": "tidelift" } ], - "time": "2026-01-29T09:40:50+00:00" + "time": "2026-01-26T15:07:59+00:00" }, { "name": "symfony/flex", @@ -11775,16 +11773,16 @@ }, { "name": "symfony/form", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/form.git", - "reference": "1ec55f7b1a6152760a670415c334f70a08d264f9" + "reference": "264fc873f01376216f0b884ecc81b34b830e25a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/form/zipball/1ec55f7b1a6152760a670415c334f70a08d264f9", - "reference": "1ec55f7b1a6152760a670415c334f70a08d264f9", + "url": "https://api.github.com/repos/symfony/form/zipball/264fc873f01376216f0b884ecc81b34b830e25a8", + "reference": "264fc873f01376216f0b884ecc81b34b830e25a8", "shasum": "" }, "require": { @@ -11854,7 +11852,7 @@ "description": "Allows to easily create, process and reuse HTML forms", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/form/tree/v7.4.6" + "source": "https://github.com/symfony/form/tree/v7.4.4" }, "funding": [ { @@ -11874,20 +11872,20 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2026-01-23T10:51:15+00:00" }, { "name": "symfony/framework-bundle", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "a4022da7530f794aa64cea34b388439afb6323a3" + "reference": "dcf89ca6712d9e1b5d3f14dea0e1c2685a05d1cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/a4022da7530f794aa64cea34b388439afb6323a3", - "reference": "a4022da7530f794aa64cea34b388439afb6323a3", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/dcf89ca6712d9e1b5d3f14dea0e1c2685a05d1cd", + "reference": "dcf89ca6712d9e1b5d3f14dea0e1c2685a05d1cd", "shasum": "" }, "require": { @@ -11910,7 +11908,7 @@ }, "conflict": { "doctrine/persistence": "<1.3", - "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/reflection-docblock": "<5.2|>=6", "phpdocumentor/type-resolver": "<1.5.1", "symfony/asset": "<6.4", "symfony/asset-mapper": "<6.4", @@ -11943,7 +11941,7 @@ "require-dev": { "doctrine/persistence": "^1.3|^2|^3", "dragonmantank/cron-expression": "^3.1", - "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "phpdocumentor/reflection-docblock": "^5.2", "seld/jsonlint": "^1.10", "symfony/asset": "^6.4|^7.0|^8.0", "symfony/asset-mapper": "^6.4|^7.0|^8.0", @@ -12012,7 +12010,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v7.4.6" + "source": "https://github.com/symfony/framework-bundle/tree/v7.4.5" }, "funding": [ { @@ -12032,20 +12030,20 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2026-01-27T08:59:58+00:00" }, { "name": "symfony/http-client", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "2bde8afd5ab2fe0b05a9c2d4c3c0e28ceb98a154" + "reference": "84bb634857a893cc146cceb467e31b3f02c5fe9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/2bde8afd5ab2fe0b05a9c2d4c3c0e28ceb98a154", - "reference": "2bde8afd5ab2fe0b05a9c2d4c3c0e28ceb98a154", + "url": "https://api.github.com/repos/symfony/http-client/zipball/84bb634857a893cc146cceb467e31b3f02c5fe9f", + "reference": "84bb634857a893cc146cceb467e31b3f02c5fe9f", "shasum": "" }, "require": { @@ -12113,7 +12111,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v7.4.6" + "source": "https://github.com/symfony/http-client/tree/v7.4.5" }, "funding": [ { @@ -12133,7 +12131,7 @@ "type": "tidelift" } ], - "time": "2026-02-18T09:46:18+00:00" + "time": "2026-01-27T16:16:02+00:00" }, { "name": "symfony/http-client-contracts", @@ -12215,16 +12213,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "fd97d5e926e988a363cef56fbbf88c5c528e9065" + "reference": "446d0db2b1f21575f1284b74533e425096abdfb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/fd97d5e926e988a363cef56fbbf88c5c528e9065", - "reference": "fd97d5e926e988a363cef56fbbf88c5c528e9065", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/446d0db2b1f21575f1284b74533e425096abdfb6", + "reference": "446d0db2b1f21575f1284b74533e425096abdfb6", "shasum": "" }, "require": { @@ -12273,7 +12271,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.4.6" + "source": "https://github.com/symfony/http-foundation/tree/v7.4.5" }, "funding": [ { @@ -12293,20 +12291,20 @@ "type": "tidelift" } ], - "time": "2026-02-21T16:25:55+00:00" + "time": "2026-01-27T16:16:02+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "002ac0cf4cd972a7fd0912dcd513a95e8a81ce83" + "reference": "229eda477017f92bd2ce7615d06222ec0c19e82a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/002ac0cf4cd972a7fd0912dcd513a95e8a81ce83", - "reference": "002ac0cf4cd972a7fd0912dcd513a95e8a81ce83", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/229eda477017f92bd2ce7615d06222ec0c19e82a", + "reference": "229eda477017f92bd2ce7615d06222ec0c19e82a", "shasum": "" }, "require": { @@ -12348,7 +12346,7 @@ "symfony/config": "^6.4|^7.0|^8.0", "symfony/console": "^6.4|^7.0|^8.0", "symfony/css-selector": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4.1|^7.0.1|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", "symfony/dom-crawler": "^6.4|^7.0|^8.0", "symfony/expression-language": "^6.4|^7.0|^8.0", "symfony/finder": "^6.4|^7.0|^8.0", @@ -12392,7 +12390,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.4.6" + "source": "https://github.com/symfony/http-kernel/tree/v7.4.5" }, "funding": [ { @@ -12412,20 +12410,20 @@ "type": "tidelift" } ], - "time": "2026-02-26T08:30:57+00:00" + "time": "2026-01-28T10:33:42+00:00" }, { "name": "symfony/intl", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/intl.git", - "reference": "6d6a398b18f73b3110140dbb030dcee2ae4ea81f" + "reference": "7fa2d46174166bcd7829abc8717949f8a0b21fb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/intl/zipball/6d6a398b18f73b3110140dbb030dcee2ae4ea81f", - "reference": "6d6a398b18f73b3110140dbb030dcee2ae4ea81f", + "url": "https://api.github.com/repos/symfony/intl/zipball/7fa2d46174166bcd7829abc8717949f8a0b21fb7", + "reference": "7fa2d46174166bcd7829abc8717949f8a0b21fb7", "shasum": "" }, "require": { @@ -12482,7 +12480,7 @@ "localization" ], "support": { - "source": "https://github.com/symfony/intl/tree/v7.4.6" + "source": "https://github.com/symfony/intl/tree/v7.4.4" }, "funding": [ { @@ -12502,20 +12500,20 @@ "type": "tidelift" } ], - "time": "2026-02-09T09:33:46+00:00" + "time": "2026-01-12T12:19:02+00:00" }, { "name": "symfony/mailer", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "b02726f39a20bc65e30364f5c750c4ddbf1f58e9" + "reference": "7b750074c40c694ceb34cb926d6dffee231c5cd6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/b02726f39a20bc65e30364f5c750c4ddbf1f58e9", - "reference": "b02726f39a20bc65e30364f5c750c4ddbf1f58e9", + "url": "https://api.github.com/repos/symfony/mailer/zipball/7b750074c40c694ceb34cb926d6dffee231c5cd6", + "reference": "7b750074c40c694ceb34cb926d6dffee231c5cd6", "shasum": "" }, "require": { @@ -12566,7 +12564,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v7.4.6" + "source": "https://github.com/symfony/mailer/tree/v7.4.4" }, "funding": [ { @@ -12586,20 +12584,20 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2026-01-08T08:25:11+00:00" }, { "name": "symfony/mime", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "9fc881d95feae4c6c48678cb6372bd8a7ba04f5f" + "reference": "b18c7e6e9eee1e19958138df10412f3c4c316148" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/9fc881d95feae4c6c48678cb6372bd8a7ba04f5f", - "reference": "9fc881d95feae4c6c48678cb6372bd8a7ba04f5f", + "url": "https://api.github.com/repos/symfony/mime/zipball/b18c7e6e9eee1e19958138df10412f3c4c316148", + "reference": "b18c7e6e9eee1e19958138df10412f3c4c316148", "shasum": "" }, "require": { @@ -12610,7 +12608,7 @@ }, "conflict": { "egulias/email-validator": "~3.0.0", - "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/reflection-docblock": "<5.2|>=6", "phpdocumentor/type-resolver": "<1.5.1", "symfony/mailer": "<6.4", "symfony/serializer": "<6.4.3|>7.0,<7.0.3" @@ -12618,7 +12616,7 @@ "require-dev": { "egulias/email-validator": "^2.1.10|^3.1|^4", "league/html-to-markdown": "^5.0", - "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "phpdocumentor/reflection-docblock": "^5.2", "symfony/dependency-injection": "^6.4|^7.0|^8.0", "symfony/process": "^6.4|^7.0|^8.0", "symfony/property-access": "^6.4|^7.0|^8.0", @@ -12655,7 +12653,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.4.6" + "source": "https://github.com/symfony/mime/tree/v7.4.5" }, "funding": [ { @@ -12675,20 +12673,20 @@ "type": "tidelift" } ], - "time": "2026-02-05T15:57:06+00:00" + "time": "2026-01-27T08:59:58+00:00" }, { "name": "symfony/monolog-bridge", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/monolog-bridge.git", - "reference": "69e98e7e10dae3daa896ef0f20e17a3928362d88" + "reference": "9c34e8170b09f062a9a38880a3cb58ee35cb7fd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/69e98e7e10dae3daa896ef0f20e17a3928362d88", - "reference": "69e98e7e10dae3daa896ef0f20e17a3928362d88", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/9c34e8170b09f062a9a38880a3cb58ee35cb7fd4", + "reference": "9c34e8170b09f062a9a38880a3cb58ee35cb7fd4", "shasum": "" }, "require": { @@ -12738,7 +12736,7 @@ "description": "Provides integration for Monolog with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/monolog-bridge/tree/v7.4.6" + "source": "https://github.com/symfony/monolog-bridge/tree/v7.4.4" }, "funding": [ { @@ -12758,7 +12756,7 @@ "type": "tidelift" } ], - "time": "2026-02-17T07:53:42+00:00" + "time": "2026-01-07T11:35:36+00:00" }, { "name": "symfony/monolog-bundle", @@ -12912,16 +12910,16 @@ }, { "name": "symfony/password-hasher", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/password-hasher.git", - "reference": "376755eb9c9857d78aedb68341ad2f46d1908b29" + "reference": "ab8e0ef42483f31c417c82ecfcf7be7b91d784fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/password-hasher/zipball/376755eb9c9857d78aedb68341ad2f46d1908b29", - "reference": "376755eb9c9857d78aedb68341ad2f46d1908b29", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/ab8e0ef42483f31c417c82ecfcf7be7b91d784fe", + "reference": "ab8e0ef42483f31c417c82ecfcf7be7b91d784fe", "shasum": "" }, "require": { @@ -12964,7 +12962,7 @@ "password" ], "support": { - "source": "https://github.com/symfony/password-hasher/tree/v7.4.6" + "source": "https://github.com/symfony/password-hasher/tree/v7.4.4" }, "funding": [ { @@ -12984,7 +12982,7 @@ "type": "tidelift" } ], - "time": "2026-02-11T16:03:16+00:00" + "time": "2026-01-01T22:13:48+00:00" }, { "name": "symfony/polyfill-ctype", @@ -13882,16 +13880,16 @@ }, { "name": "symfony/property-info", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "6396b28f44d7c28b209a1bd73acf0dd985a0a4ef" + "reference": "1c9d326bd69602561e2ea467a16c09b5972eee21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/6396b28f44d7c28b209a1bd73acf0dd985a0a4ef", - "reference": "6396b28f44d7c28b209a1bd73acf0dd985a0a4ef", + "url": "https://api.github.com/repos/symfony/property-info/zipball/1c9d326bd69602561e2ea467a16c09b5972eee21", + "reference": "1c9d326bd69602561e2ea467a16c09b5972eee21", "shasum": "" }, "require": { @@ -13901,14 +13899,14 @@ "symfony/type-info": "~7.3.10|^7.4.4|^8.0.4" }, "conflict": { - "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/reflection-docblock": "<5.2|>=6", "phpdocumentor/type-resolver": "<1.5.1", "symfony/cache": "<6.4", "symfony/dependency-injection": "<6.4", "symfony/serializer": "<6.4" }, "require-dev": { - "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "phpdocumentor/reflection-docblock": "^5.2", "phpstan/phpdoc-parser": "^1.0|^2.0", "symfony/cache": "^6.4|^7.0|^8.0", "symfony/dependency-injection": "^6.4|^7.0|^8.0", @@ -13948,7 +13946,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v7.4.6" + "source": "https://github.com/symfony/property-info/tree/v7.4.5" }, "funding": [ { @@ -13968,7 +13966,7 @@ "type": "tidelift" } ], - "time": "2026-02-13T11:51:31+00:00" + "time": "2026-01-27T16:16:02+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -14060,16 +14058,16 @@ }, { "name": "symfony/rate-limiter", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/rate-limiter.git", - "reference": "7219be81396041c24c1d12241ca7ef1f88b80783" + "reference": "7e275c57293cd2d894e126cc68855ecd82bcd173" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/7219be81396041c24c1d12241ca7ef1f88b80783", - "reference": "7219be81396041c24c1d12241ca7ef1f88b80783", + "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/7e275c57293cd2d894e126cc68855ecd82bcd173", + "reference": "7e275c57293cd2d894e126cc68855ecd82bcd173", "shasum": "" }, "require": { @@ -14110,7 +14108,7 @@ "rate-limiter" ], "support": { - "source": "https://github.com/symfony/rate-limiter/tree/v7.4.6" + "source": "https://github.com/symfony/rate-limiter/tree/v7.4.5" }, "funding": [ { @@ -14130,20 +14128,20 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2026-01-27T16:16:02+00:00" }, { "name": "symfony/routing", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "238d749c56b804b31a9bf3e26519d93b65a60938" + "reference": "0798827fe2c79caeed41d70b680c2c3507d10147" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/238d749c56b804b31a9bf3e26519d93b65a60938", - "reference": "238d749c56b804b31a9bf3e26519d93b65a60938", + "url": "https://api.github.com/repos/symfony/routing/zipball/0798827fe2c79caeed41d70b680c2c3507d10147", + "reference": "0798827fe2c79caeed41d70b680c2c3507d10147", "shasum": "" }, "require": { @@ -14195,7 +14193,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v7.4.6" + "source": "https://github.com/symfony/routing/tree/v7.4.4" }, "funding": [ { @@ -14215,7 +14213,7 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2026-01-12T12:19:02+00:00" }, { "name": "symfony/runtime", @@ -14302,16 +14300,16 @@ }, { "name": "symfony/security-bundle", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/security-bundle.git", - "reference": "d79c6d9a373fe8585e85bcfca4c24b9783214263" + "reference": "7281b644c76985ddf3927f5e65152b0cc29d175b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-bundle/zipball/d79c6d9a373fe8585e85bcfca4c24b9783214263", - "reference": "d79c6d9a373fe8585e85bcfca4c24b9783214263", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/7281b644c76985ddf3927f5e65152b0cc29d175b", + "reference": "7281b644c76985ddf3927f5e65152b0cc29d175b", "shasum": "" }, "require": { @@ -14390,7 +14388,7 @@ "description": "Provides a tight integration of the Security component into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-bundle/tree/v7.4.6" + "source": "https://github.com/symfony/security-bundle/tree/v7.4.4" }, "funding": [ { @@ -14410,7 +14408,7 @@ "type": "tidelift" } ], - "time": "2026-02-22T22:01:45+00:00" + "time": "2026-01-10T13:56:23+00:00" }, { "name": "symfony/security-core", @@ -14505,16 +14503,16 @@ }, { "name": "symfony/security-csrf", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "d01adcd3141bec95e4cfd338f6b4482f1dd6a42b" + "reference": "06a2a2f90f355b8b4ec23685fa6ceff8d5dc41cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/d01adcd3141bec95e4cfd338f6b4482f1dd6a42b", - "reference": "d01adcd3141bec95e4cfd338f6b4482f1dd6a42b", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/06a2a2f90f355b8b4ec23685fa6ceff8d5dc41cc", + "reference": "06a2a2f90f355b8b4ec23685fa6ceff8d5dc41cc", "shasum": "" }, "require": { @@ -14555,7 +14553,7 @@ "description": "Symfony Security Component - CSRF Library", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-csrf/tree/v7.4.6" + "source": "https://github.com/symfony/security-csrf/tree/v7.4.4" }, "funding": [ { @@ -14575,20 +14573,20 @@ "type": "tidelift" } ], - "time": "2026-02-11T16:03:16+00:00" + "time": "2026-01-14T10:11:16+00:00" }, { "name": "symfony/security-http", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/security-http.git", - "reference": "52ce5ef5708900dcab9f55750cf81250a0ebba9f" + "reference": "9d41a473637bf5d074c5f5a73177fd9d769407fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-http/zipball/52ce5ef5708900dcab9f55750cf81250a0ebba9f", - "reference": "52ce5ef5708900dcab9f55750cf81250a0ebba9f", + "url": "https://api.github.com/repos/symfony/security-http/zipball/9d41a473637bf5d074c5f5a73177fd9d769407fd", + "reference": "9d41a473637bf5d074c5f5a73177fd9d769407fd", "shasum": "" }, "require": { @@ -14647,7 +14645,7 @@ "description": "Symfony Security Component - HTTP Integration", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/security-http/tree/v7.4.6" + "source": "https://github.com/symfony/security-http/tree/v7.4.4" }, "funding": [ { @@ -14667,20 +14665,20 @@ "type": "tidelift" } ], - "time": "2026-02-18T09:46:18+00:00" + "time": "2026-01-14T10:11:16+00:00" }, { "name": "symfony/serializer", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "83c3cbd6dcb96c1dbe197499a0714f8dceb0f274" + "reference": "480cd1237c98ab1219c20945b92c9d4480a44f47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/83c3cbd6dcb96c1dbe197499a0714f8dceb0f274", - "reference": "83c3cbd6dcb96c1dbe197499a0714f8dceb0f274", + "url": "https://api.github.com/repos/symfony/serializer/zipball/480cd1237c98ab1219c20945b92c9d4480a44f47", + "reference": "480cd1237c98ab1219c20945b92c9d4480a44f47", "shasum": "" }, "require": { @@ -14690,18 +14688,17 @@ "symfony/polyfill-php84": "^1.30" }, "conflict": { - "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/reflection-docblock": "<5.2|>=6", "phpdocumentor/type-resolver": "<1.5.1", "symfony/dependency-injection": "<6.4", "symfony/property-access": "<6.4", "symfony/property-info": "<6.4", - "symfony/type-info": "<7.2.5", "symfony/uid": "<6.4", "symfony/validator": "<6.4", "symfony/yaml": "<6.4" }, "require-dev": { - "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "phpdocumentor/reflection-docblock": "^5.2", "phpstan/phpdoc-parser": "^1.0|^2.0", "seld/jsonlint": "^1.10", "symfony/cache": "^6.4|^7.0|^8.0", @@ -14718,7 +14715,7 @@ "symfony/property-access": "^6.4|^7.0|^8.0", "symfony/property-info": "^6.4|^7.0|^8.0", "symfony/translation-contracts": "^2.5|^3", - "symfony/type-info": "^7.2.5|^8.0", + "symfony/type-info": "^7.1.8|^8.0", "symfony/uid": "^6.4|^7.0|^8.0", "symfony/validator": "^6.4|^7.0|^8.0", "symfony/var-dumper": "^6.4|^7.0|^8.0", @@ -14751,7 +14748,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v7.4.6" + "source": "https://github.com/symfony/serializer/tree/v7.4.5" }, "funding": [ { @@ -14771,7 +14768,7 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2026-01-27T08:59:58+00:00" }, { "name": "symfony/service-contracts", @@ -15001,16 +14998,16 @@ }, { "name": "symfony/string", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "9f209231affa85aa930a5e46e6eb03381424b30b" + "reference": "1c4b10461bf2ec27537b5f36105337262f5f5d6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/9f209231affa85aa930a5e46e6eb03381424b30b", - "reference": "9f209231affa85aa930a5e46e6eb03381424b30b", + "url": "https://api.github.com/repos/symfony/string/zipball/1c4b10461bf2ec27537b5f36105337262f5f5d6f", + "reference": "1c4b10461bf2ec27537b5f36105337262f5f5d6f", "shasum": "" }, "require": { @@ -15068,7 +15065,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.4.6" + "source": "https://github.com/symfony/string/tree/v7.4.4" }, "funding": [ { @@ -15088,20 +15085,20 @@ "type": "tidelift" } ], - "time": "2026-02-09T09:33:46+00:00" + "time": "2026-01-12T10:54:30+00:00" }, { "name": "symfony/translation", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "1888cf064399868af3784b9e043240f1d89d25ce" + "reference": "bfde13711f53f549e73b06d27b35a55207528877" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/1888cf064399868af3784b9e043240f1d89d25ce", - "reference": "1888cf064399868af3784b9e043240f1d89d25ce", + "url": "https://api.github.com/repos/symfony/translation/zipball/bfde13711f53f549e73b06d27b35a55207528877", + "reference": "bfde13711f53f549e73b06d27b35a55207528877", "shasum": "" }, "require": { @@ -15168,7 +15165,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.4.6" + "source": "https://github.com/symfony/translation/tree/v7.4.4" }, "funding": [ { @@ -15188,7 +15185,7 @@ "type": "tidelift" } ], - "time": "2026-02-17T07:53:42+00:00" + "time": "2026-01-13T10:40:19+00:00" }, { "name": "symfony/translation-contracts", @@ -15274,16 +15271,16 @@ }, { "name": "symfony/twig-bridge", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "8903bc9a64cf624ffe522893f3626d5a0b97175c" + "reference": "f2dd26b604e856476ef7e0efa4568bc07eb7ddc8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/8903bc9a64cf624ffe522893f3626d5a0b97175c", - "reference": "8903bc9a64cf624ffe522893f3626d5a0b97175c", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/f2dd26b604e856476ef7e0efa4568bc07eb7ddc8", + "reference": "f2dd26b604e856476ef7e0efa4568bc07eb7ddc8", "shasum": "" }, "require": { @@ -15293,7 +15290,7 @@ "twig/twig": "^3.21" }, "conflict": { - "phpdocumentor/reflection-docblock": "<5.2|>=7", + "phpdocumentor/reflection-docblock": "<5.2|>=6", "phpdocumentor/type-resolver": "<1.5.1", "symfony/console": "<6.4", "symfony/form": "<6.4.32|>7,<7.3.10|>7.4,<7.4.4|>8.0,<8.0.4", @@ -15307,7 +15304,7 @@ "require-dev": { "egulias/email-validator": "^2.1.10|^3|^4", "league/html-to-markdown": "^5.0", - "phpdocumentor/reflection-docblock": "^5.2|^6.0", + "phpdocumentor/reflection-docblock": "^5.2", "symfony/asset": "^6.4|^7.0|^8.0", "symfony/asset-mapper": "^6.4|^7.0|^8.0", "symfony/console": "^6.4|^7.0|^8.0", @@ -15365,7 +15362,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v7.4.6" + "source": "https://github.com/symfony/twig-bridge/tree/v7.4.5" }, "funding": [ { @@ -15385,7 +15382,7 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2026-01-27T08:59:58+00:00" }, { "name": "symfony/twig-bundle", @@ -15479,16 +15476,16 @@ }, { "name": "symfony/type-info", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/type-info.git", - "reference": "4855ceea609b2c09e48ff76e12a97a3955531735" + "reference": "f83c725e72b39b2704b9d6fc85070ad6ac7a5889" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/type-info/zipball/4855ceea609b2c09e48ff76e12a97a3955531735", - "reference": "4855ceea609b2c09e48ff76e12a97a3955531735", + "url": "https://api.github.com/repos/symfony/type-info/zipball/f83c725e72b39b2704b9d6fc85070ad6ac7a5889", + "reference": "f83c725e72b39b2704b9d6fc85070ad6ac7a5889", "shasum": "" }, "require": { @@ -15538,7 +15535,7 @@ "type" ], "support": { - "source": "https://github.com/symfony/type-info/tree/v7.4.6" + "source": "https://github.com/symfony/type-info/tree/v7.4.4" }, "funding": [ { @@ -15558,7 +15555,7 @@ "type": "tidelift" } ], - "time": "2026-02-17T14:00:31+00:00" + "time": "2026-01-09T12:14:21+00:00" }, { "name": "symfony/uid", @@ -15824,16 +15821,16 @@ }, { "name": "symfony/validator", - "version": "v7.4.6", + "version": "v7.4.5", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "a1ceaf285712ed8034819a76b5fbba23eaf3e54d" + "reference": "fcec92c40df1c93507857da08226005573b655c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/a1ceaf285712ed8034819a76b5fbba23eaf3e54d", - "reference": "a1ceaf285712ed8034819a76b5fbba23eaf3e54d", + "url": "https://api.github.com/repos/symfony/validator/zipball/fcec92c40df1c93507857da08226005573b655c6", + "reference": "fcec92c40df1c93507857da08226005573b655c6", "shasum": "" }, "require": { @@ -15904,7 +15901,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v7.4.6" + "source": "https://github.com/symfony/validator/tree/v7.4.5" }, "funding": [ { @@ -15924,20 +15921,20 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2026-01-27T08:59:58+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "045321c440ac18347b136c63d2e9bf28a2dc0291" + "reference": "0e4769b46a0c3c62390d124635ce59f66874b282" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/045321c440ac18347b136c63d2e9bf28a2dc0291", - "reference": "045321c440ac18347b136c63d2e9bf28a2dc0291", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0e4769b46a0c3c62390d124635ce59f66874b282", + "reference": "0e4769b46a0c3c62390d124635ce59f66874b282", "shasum": "" }, "require": { @@ -15991,7 +15988,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.4.6" + "source": "https://github.com/symfony/var-dumper/tree/v7.4.4" }, "funding": [ { @@ -16011,7 +16008,7 @@ "type": "tidelift" } ], - "time": "2026-02-15T10:53:20+00:00" + "time": "2026-01-01T22:13:48+00:00" }, { "name": "symfony/var-exporter", @@ -16259,16 +16256,16 @@ }, { "name": "symfony/yaml", - "version": "v7.4.6", + "version": "v7.4.1", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "58751048de17bae71c5aa0d13cb19d79bca26391" + "reference": "24dd4de28d2e3988b311751ac49e684d783e2345" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/58751048de17bae71c5aa0d13cb19d79bca26391", - "reference": "58751048de17bae71c5aa0d13cb19d79bca26391", + "url": "https://api.github.com/repos/symfony/yaml/zipball/24dd4de28d2e3988b311751ac49e684d783e2345", + "reference": "24dd4de28d2e3988b311751ac49e684d783e2345", "shasum": "" }, "require": { @@ -16311,7 +16308,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.4.6" + "source": "https://github.com/symfony/yaml/tree/v7.4.1" }, "funding": [ { @@ -16331,7 +16328,7 @@ "type": "tidelift" } ], - "time": "2026-02-09T09:33:46+00:00" + "time": "2025-12-04T18:11:45+00:00" }, { "name": "symplify/easy-coding-standard", @@ -16396,16 +16393,16 @@ }, { "name": "tecnickcom/tc-lib-barcode", - "version": "2.4.27", + "version": "2.4.24", "source": { "type": "git", "url": "https://github.com/tecnickcom/tc-lib-barcode.git", - "reference": "8d754e2cb6001114ff7669982739245078346d8f" + "reference": "605b92bfaf8ed2cba18a1c6603d90bc828aa3d5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/tc-lib-barcode/zipball/8d754e2cb6001114ff7669982739245078346d8f", - "reference": "8d754e2cb6001114ff7669982739245078346d8f", + "url": "https://api.github.com/repos/tecnickcom/tc-lib-barcode/zipball/605b92bfaf8ed2cba18a1c6603d90bc828aa3d5b", + "reference": "605b92bfaf8ed2cba18a1c6603d90bc828aa3d5b", "shasum": "" }, "require": { @@ -16420,7 +16417,7 @@ "pdepend/pdepend": "2.16.2", "phpcompatibility/php-compatibility": "^10.0.0@dev", "phpmd/phpmd": "2.15.0", - "phpunit/phpunit": "13.0.5 || 12.5.14 || 11.5.55 || 10.5.63", + "phpunit/phpunit": "12.5.8 || 11.5.50 || 10.5.63", "squizlabs/php_codesniffer": "4.0.1" }, "type": "library", @@ -16485,7 +16482,7 @@ ], "support": { "issues": "https://github.com/tecnickcom/tc-lib-barcode/issues", - "source": "https://github.com/tecnickcom/tc-lib-barcode/tree/2.4.27" + "source": "https://github.com/tecnickcom/tc-lib-barcode/tree/2.4.24" }, "funding": [ { @@ -16493,20 +16490,20 @@ "type": "custom" } ], - "time": "2026-02-28T10:33:16+00:00" + "time": "2026-02-04T19:57:11+00:00" }, { "name": "tecnickcom/tc-lib-color", - "version": "2.3.9", + "version": "2.3.8", "source": { "type": "git", "url": "https://github.com/tecnickcom/tc-lib-color.git", - "reference": "7eed5344ed57a3d55b56bebbd1329bd0e8fe597a" + "reference": "6331d57bd847d883652012a5c3594aa03aea4c50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/tc-lib-color/zipball/7eed5344ed57a3d55b56bebbd1329bd0e8fe597a", - "reference": "7eed5344ed57a3d55b56bebbd1329bd0e8fe597a", + "url": "https://api.github.com/repos/tecnickcom/tc-lib-color/zipball/6331d57bd847d883652012a5c3594aa03aea4c50", + "reference": "6331d57bd847d883652012a5c3594aa03aea4c50", "shasum": "" }, "require": { @@ -16517,7 +16514,7 @@ "pdepend/pdepend": "2.16.2", "phpcompatibility/php-compatibility": "^10.0.0@dev", "phpmd/phpmd": "2.15.0", - "phpunit/phpunit": "13.0.5 || 12.5.14 || 11.5.55 || 10.5.63", + "phpunit/phpunit": "12.5.8 || 11.5.50 || 10.5.63", "squizlabs/php_codesniffer": "4.0.1" }, "type": "library", @@ -16555,7 +16552,7 @@ ], "support": { "issues": "https://github.com/tecnickcom/tc-lib-color/issues", - "source": "https://github.com/tecnickcom/tc-lib-color/tree/2.3.9" + "source": "https://github.com/tecnickcom/tc-lib-color/tree/2.3.8" }, "funding": [ { @@ -16563,7 +16560,7 @@ "type": "custom" } ], - "time": "2026-02-23T20:00:30+00:00" + "time": "2026-02-04T19:55:28+00:00" }, { "name": "thecodingmachine/safe", @@ -17678,16 +17675,16 @@ }, { "name": "webmozart/assert", - "version": "2.1.6", + "version": "2.1.5", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "ff31ad6efc62e66e518fbab1cde3453d389bcdc8" + "reference": "79155f94852fa27e2f73b459f6503f5e87e2c188" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/ff31ad6efc62e66e518fbab1cde3453d389bcdc8", - "reference": "ff31ad6efc62e66e518fbab1cde3453d389bcdc8", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/79155f94852fa27e2f73b459f6503f5e87e2c188", + "reference": "79155f94852fa27e2f73b459f6503f5e87e2c188", "shasum": "" }, "require": { @@ -17734,9 +17731,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/2.1.6" + "source": "https://github.com/webmozarts/assert/tree/2.1.5" }, - "time": "2026-02-27T10:28:38+00:00" + "time": "2026-02-18T14:09:36+00:00" }, { "name": "willdurand/negotiation", @@ -18373,11 +18370,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.40", + "version": "2.1.39", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9b2c7aeb83a75d8680ea5e7c9b7fca88052b766b", - "reference": "9b2c7aeb83a75d8680ea5e7c9b7fca88052b766b", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c6f73a2af4cbcd99c931d0fb8f08548cc0fa8224", + "reference": "c6f73a2af4cbcd99c931d0fb8f08548cc0fa8224", "shasum": "" }, "require": { @@ -18422,20 +18419,20 @@ "type": "github" } ], - "time": "2026-02-23T15:04:35+00:00" + "time": "2026-02-11T14:48:56+00:00" }, { "name": "phpstan/phpstan-doctrine", - "version": "2.0.18", + "version": "2.0.17", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-doctrine.git", - "reference": "44a216a5cd9fe52be489dcf1e2d565c473daa1ca" + "reference": "734ef36c2709b51943f04aacadddb76f239562d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/44a216a5cd9fe52be489dcf1e2d565c473daa1ca", - "reference": "44a216a5cd9fe52be489dcf1e2d565c473daa1ca", + "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/734ef36c2709b51943f04aacadddb76f239562d3", + "reference": "734ef36c2709b51943f04aacadddb76f239562d3", "shasum": "" }, "require": { @@ -18460,7 +18457,7 @@ "doctrine/lexer": "^2.0 || ^3.0", "doctrine/mongodb-odm": "^2.4.3", "doctrine/orm": "^2.16.0", - "doctrine/persistence": "^2.2.1 || ^3.4.3", + "doctrine/persistence": "^2.2.1 || ^3.2", "gedmo/doctrine-extensions": "^3.8", "nesbot/carbon": "^2.49", "php-parallel-lint/php-parallel-lint": "^1.2", @@ -18496,9 +18493,9 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan-doctrine/issues", - "source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.18" + "source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.17" }, - "time": "2026-02-24T10:01:00+00:00" + "time": "2026-02-18T10:21:23+00:00" }, { "name": "phpstan/phpstan-strict-rules", @@ -18553,16 +18550,16 @@ }, { "name": "phpstan/phpstan-symfony", - "version": "2.0.15", + "version": "2.0.14", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-symfony.git", - "reference": "9b85ab476969b87bbe2253b69e265a9359b2f395" + "reference": "678136545a552a33b07f1a59a013f76df286cc34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/9b85ab476969b87bbe2253b69e265a9359b2f395", - "reference": "9b85ab476969b87bbe2253b69e265a9359b2f395", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/678136545a552a33b07f1a59a013f76df286cc34", + "reference": "678136545a552a33b07f1a59a013f76df286cc34", "shasum": "" }, "require": { @@ -18621,9 +18618,9 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan-symfony/issues", - "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.15" + "source": "https://github.com/phpstan/phpstan-symfony/tree/2.0.14" }, - "time": "2026-02-26T10:15:59+00:00" + "time": "2026-02-11T12:27:30+00:00" }, { "name": "phpunit/php-code-coverage", @@ -19148,12 +19145,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "89525190c449738e468ee27e77f9fdc1bc160e08" + "reference": "92c5ec5685cfbcd7ef721a502e6622516728011c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/89525190c449738e468ee27e77f9fdc1bc160e08", - "reference": "89525190c449738e468ee27e77f9fdc1bc160e08", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/92c5ec5685cfbcd7ef721a502e6622516728011c", + "reference": "92c5ec5685cfbcd7ef721a502e6622516728011c", "shasum": "" }, "conflict": { @@ -19457,7 +19454,7 @@ "froxlor/froxlor": "<=2.2.5", "frozennode/administrator": "<=5.0.12", "fuel/core": "<1.8.1", - "funadmin/funadmin": "<=7.1.0.0-RC4", + "funadmin/funadmin": "<=5.0.2", "gaoming13/wechat-php-sdk": "<=1.10.2", "genix/cms": "<=1.1.11", "georgringer/news": "<1.3.3", @@ -19616,7 +19613,7 @@ "marshmallow/nova-tiptap": "<5.7", "matomo/matomo": "<1.11", "matyhtf/framework": "<3.0.6", - "mautic/core": "<5.2.10|>=6,<6.0.8|>=7.0.0.0-alpha,<7.0.1", + "mautic/core": "<5.2.9|>=6,<6.0.7", "mautic/core-lib": ">=1.0.0.0-beta,<4.4.13|>=5.0.0.0-alpha,<5.1.1", "mautic/grapes-js-builder-bundle": ">=4,<4.4.18|>=5,<5.2.9|>=6,<6.0.7", "maximebf/debugbar": "<1.19", @@ -19649,7 +19646,7 @@ "mongodb/mongodb": ">=1,<1.9.2", "mongodb/mongodb-extension": "<1.21.2", "monolog/monolog": ">=1.8,<1.12", - "moodle/moodle": "<4.5.9|>=5.0.0.0-beta,<5.0.5|>=5.1.0.0-beta,<5.1.2", + "moodle/moodle": "<4.4.12|>=4.5.0.0-beta,<4.5.8|>=5.0.0.0-beta,<5.0.4|>=5.1.0.0-beta,<5.1.1", "moonshine/moonshine": "<=3.12.5", "mos/cimage": "<0.7.19", "movim/moxl": ">=0.8,<=0.10", @@ -19767,7 +19764,7 @@ "pimcore/demo": "<10.3", "pimcore/ecommerce-framework-bundle": "<1.0.10", "pimcore/perspective-editor": "<1.5.1", - "pimcore/pimcore": "<=11.5.14.1|>=12,<12.3.3", + "pimcore/pimcore": "<=11.5.13|>=12.0.0.0-RC1-dev,<12.3.1", "pimcore/web2print-tools-bundle": "<=5.2.1|>=6.0.0.0-RC1-dev,<=6.1", "piwik/piwik": "<1.11", "pixelfed/pixelfed": "<0.12.5", @@ -19896,7 +19893,7 @@ "starcitizentools/short-description": ">=4,<4.0.1", "starcitizentools/tabber-neue": ">=1.9.1,<2.7.2|>=3,<3.1.1", "starcitizenwiki/embedvideo": "<=4", - "statamic/cms": "<5.73.11|>=6,<6.4", + "statamic/cms": "<5.73.9|>=6,<6.3.2", "stormpath/sdk": "<9.9.99", "studio-42/elfinder": "<=2.1.64", "studiomitte/friendlycaptcha": "<0.1.4", @@ -19970,7 +19967,7 @@ "thelia/thelia": ">=2.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", "thinkcmf/thinkcmf": "<6.0.8", - "thorsten/phpmyfaq": "<4.0.18|>=4.1.0.0-alpha,<=4.1.0.0-beta2", + "thorsten/phpmyfaq": "<=4.0.16|>=4.1.0.0-alpha,<=4.1.0.0-beta2", "tikiwiki/tiki-manager": "<=17.1", "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", "tinymce/tinymce": "<7.2", @@ -19988,7 +19985,6 @@ "ttskch/pagination-service-provider": "<1", "twbs/bootstrap": "<3.4.1|>=4,<4.3.1", "twig/twig": "<3.11.2|>=3.12,<3.14.1|>=3.16,<3.19", - "typicms/core": "<16.1.7", "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<9.5.55|>=10,<=10.4.54|>=11,<=11.5.48|>=12,<=12.4.40|>=13,<=13.4.22|>=14,<=14.0.1", "typo3/cms-belog": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", @@ -20069,7 +20065,7 @@ "wpanel/wpanel4-cms": "<=4.3.1", "wpcloud/wp-stateless": "<3.2", "wpglobus/wpglobus": "<=1.9.6", - "wwbn/avideo": "<=21", + "wwbn/avideo": "<21", "xataface/xataface": "<3", "xpressengine/xpressengine": "<3.0.15", "yab/quarx": "<2.4.5", @@ -20167,7 +20163,7 @@ "type": "tidelift" } ], - "time": "2026-03-01T01:36:02+00:00" + "time": "2026-02-20T22:06:39+00:00" }, { "name": "sebastian/cli-parser", @@ -21540,16 +21536,16 @@ }, { "name": "symfony/web-profiler-bundle", - "version": "v7.4.6", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "952fbb5ea12e101e05510069eacf01e169955100" + "reference": "be165e29e6109efb89bfaefe56e3deccf72a8643" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/952fbb5ea12e101e05510069eacf01e169955100", - "reference": "952fbb5ea12e101e05510069eacf01e169955100", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/be165e29e6109efb89bfaefe56e3deccf72a8643", + "reference": "be165e29e6109efb89bfaefe56e3deccf72a8643", "shasum": "" }, "require": { @@ -21606,7 +21602,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.4.6" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.4.4" }, "funding": [ { @@ -21626,7 +21622,7 @@ "type": "tidelift" } ], - "time": "2026-02-11T16:03:16+00:00" + "time": "2026-01-07T11:56:45+00:00" }, { "name": "theseer/tokenizer", diff --git a/config/reference.php b/config/reference.php index bfac5a46..978a82f9 100644 --- a/config/reference.php +++ b/config/reference.php @@ -208,29 +208,29 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * initial_marking?: list, * events_to_dispatch?: list|null, * places?: list, + * name: scalar|Param|null, + * metadata?: list, * }>, - * transitions?: list, * to?: list, * weight?: int|Param, // Default: 1 - * metadata?: array, + * metadata?: list, * }>, - * metadata?: array, + * metadata?: list, * }>, * }, * router?: bool|array{ // Router configuration * enabled?: bool|Param, // Default: false - * resource?: scalar|Param|null, + * resource: scalar|Param|null, * type?: scalar|Param|null, * cache_dir?: scalar|Param|null, // Deprecated: Setting the "framework.router.cache_dir.cache_dir" configuration option is deprecated. It will be removed in version 8.0. // Default: "%kernel.build_dir%" * default_uri?: scalar|Param|null, // The default URI used to generate URLs in a non-HTTP context. // Default: null @@ -360,10 +360,10 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * mapping?: array{ * paths?: list, * }, - * default_context?: array, + * default_context?: list, * named_serializers?: array, + * default_context?: list, * include_built_in_normalizers?: bool|Param, // Whether to include the built-in normalizers // Default: true * include_built_in_encoders?: bool|Param, // Whether to include the built-in encoders // Default: true * }>, @@ -427,7 +427,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * messenger?: bool|array{ // Messenger configuration * enabled?: bool|Param, // Default: false - * routing?: array, * }>, * serializer?: array{ @@ -440,7 +440,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * transports?: array, + * options?: list, * failure_transport?: scalar|Param|null, // Transport name to send failed messages to (after all retries have failed). // Default: null * retry_strategy?: string|array{ * service?: scalar|Param|null, // Service id to override the retry strategy entirely. // Default: null @@ -462,7 +462,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * allow_no_senders?: bool|Param, // Default: true * }, * middleware?: list, * }>, * }>, @@ -634,7 +634,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * lock_factory?: scalar|Param|null, // The service ID of the lock factory used by this limiter (or null to disable locking). // Default: "auto" * cache_pool?: scalar|Param|null, // The cache pool to use for storing the current limiter state. // Default: "cache.rate_limiter" * storage_service?: scalar|Param|null, // The service ID of a custom storage implementation, this precedes any configured "cache_pool". // Default: null - * policy?: "fixed_window"|"token_bucket"|"sliding_window"|"compound"|"no_limit"|Param, // The algorithm to be used by this limiter. + * policy: "fixed_window"|"token_bucket"|"sliding_window"|"compound"|"no_limit"|Param, // The algorithm to be used by this limiter. * limiters?: list, * limit?: int|Param, // The maximum allowed hits in a fixed interval or burst. * interval?: scalar|Param|null, // Configures the fixed interval if "policy" is set to "fixed_window" or "sliding_window". The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent). @@ -679,7 +679,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * enabled?: bool|Param, // Default: false * message_bus?: scalar|Param|null, // The message bus to use. // Default: "messenger.default_bus" * routing?: array, * }, @@ -694,7 +694,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * dbal?: array{ * default_connection?: scalar|Param|null, * types?: array, * driver_schemes?: array, @@ -910,7 +910,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * datetime_functions?: array, * }, * filters?: array, * }>, @@ -975,7 +975,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * providers?: list, * }, * entity?: array{ - * class?: scalar|Param|null, // The full entity class name of your user class. + * class: scalar|Param|null, // The full entity class name of your user class. * property?: scalar|Param|null, // Default: null * manager_name?: scalar|Param|null, // Default: null * }, @@ -986,8 +986,8 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }>, * }, * ldap?: array{ - * service?: scalar|Param|null, - * base_dn?: scalar|Param|null, + * service: scalar|Param|null, + * base_dn: scalar|Param|null, * search_dn?: scalar|Param|null, // Default: null * search_password?: scalar|Param|null, // Default: null * extra_fields?: list, @@ -998,11 +998,11 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * password_attribute?: scalar|Param|null, // Default: null * }, * saml?: array{ - * user_class?: scalar|Param|null, + * user_class: scalar|Param|null, * default_roles?: list, * }, * }>, - * firewalls?: array, @@ -1136,9 +1136,9 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * failure_path_parameter?: scalar|Param|null, // Default: "_failure_path" * }, * login_link?: array{ - * check_route?: scalar|Param|null, // Route that will validate the login link - e.g. "app_login_link_verify". + * check_route: scalar|Param|null, // Route that will validate the login link - e.g. "app_login_link_verify". * check_post_only?: scalar|Param|null, // If true, only HTTP POST requests to "check_route" will be handled by the authenticator. // Default: false - * signature_properties?: list, + * signature_properties: list, * lifetime?: int|Param, // The lifetime of the login link in seconds. // Default: 600 * max_uses?: int|Param, // Max number of times a login link can be used - null means unlimited within lifetime. // Default: null * used_link_cache?: scalar|Param|null, // Cache service id used to expired links of max_uses is set. @@ -1240,13 +1240,13 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * failure_handler?: scalar|Param|null, * realm?: scalar|Param|null, // Default: null * token_extractors?: list, - * token_handler?: string|array{ + * token_handler: string|array{ * id?: scalar|Param|null, * oidc_user_info?: string|array{ - * base_uri?: scalar|Param|null, // Base URI of the userinfo endpoint on the OIDC server, or the OIDC server URI to use the discovery (require "discovery" to be configured). + * base_uri: scalar|Param|null, // Base URI of the userinfo endpoint on the OIDC server, or the OIDC server URI to use the discovery (require "discovery" to be configured). * discovery?: array{ // Enable the OIDC discovery. * cache?: array{ - * id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. + * id: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. * }, * }, * claim?: scalar|Param|null, // Claim which contains the user identifier (e.g. sub, email, etc.). // Default: "sub" @@ -1254,27 +1254,27 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * oidc?: array{ * discovery?: array{ // Enable the OIDC discovery. - * base_uri?: list, + * base_uri: list, * cache?: array{ - * id?: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. + * id: scalar|Param|null, // Cache service id to use to cache the OIDC discovery configuration. * }, * }, * claim?: scalar|Param|null, // Claim which contains the user identifier (e.g.: sub, email..). // Default: "sub" - * audience?: scalar|Param|null, // Audience set in the token, for validation purpose. - * issuers?: list, + * audience: scalar|Param|null, // Audience set in the token, for validation purpose. + * issuers: list, * algorithm?: array, - * algorithms?: list, + * algorithms: list, * key?: scalar|Param|null, // Deprecated: The "key" option is deprecated and will be removed in 8.0. Use the "keyset" option instead. // JSON-encoded JWK used to sign the token (must contain a "kty" key). * keyset?: scalar|Param|null, // JSON-encoded JWKSet used to sign the token (must contain a list of valid public keys). * encryption?: bool|array{ * enabled?: bool|Param, // Default: false * enforce?: bool|Param, // When enabled, the token shall be encrypted. // Default: false - * algorithms?: list, - * keyset?: scalar|Param|null, // JSON-encoded JWKSet used to decrypt the token (must contain a list of valid private keys). + * algorithms: list, + * keyset: scalar|Param|null, // JSON-encoded JWKSet used to decrypt the token (must contain a list of valid private keys). * }, * }, * cas?: array{ - * validation_url?: scalar|Param|null, // CAS server validation URL + * validation_url: scalar|Param|null, // CAS server validation URL * prefix?: scalar|Param|null, // CAS prefix // Default: "cas" * http_client?: scalar|Param|null, // HTTP Client service // Default: null * }, @@ -1379,7 +1379,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * use_microseconds?: scalar|Param|null, // Default: true * channels?: list, * handlers?: array, * mailer?: scalar|Param|null, // Default: null * email_prototype?: string|array{ - * id?: scalar|Param|null, + * id: scalar|Param|null, * method?: scalar|Param|null, // Default: null * }, * verbosity_levels?: array{ @@ -1531,7 +1531,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * generate_final_entities?: bool|Param, // Default: false * } * @psalm-type WebpackEncoreConfig = array{ - * output_path?: scalar|Param|null, // The path where Encore is building the assets - i.e. Encore.setOutputPath() + * output_path: scalar|Param|null, // The path where Encore is building the assets - i.e. Encore.setOutputPath() * crossorigin?: false|"anonymous"|"use-credentials"|Param, // crossorigin value when Encore.enableIntegrityHashes() is used, can be false (default), anonymous or use-credentials // Default: false * preload?: bool|Param, // preload all rendered script and link tags automatically via the http2 Link header. // Default: false * cache?: bool|Param, // Enable caching of the entry point file(s) // Default: false @@ -1561,27 +1561,27 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * cache_prefix?: scalar|Param|null, // Default: "media/cache" * }, * aws_s3?: array{ - * bucket?: scalar|Param|null, + * bucket: scalar|Param|null, * cache?: scalar|Param|null, // Default: false * use_psr_cache?: bool|Param, // Default: false * acl?: scalar|Param|null, // Default: "public-read" * cache_prefix?: scalar|Param|null, // Default: "" * client_id?: scalar|Param|null, // Default: null - * client_config?: list, + * client_config: list, * get_options?: array, * put_options?: array, * proxies?: array, * }, * flysystem?: array{ - * filesystem_service?: scalar|Param|null, + * filesystem_service: scalar|Param|null, * cache_prefix?: scalar|Param|null, // Default: "" - * root_url?: scalar|Param|null, + * root_url: scalar|Param|null, * visibility?: "public"|"private"|"noPredefinedVisibility"|Param, // Default: "public" * }, * }>, * loaders?: array, * chain?: array{ - * loaders?: list, + * loaders: list, * }, * }>, * driver?: scalar|Param|null, // Default: "gd" @@ -1746,23 +1746,23 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * providers?: array{ * apilayer_fixer?: array{ * priority?: int|Param, // Default: 0 - * api_key?: scalar|Param|null, + * api_key: scalar|Param|null, * }, * apilayer_currency_data?: array{ * priority?: int|Param, // Default: 0 - * api_key?: scalar|Param|null, + * api_key: scalar|Param|null, * }, * apilayer_exchange_rates_data?: array{ * priority?: int|Param, // Default: 0 - * api_key?: scalar|Param|null, + * api_key: scalar|Param|null, * }, * abstract_api?: array{ * priority?: int|Param, // Default: 0 - * api_key?: scalar|Param|null, + * api_key: scalar|Param|null, * }, * fixer?: array{ * priority?: int|Param, // Default: 0 - * access_key?: scalar|Param|null, + * access_key: scalar|Param|null, * enterprise?: bool|Param, // Default: false * }, * cryptonator?: array{ @@ -1770,7 +1770,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * exchange_rates_api?: array{ * priority?: int|Param, // Default: 0 - * access_key?: scalar|Param|null, + * access_key: scalar|Param|null, * enterprise?: bool|Param, // Default: false * }, * webservicex?: array{ @@ -1805,38 +1805,38 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * currency_data_feed?: array{ * priority?: int|Param, // Default: 0 - * api_key?: scalar|Param|null, + * api_key: scalar|Param|null, * }, * currency_layer?: array{ * priority?: int|Param, // Default: 0 - * access_key?: scalar|Param|null, + * access_key: scalar|Param|null, * enterprise?: bool|Param, // Default: false * }, * forge?: array{ * priority?: int|Param, // Default: 0 - * api_key?: scalar|Param|null, + * api_key: scalar|Param|null, * }, * open_exchange_rates?: array{ * priority?: int|Param, // Default: 0 - * app_id?: scalar|Param|null, + * app_id: scalar|Param|null, * enterprise?: bool|Param, // Default: false * }, * xignite?: array{ * priority?: int|Param, // Default: 0 - * token?: scalar|Param|null, + * token: scalar|Param|null, * }, * xchangeapi?: array{ * priority?: int|Param, // Default: 0 - * api_key?: scalar|Param|null, + * api_key: scalar|Param|null, * }, * currency_converter?: array{ * priority?: int|Param, // Default: 0 - * access_key?: scalar|Param|null, + * access_key: scalar|Param|null, * enterprise?: bool|Param, // Default: false * }, * array?: array{ * priority?: int|Param, // Default: 0 - * latestRates?: mixed, + * latestRates: mixed, * historicalRates?: mixed, * }, * }, @@ -2098,9 +2098,9 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * counter_checker?: scalar|Param|null, // This service will check if the counter is valid. By default it throws an exception (recommended). // Default: "Webauthn\\Counter\\ThrowExceptionIfInvalid" * top_origin_validator?: scalar|Param|null, // For cross origin (e.g. iframe), this service will be in charge of verifying the top origin. // Default: null * creation_profiles?: array, * metadata?: bool|array{ // Enable the support of the Metadata Statements. Please read the documentation for this feature. * enabled?: bool|Param, // Default: false - * mds_repository?: scalar|Param|null, // The Metadata Statement repository. - * status_report_repository?: scalar|Param|null, // The Status Report repository. + * mds_repository: scalar|Param|null, // The Metadata Statement repository. + * status_report_repository: scalar|Param|null, // The Status Report repository. * certificate_chain_checker?: scalar|Param|null, // A Certificate Chain checker. // Default: "Webauthn\\MetadataService\\CertificateChain\\PhpCertificateChainValidator" * }, * controllers?: bool|array{ * enabled?: bool|Param, // Default: false * creation?: array, * request?: array/saml/" * strict?: bool|Param, * debug?: bool|Param, - * idp?: array{ - * entityId?: scalar|Param|null, - * singleSignOnService?: array{ - * url?: scalar|Param|null, + * idp: array{ + * entityId: scalar|Param|null, + * singleSignOnService: array{ + * url: scalar|Param|null, * binding?: scalar|Param|null, * }, * singleLogoutService?: array{ @@ -2245,30 +2245,30 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * contactPerson?: array{ * technical?: array{ - * givenName?: scalar|Param|null, - * emailAddress?: scalar|Param|null, + * givenName: scalar|Param|null, + * emailAddress: scalar|Param|null, * }, * support?: array{ - * givenName?: scalar|Param|null, - * emailAddress?: scalar|Param|null, + * givenName: scalar|Param|null, + * emailAddress: scalar|Param|null, * }, * administrative?: array{ - * givenName?: scalar|Param|null, - * emailAddress?: scalar|Param|null, + * givenName: scalar|Param|null, + * emailAddress: scalar|Param|null, * }, * billing?: array{ - * givenName?: scalar|Param|null, - * emailAddress?: scalar|Param|null, + * givenName: scalar|Param|null, + * emailAddress: scalar|Param|null, * }, * other?: array{ - * givenName?: scalar|Param|null, - * emailAddress?: scalar|Param|null, + * givenName: scalar|Param|null, + * emailAddress: scalar|Param|null, * }, * }, * organization?: list, * }>, * use_proxy_vars?: bool|Param, // Default: false @@ -2304,7 +2304,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * auto_install?: bool|Param, // Default: false * fonts?: list, * max_query_complexity?: int|Param, // Default: 500 * nesting_separator?: scalar|Param|null, // The separator to use to filter nested fields. // Default: "_" * collection?: array{ @@ -2514,7 +2512,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * termsOfService?: scalar|Param|null, // A URL to the Terms of Service for the API. MUST be in the format of a URL. // Default: null * tags?: list, * license?: array{ @@ -2806,10 +2804,7 @@ final class App */ public static function config(array $config): array { - /** @var ConfigType $config */ - $config = AppReference::config($config); - - return $config; + return AppReference::config($config); } } diff --git a/docs/usage/console_commands.md b/docs/usage/console_commands.md index bc9bb013..576b3314 100644 --- a/docs/usage/console_commands.md +++ b/docs/usage/console_commands.md @@ -88,6 +88,3 @@ The value of the environment variable is copied to the settings database, so the * `php bin/console partdb:attachments:download`: Download all attachments that are not already downloaded to the local filesystem. This is useful to create local backups of the attachments, no matter what happens on the remote, and also makes picture thumbnails available for the frontend for them. - -## EDA integration commands -* `php bin/console partdb:kicad:populate`: Populate KiCad footprint paths and symbol paths for footprints and categories based on their names. Use `--dry-run` to preview changes without applying them, and `--list` to list current values. See the [EDA integration documentation](eda_integration.md) for more details. diff --git a/docs/usage/eda_integration.md b/docs/usage/eda_integration.md index b99ed4dd..28386a91 100644 --- a/docs/usage/eda_integration.md +++ b/docs/usage/eda_integration.md @@ -87,31 +87,3 @@ To show more levels of categories, you can set this value to a higher number. If you set this value to -1, all parts are shown inside a single category in KiCad, without any subcategories. You can view the "real" category path of a part in the part details dialog in KiCad. - -### Kicad:populate command - -Part-DB also provides a command that attempts to automatically populate the KiCad symbol and footprint fields based on the part's category and footprint names. -This is especially useful if you have a large database and want to quickly assign symbols and footprints to parts without doing it manually. - -For this run `bin/console partdb:kicad:populate --dry-run` in the terminal, it will show you a list of suggestions for mappings for your existing categories and footprints. -It uses names and alternative names, when the primary name doesn't match, to find the right mapping. -If you are happy with the suggestions, you can run the command without the `--dry-run` option to apply the changes to your database. By default, only empty values are updated, but you can use the `--force` option to overwrite existing values as well. - -It uses the mapping under `assets/commands/kicad_populate_default_mappings.json` by default, but you can extend/override it by providing your own mapping file -with the `--mapping-file` option. -The mapping file is a JSON file with the following structure, where the key is the name of the footprint or category, and the value is the corresponding KiCad library path: -```json -{ - "footprints": { - "MyCustomPackage": "MyLibrary:MyFootprint", - "0805": "Capacitor_SMD:C_0805_2012Metric" - }, - "categories": { - "Sensor": "Sensor:Sensor_Temperature", - "MCU": "MCU_Microchip:PIC16F877A" - } -} -``` -Its okay if the file contains just one of the `footprints` or `categories` keys, so you can choose to only provide mappings for one of them if you want. - -It is recommended to take a backup of your database before running this command. diff --git a/docs/usage/scanner.md b/docs/usage/scanner.md deleted file mode 100644 index 47b3feff..00000000 --- a/docs/usage/scanner.md +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Barcode Scanner -layout: default -parent: Usage ---- - -# Barcode scanner - -When the user has the correct permission there will be a barcode scanner button in the navbar. -On this page you can either input a barcode code by hand, use an external barcode scanner, or use your devices camera to -scan a barcode. - -In info mode (when the "Info" toggle is enabled) you can scan a barcode and Part-DB will parse it and show information -about it. - -Without info mode, the barcode will directly redirect you to the corresponding page. - -### Barcode matching - -When you scan a barcode, Part-DB will try to match it to an existing part, part lot or storage location first. -For Part-DB generated barcodes, it will use the internal ID of a part. Alternatively you can also scan a barcode that contains the part's IPN. - -You can set a GTIN/EAN code in the part properties and Part-DB will open the part page when you scan the corresponding GTIN/EAN barcode. - -On a part lot you can under "Advanced" set a user barcode, that will redirect you to the part lot page when scanned. This allows to reuse -arbitrary existing barcodes that already exist on the part lots (for example, from the manufacturer) and link them to the part lot in Part-DB. - -Part-DB can also parse various distributor barcodes (for example from Digikey and Mouser) and will try to redirect you to the corresponding -part page based on the distributor part number in the barcode. - -### Part creation from barcodes -For certain barcodes Part-DB can automatically create a new part, when it cannot find a matching part. -Part-DB will try to retrieve the part information from an information provider and redirects you to the part creation page -with the retrieved information pre-filled. - -## Using an external barcode scanner - -Part-DB supports the use of external barcode scanners that emulate keyboard input. To use a barcode scanner with Part-DB, -simply connect the scanner to your computer and scan a barcode while the cursor is in a text field in Part-DB. -The scanned barcode will be entered into the text field as if you had typed it on the keyboard. - -In scanner fields, it will also try to insert special non-printable characters the scanner send via Alt + key combinations. -This is required for EIGP114 datamatrix codes. - -### Automatically redirect on barcode scanning - -If you configure your barcode scanner to send a (Start of heading, 0x01) non-printable character at the beginning -of the scanned barcode, Part-DB will automatically scan the barcode that comes afterward (and is ended with an enter key) -and redirects you to the corresponding page. -This allows you to quickly scan a barcode from anywhere in Part-DB without the need to first open the scanner page. -If an input field is focused, the barcode will be entered into the field as usual and no redirection will happen. diff --git a/migrations/Version20260211000000.php b/migrations/Version20260211000000.php deleted file mode 100644 index 33f3db57..00000000 --- a/migrations/Version20260211000000.php +++ /dev/null @@ -1,52 +0,0 @@ -addSql('ALTER TABLE parameters ADD eda_visibility TINYINT(1) DEFAULT NULL'); - $this->addSql('ALTER TABLE `orderdetails` ADD eda_visibility TINYINT(1) DEFAULT NULL'); - } - - public function mySQLDown(Schema $schema): void - { - $this->addSql('ALTER TABLE parameters DROP COLUMN eda_visibility'); - $this->addSql('ALTER TABLE `orderdetails` DROP COLUMN eda_visibility'); - } - - public function sqLiteUp(Schema $schema): void - { - $this->addSql('ALTER TABLE parameters ADD COLUMN eda_visibility BOOLEAN DEFAULT NULL'); - $this->addSql('ALTER TABLE orderdetails ADD COLUMN eda_visibility BOOLEAN DEFAULT NULL'); - } - - public function sqLiteDown(Schema $schema): void - { - $this->addSql('ALTER TABLE parameters DROP COLUMN eda_visibility'); - $this->addSql('ALTER TABLE orderdetails DROP COLUMN eda_visibility'); - } - - public function postgreSQLUp(Schema $schema): void - { - $this->addSql('ALTER TABLE parameters ADD eda_visibility BOOLEAN DEFAULT NULL'); - $this->addSql('ALTER TABLE orderdetails ADD eda_visibility BOOLEAN DEFAULT NULL'); - } - - public function postgreSQLDown(Schema $schema): void - { - $this->addSql('ALTER TABLE parameters DROP COLUMN eda_visibility'); - $this->addSql('ALTER TABLE orderdetails DROP COLUMN eda_visibility'); - } -} diff --git a/public/kicad/footprints.txt b/public/kicad/footprints.txt index 51f99de5..be6020cb 100644 --- a/public/kicad/footprints.txt +++ b/public/kicad/footprints.txt @@ -1,4 +1,4 @@ -# Generated on Tue Mar 3 14:26:21 UTC 2026 +# Generated on Sun Mar 1 11:46:09 UTC 2026 # This file contains all footprints available in the offical KiCAD library Audio_Module:Reverb_BTDR-1H Audio_Module:Reverb_BTDR-1V diff --git a/public/kicad/symbols.txt b/public/kicad/symbols.txt index 984e4d66..9941ad2c 100644 --- a/public/kicad/symbols.txt +++ b/public/kicad/symbols.txt @@ -1,4 +1,4 @@ -# Generated on Tue Mar 3 14:27:05 UTC 2026 +# Generated on Sun Mar 1 11:46:51 UTC 2026 # This file contains all symbols available in the offical KiCAD library 4xxx:14528 4xxx:14529 @@ -20842,9 +20842,6 @@ Sensor_Pressure:40PC015G Sensor_Pressure:40PC100G Sensor_Pressure:40PC150G Sensor_Pressure:40PC250G -Sensor_Pressure:ABPxxxxxxxxx0 -Sensor_Pressure:ABPxxxxxxxxxA -Sensor_Pressure:ABPxxxxxxxxxS Sensor_Pressure:BMP280 Sensor_Pressure:ILPS28QSW Sensor_Pressure:LPS22DF diff --git a/src/Command/PopulateKicadCommand.php b/src/Command/PopulateKicadCommand.php deleted file mode 100644 index 721e7706..00000000 --- a/src/Command/PopulateKicadCommand.php +++ /dev/null @@ -1,364 +0,0 @@ -setHelp('This command populates KiCad footprint paths on Footprint entities and KiCad symbol paths on Category entities based on their names.'); - - $this - ->addOption('dry-run', null, InputOption::VALUE_NONE, 'Preview changes without applying them') - ->addOption('footprints', null, InputOption::VALUE_NONE, 'Only update footprint entities') - ->addOption('categories', null, InputOption::VALUE_NONE, 'Only update category entities') - ->addOption('force', null, InputOption::VALUE_NONE, 'Overwrite existing values (by default, only empty values are updated)') - ->addOption('list', null, InputOption::VALUE_NONE, 'List all footprints and categories with their current KiCad values') - ->addOption('mapping-file', null, InputOption::VALUE_REQUIRED, 'Path to a JSON file with custom mappings (merges with built-in defaults)') - ; - } - - protected function execute(InputInterface $input, OutputInterface $output): int - { - $io = new SymfonyStyle($input, $output); - $dryRun = $input->getOption('dry-run'); - $footprintsOnly = $input->getOption('footprints'); - $categoriesOnly = $input->getOption('categories'); - $force = $input->getOption('force'); - $list = $input->getOption('list'); - $mappingFile = $input->getOption('mapping-file'); - - // If neither specified, do both - $doFootprints = !$categoriesOnly || $footprintsOnly; - $doCategories = !$footprintsOnly || $categoriesOnly; - - if ($list) { - $this->listCurrentValues($io); - return Command::SUCCESS; - } - - // Load mappings: start with built-in defaults, then merge user-supplied file - ['footprints' => $footprintMappings, 'categories' => $categoryMappings] = $this->getDefaultMappings(); - - if ($mappingFile !== null) { - $customMappings = $this->loadMappingFile($mappingFile, $io); - if ($customMappings === null) { - return Command::FAILURE; - } - if (isset($customMappings['footprints']) && is_array($customMappings['footprints'])) { - // User mappings take priority (overwrite defaults) - $footprintMappings = array_merge($footprintMappings, $customMappings['footprints']); - $io->text(sprintf('Loaded %d custom footprint mappings from %s', count($customMappings['footprints']), $mappingFile)); - } - if (isset($customMappings['categories']) && is_array($customMappings['categories'])) { - $categoryMappings = array_merge($categoryMappings, $customMappings['categories']); - $io->text(sprintf('Loaded %d custom category mappings from %s', count($customMappings['categories']), $mappingFile)); - } - } - - if ($dryRun) { - $io->note('DRY RUN MODE - No changes will be made'); - } - - $totalUpdated = 0; - - if ($doFootprints) { - $updated = $this->updateFootprints($io, $dryRun, $force, $footprintMappings); - $totalUpdated += $updated; - } - - if ($doCategories) { - $updated = $this->updateCategories($io, $dryRun, $force, $categoryMappings); - $totalUpdated += $updated; - } - - if (!$dryRun && $totalUpdated > 0) { - $this->entityManager->flush(); - $io->success(sprintf('Updated %d entities. Run "php bin/console cache:clear" to clear the cache.', $totalUpdated)); - } elseif ($dryRun && $totalUpdated > 0) { - $io->info(sprintf('DRY RUN: Would update %d entities. Run without --dry-run to apply changes.', $totalUpdated)); - } else { - $io->info('No entities needed updating.'); - } - - return Command::SUCCESS; - } - - private function listCurrentValues(SymfonyStyle $io): void - { - $io->section('Current Footprint KiCad Values'); - - $footprintRepo = $this->entityManager->getRepository(Footprint::class); - /** @var Footprint[] $footprints */ - $footprints = $footprintRepo->findAll(); - - $rows = []; - foreach ($footprints as $footprint) { - $kicadValue = $footprint->getEdaInfo()->getKicadFootprint(); - $rows[] = [ - $footprint->getId(), - $footprint->getName(), - $kicadValue ?? '(empty)', - ]; - } - - $io->table(['ID', 'Name', 'KiCad Footprint'], $rows); - - $io->section('Current Category KiCad Values'); - - $categoryRepo = $this->entityManager->getRepository(Category::class); - /** @var Category[] $categories */ - $categories = $categoryRepo->findAll(); - - $rows = []; - foreach ($categories as $category) { - $kicadValue = $category->getEdaInfo()->getKicadSymbol(); - $rows[] = [ - $category->getId(), - $category->getName(), - $kicadValue ?? '(empty)', - ]; - } - - $io->table(['ID', 'Name', 'KiCad Symbol'], $rows); - } - - private function updateFootprints(SymfonyStyle $io, bool $dryRun, bool $force, array $mappings): int - { - $io->section('Updating Footprint Entities'); - - $footprintRepo = $this->entityManager->getRepository(Footprint::class); - /** @var Footprint[] $footprints */ - $footprints = $footprintRepo->findAll(); - - $updated = 0; - $skipped = []; - - foreach ($footprints as $footprint) { - $name = $footprint->getName(); - $currentValue = $footprint->getEdaInfo()->getKicadFootprint(); - - // Skip if already has value and not forcing - if (!$force && $currentValue !== null && $currentValue !== '') { - continue; - } - - // Check for exact match on name first, then try alternative names - $matchedValue = $this->findFootprintMapping($mappings, $name, $footprint->getAlternativeNames()); - - if ($matchedValue !== null) { - $io->text(sprintf(' %s: %s -> %s', $name, $currentValue ?? '(empty)', $matchedValue)); - - if (!$dryRun) { - $footprint->getEdaInfo()->setKicadFootprint($matchedValue); - } - $updated++; - } else { - // No mapping found - $skipped[] = $name; - } - } - - $io->newLine(); - $io->text(sprintf('Updated: %d footprints', $updated)); - - if (count($skipped) > 0) { - $io->warning(sprintf('No mapping found for %d footprints:', count($skipped))); - foreach ($skipped as $name) { - $io->text(' - ' . $name); - } - } - - return $updated; - } - - private function updateCategories(SymfonyStyle $io, bool $dryRun, bool $force, array $mappings): int - { - $io->section('Updating Category Entities'); - - $categoryRepo = $this->entityManager->getRepository(Category::class); - /** @var Category[] $categories */ - $categories = $categoryRepo->findAll(); - - $updated = 0; - $skipped = []; - - foreach ($categories as $category) { - $name = $category->getName(); - $currentValue = $category->getEdaInfo()->getKicadSymbol(); - - // Skip if already has value and not forcing - if (!$force && $currentValue !== null && $currentValue !== '') { - continue; - } - - // Check for matches using the pattern-based mappings (also check alternative names) - $matchedValue = $this->findCategoryMapping($mappings, $name, $category->getAlternativeNames()); - - if ($matchedValue !== null) { - $io->text(sprintf(' %s: %s -> %s', $name, $currentValue ?? '(empty)', $matchedValue)); - - if (!$dryRun) { - $category->getEdaInfo()->setKicadSymbol($matchedValue); - } - $updated++; - } else { - $skipped[] = $name; - } - } - - $io->newLine(); - $io->text(sprintf('Updated: %d categories', $updated)); - - if (count($skipped) > 0) { - $io->note(sprintf('No mapping found for %d categories (this is often expected):', count($skipped))); - foreach ($skipped as $name) { - $io->text(' - ' . $name); - } - } - - return $updated; - } - - /** - * Loads a JSON mapping file and returns the parsed data. - * Expected format: {"footprints": {"Name": "KiCad:Path"}, "categories": {"Pattern": "KiCad:Path"}} - * - * @return array|null The parsed mappings, or null on error - */ - private function loadMappingFile(string $path, SymfonyStyle $io): ?array - { - if (!file_exists($path)) { - $io->error(sprintf('Mapping file not found: %s', $path)); - return null; - } - - $content = file_get_contents($path); - if ($content === false) { - $io->error(sprintf('Could not read mapping file: %s', $path)); - return null; - } - - $data = json_decode($content, true); - if (!is_array($data)) { - $io->error(sprintf('Invalid JSON in mapping file: %s', $path)); - return null; - } - - return $data; - } - - private function matchesPattern(string $name, string $pattern): bool - { - // Check for exact match - if ($pattern === $name) { - return true; - } - - // Check for case-insensitive contains - if (stripos($name, $pattern) !== false) { - return true; - } - - return false; - } - - /** - * Finds a footprint mapping by checking the entity name and its alternative names. - * Footprints use exact matching. - * - * @param array $mappings - * @param string $name The primary name of the footprint - * @param string|null $alternativeNames Comma-separated alternative names - * @return string|null The matched KiCad path, or null if no match found - */ - private function findFootprintMapping(array $mappings, string $name, ?string $alternativeNames): ?string - { - // Check primary name - if (isset($mappings[$name])) { - return $mappings[$name]; - } - - // Check alternative names - if ($alternativeNames !== null && $alternativeNames !== '') { - foreach (explode(',', $alternativeNames) as $altName) { - $altName = trim($altName); - if ($altName !== '' && isset($mappings[$altName])) { - return $mappings[$altName]; - } - } - } - - return null; - } - - /** - * Finds a category mapping by checking the entity name and its alternative names. - * Categories use pattern-based matching (case-insensitive contains). - * - * @param array $mappings - * @param string $name The primary name of the category - * @param string|null $alternativeNames Comma-separated alternative names - * @return string|null The matched KiCad symbol path, or null if no match found - */ - private function findCategoryMapping(array $mappings, string $name, ?string $alternativeNames): ?string - { - // Check primary name against all patterns - foreach ($mappings as $pattern => $kicadSymbol) { - if ($this->matchesPattern($name, $pattern)) { - return $kicadSymbol; - } - } - - // Check alternative names against all patterns - if ($alternativeNames !== null && $alternativeNames !== '') { - foreach (explode(',', $alternativeNames) as $altName) { - $altName = trim($altName); - if ($altName === '') { - continue; - } - foreach ($mappings as $pattern => $kicadSymbol) { - if ($this->matchesPattern($altName, $pattern)) { - return $kicadSymbol; - } - } - } - } - - return null; - } - - /** - * Returns the default mappings for footprints and categories. - * @return array{footprints: array, categories: array} - * @throws \JsonException - */ - private function getDefaultMappings(): array - { - $path = $this->projectDir . '/' . self::DEFAULT_MAPPING_FILE; - $content = file_get_contents($path); - - return json_decode($content, true, 512, JSON_THROW_ON_ERROR); - } -} diff --git a/src/Controller/BatchEdaController.php b/src/Controller/BatchEdaController.php deleted file mode 100644 index 82c4bb48..00000000 --- a/src/Controller/BatchEdaController.php +++ /dev/null @@ -1,117 +0,0 @@ - - */ - private function getSharedEdaValues(array $parts): array - { - $fields = [ - 'reference_prefix' => static fn (Part $p) => $p->getEdaInfo()->getReferencePrefix(), - 'value' => static fn (Part $p) => $p->getEdaInfo()->getValue(), - 'kicad_symbol' => static fn (Part $p) => $p->getEdaInfo()->getKicadSymbol(), - 'kicad_footprint' => static fn (Part $p) => $p->getEdaInfo()->getKicadFootprint(), - 'visibility' => static fn (Part $p) => $p->getEdaInfo()->getVisibility(), - 'exclude_from_bom' => static fn (Part $p) => $p->getEdaInfo()->getExcludeFromBom(), - 'exclude_from_board' => static fn (Part $p) => $p->getEdaInfo()->getExcludeFromBoard(), - 'exclude_from_sim' => static fn (Part $p) => $p->getEdaInfo()->getExcludeFromSim(), - ]; - - $data = []; - foreach ($fields as $key => $getter) { - $values = array_map($getter, $parts); - $unique = array_unique($values, SORT_REGULAR); - if (count($unique) === 1) { - $data[$key] = $unique[array_key_first($unique)]; - } - } - - return $data; - } - - #[Route('/tools/batch_eda_edit', name: 'batch_eda_edit')] - public function batchEdaEdit(Request $request): Response - { - $this->denyAccessUnlessGranted('@parts.edit'); - - $ids = $request->query->getString('ids', ''); - $redirectUrl = $request->query->getString('_redirect', ''); - - //Parse part IDs and load parts - $idArray = array_filter(array_map(intval(...), explode(',', $ids)), static fn (int $id): bool => $id > 0); - $parts = $this->entityManager->getRepository(Part::class)->findBy(['id' => $idArray]); - - if ($parts === []) { - $this->addFlash('error', 'batch_eda.no_parts_selected'); - - return $redirectUrl !== '' ? $this->redirect($redirectUrl) : $this->redirectToRoute('parts_show_all'); - } - - //Pre-populate form with shared values (when all parts have the same value) - $initialData = $this->getSharedEdaValues($parts); - $form = $this->createForm(BatchEdaType::class, $initialData); - $form->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - foreach ($parts as $part) { - $this->denyAccessUnlessGranted('edit', $part); - $edaInfo = $part->getEdaInfo(); - - if ($form->get('apply_reference_prefix')->getData()) { - $edaInfo->setReferencePrefix($form->get('reference_prefix')->getData() ?: null); - } - if ($form->get('apply_value')->getData()) { - $edaInfo->setValue($form->get('value')->getData() ?: null); - } - if ($form->get('apply_kicad_symbol')->getData()) { - $edaInfo->setKicadSymbol($form->get('kicad_symbol')->getData() ?: null); - } - if ($form->get('apply_kicad_footprint')->getData()) { - $edaInfo->setKicadFootprint($form->get('kicad_footprint')->getData() ?: null); - } - if ($form->get('apply_visibility')->getData()) { - $edaInfo->setVisibility($form->get('visibility')->getData()); - } - if ($form->get('apply_exclude_from_bom')->getData()) { - $edaInfo->setExcludeFromBom($form->get('exclude_from_bom')->getData()); - } - if ($form->get('apply_exclude_from_board')->getData()) { - $edaInfo->setExcludeFromBoard($form->get('exclude_from_board')->getData()); - } - if ($form->get('apply_exclude_from_sim')->getData()) { - $edaInfo->setExcludeFromSim($form->get('exclude_from_sim')->getData()); - } - } - - $this->entityManager->flush(); - $this->addFlash('success', 'batch_eda.success'); - - return $redirectUrl !== '' ? $this->redirect($redirectUrl) : $this->redirectToRoute('parts_show_all'); - } - - return $this->render('parts/batch_eda_edit.html.twig', [ - 'form' => $form->createView(), - 'parts' => $parts, - 'redirect_url' => $redirectUrl, - ]); - } -} diff --git a/src/Controller/KiCadApiController.php b/src/Controller/KiCadApiController.php index 76727877..c28e87a6 100644 --- a/src/Controller/KiCadApiController.php +++ b/src/Controller/KiCadApiController.php @@ -27,8 +27,6 @@ use App\Entity\Parts\Category; use App\Entity\Parts\Part; use App\Services\EDA\KiCadHelper; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; -use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Attribute\Route; @@ -57,16 +55,15 @@ class KiCadApiController extends AbstractController } #[Route('/categories.json', name: 'kicad_api_categories')] - public function categories(Request $request): Response + public function categories(): Response { $this->denyAccessUnlessGranted('@categories.read'); - $data = $this->kiCADHelper->getCategories(); - return $this->createCacheableJsonResponse($request, $data, 300); + return $this->json($this->kiCADHelper->getCategories()); } #[Route('/parts/category/{category}.json', name: 'kicad_api_category')] - public function categoryParts(Request $request, ?Category $category): Response + public function categoryParts(?Category $category): Response { if ($category !== null) { $this->denyAccessUnlessGranted('read', $category); @@ -75,31 +72,14 @@ class KiCadApiController extends AbstractController } $this->denyAccessUnlessGranted('@parts.read'); - $minimal = $request->query->getBoolean('minimal', false); - $data = $this->kiCADHelper->getCategoryParts($category, $minimal); - return $this->createCacheableJsonResponse($request, $data, 300); + return $this->json($this->kiCADHelper->getCategoryParts($category)); } #[Route('/parts/{part}.json', name: 'kicad_api_part')] - public function partDetails(Request $request, Part $part): Response + public function partDetails(Part $part): Response { $this->denyAccessUnlessGranted('read', $part); - $data = $this->kiCADHelper->getKiCADPart($part); - return $this->createCacheableJsonResponse($request, $data, 60); - } - - /** - * Creates a JSON response with HTTP cache headers (ETag and Cache-Control). - * Returns 304 Not Modified if the client's ETag matches. - */ - private function createCacheableJsonResponse(Request $request, array $data, int $maxAge): Response - { - $response = new JsonResponse($data); - $response->setEtag(md5(json_encode($data))); - $response->headers->set('Cache-Control', 'private, max-age=' . $maxAge); - $response->isNotModified($request); - - return $response; + return $this->json($this->kiCADHelper->getKiCADPart($part)); } } \ No newline at end of file diff --git a/src/DataTables/Helpers/PartDataTableHelper.php b/src/DataTables/Helpers/PartDataTableHelper.php index 54094ff1..c33c3a82 100644 --- a/src/DataTables/Helpers/PartDataTableHelper.php +++ b/src/DataTables/Helpers/PartDataTableHelper.php @@ -115,61 +115,6 @@ class PartDataTableHelper return implode('
', $tmp); } - /** - * Renders an EDA/KiCad completeness indicator for the given part. - * Shows icons for symbol, footprint, and value status. - */ - public function renderEdaStatus(Part $context): string - { - $edaInfo = $context->getEdaInfo(); - $category = $context->getCategory(); - $footprint = $context->getFootprint(); - - // Determine effective values (direct or inherited) - $hasSymbol = $edaInfo->getKicadSymbol() !== null || $category?->getEdaInfo()->getKicadSymbol() !== null; - $hasFootprint = $edaInfo->getKicadFootprint() !== null || $footprint?->getEdaInfo()->getKicadFootprint() !== null; - $hasReference = $edaInfo->getReferencePrefix() !== null || $category?->getEdaInfo()->getReferencePrefix() !== null; - - $symbolInherited = $edaInfo->getKicadSymbol() === null && $category?->getEdaInfo()->getKicadSymbol() !== null; - $footprintInherited = $edaInfo->getKicadFootprint() === null && $footprint?->getEdaInfo()->getKicadFootprint() !== null; - - $icons = []; - - // Symbol status - if ($hasSymbol) { - $title = $this->translator->trans('eda.status.symbol_set'); - $class = $symbolInherited ? 'text-info' : 'text-success'; - $icons[] = sprintf('', $class, $title); - } - - // Footprint status - if ($hasFootprint) { - $title = $this->translator->trans('eda.status.footprint_set'); - $class = $footprintInherited ? 'text-info' : 'text-success'; - $icons[] = sprintf('', $class, $title); - } - - // Reference prefix status - if ($hasReference) { - $icons[] = sprintf('', - $this->translator->trans('eda.status.reference_set')); - } - - if (empty($icons)) { - return ''; - } - - // Overall status: all 3 = green check, partial = yellow - $allSet = $hasSymbol && $hasFootprint && $hasReference; - $statusIcon = $allSet - ? sprintf('', $this->translator->trans('eda.status.complete')) - : sprintf('', $this->translator->trans('eda.status.partial')); - - // Wrap in link to EDA settings tab (data-turbo=false to ensure hash is read on page load) - $editUrl = $this->entityURLGenerator->editURL($context) . '#eda'; - return sprintf('%s', $editUrl, $statusIcon); - } - public function renderAmount(Part $context): string { $amount = $context->getAmountSum(); diff --git a/src/DataTables/PartsDataTable.php b/src/DataTables/PartsDataTable.php index 8bb5f6aa..d2faba76 100644 --- a/src/DataTables/PartsDataTable.php +++ b/src/DataTables/PartsDataTable.php @@ -89,10 +89,6 @@ final class PartsDataTable implements DataTableTypeInterface $this->configureOptions($resolver); $options = $resolver->resolve($options); - /************************************************************************************************************* - * When adding columns here, add them also to PartTableColumns enum, to make them configurable in the settings! - *************************************************************************************************************/ - $this->csh //Color the table rows depending on the review and favorite status ->add('row_color', RowClassColumn::class, [ @@ -232,21 +228,6 @@ final class PartsDataTable implements DataTableTypeInterface ]) ->add('attachments', PartAttachmentsColumn::class, [ 'label' => $this->translator->trans('part.table.attachments'), - ]) - ->add('eda_reference', TextColumn::class, [ - 'label' => $this->translator->trans('part.table.eda_reference'), - 'render' => static fn($value, Part $context) => htmlspecialchars($context->getEdaInfo()->getReferencePrefix() ?? ''), - 'orderField' => 'NATSORT(part.eda_info.reference_prefix)' - ]) - ->add('eda_value', TextColumn::class, [ - 'label' => $this->translator->trans('part.table.eda_value'), - 'render' => static fn($value, Part $context) => htmlspecialchars($context->getEdaInfo()->getValue() ?? ''), - 'orderField' => 'NATSORT(part.eda_info.value)' - ]) - ->add('eda_status', TextColumn::class, [ - 'label' => $this->translator->trans('part.table.eda_status'), - 'render' => fn($value, Part $context) => $this->partDataTableHelper->renderEdaStatus($context), - 'className' => 'text-center', ]); //Add a column to list the projects where the part is used, when the user has the permission to see the projects diff --git a/src/Entity/Parameters/AbstractParameter.php b/src/Entity/Parameters/AbstractParameter.php index f47f2e82..d84e68ad 100644 --- a/src/Entity/Parameters/AbstractParameter.php +++ b/src/Entity/Parameters/AbstractParameter.php @@ -172,13 +172,6 @@ abstract class AbstractParameter extends AbstractNamedDBElement implements Uniqu #[Assert\Length(max: 255)] protected string $group = ''; - /** - * @var bool|null Whether this parameter should be exported as a field in the EDA HTTP library API. Null means use system default. - */ - #[Groups(['full', 'parameter:read', 'parameter:write', 'import'])] - #[ORM\Column(type: Types::BOOLEAN, nullable: true, options: ['default' => null])] - protected ?bool $eda_visibility = null; - /** * Mapping is done in subclasses. * @@ -478,21 +471,6 @@ abstract class AbstractParameter extends AbstractNamedDBElement implements Uniqu return static::ALLOWED_ELEMENT_CLASS; } - public function isEdaVisibility(): ?bool - { - return $this->eda_visibility; - } - - /** - * @return $this - */ - public function setEdaVisibility(?bool $eda_visibility): self - { - $this->eda_visibility = $eda_visibility; - - return $this; - } - public function getComparableFields(): array { return ['name' => $this->name, 'group' => $this->group, 'element' => $this->element?->getId()]; diff --git a/src/Entity/PriceInformations/Orderdetail.php b/src/Entity/PriceInformations/Orderdetail.php index 56428e3a..58f69598 100644 --- a/src/Entity/PriceInformations/Orderdetail.php +++ b/src/Entity/PriceInformations/Orderdetail.php @@ -122,13 +122,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N #[ORM\Column(type: Types::BOOLEAN)] protected bool $obsolete = false; - /** - * @var bool|null Whether this orderdetail's supplier part number should be exported as an EDA field. Null means use system default. - */ - #[Groups(['full', 'import', 'orderdetail:read', 'orderdetail:write'])] - #[ORM\Column(type: Types::BOOLEAN, nullable: true, options: ['default' => null])] - protected ?bool $eda_visibility = null; - /** * @var string The URL to the product on the supplier's website */ @@ -425,21 +418,6 @@ class Orderdetail extends AbstractDBElement implements TimeStampableInterface, N return $this; } - public function isEdaVisibility(): ?bool - { - return $this->eda_visibility; - } - - /** - * @return $this - */ - public function setEdaVisibility(?bool $eda_visibility): self - { - $this->eda_visibility = $eda_visibility; - - return $this; - } - public function getName(): string { return $this->getSupplierPartNr(); diff --git a/src/Form/LabelSystem/ScanDialogType.php b/src/Form/LabelSystem/ScanDialogType.php index 5f9ce65f..cd1440c6 100644 --- a/src/Form/LabelSystem/ScanDialogType.php +++ b/src/Form/LabelSystem/ScanDialogType.php @@ -61,8 +61,6 @@ class ScanDialogType extends AbstractType 'attr' => [ 'autofocus' => true, 'id' => 'scan_dialog_input', - 'style' => 'font-family: var(--bs-font-monospace)', - 'data-controller' => 'elements--nonprintable-char-input', ], ]); diff --git a/src/Form/ParameterType.php b/src/Form/ParameterType.php index f68c3921..4c2174ae 100644 --- a/src/Form/ParameterType.php +++ b/src/Form/ParameterType.php @@ -54,9 +54,7 @@ use App\Entity\Parameters\StorageLocationParameter; use App\Entity\Parameters\SupplierParameter; use App\Entity\Parts\MeasurementUnit; use App\Form\Type\ExponentialNumberType; -use App\Form\Type\TriStateCheckboxType; use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\Extension\Core\Type\CheckboxType; use Symfony\Component\Form\Extension\Core\Type\NumberType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; @@ -149,14 +147,6 @@ class ParameterType extends AbstractType 'class' => 'form-control-sm', ], ]); - - // Only show the EDA visibility field for part parameters, as it has no function for other entities - if ($options['data_class'] === PartParameter::class) { - $builder->add('eda_visibility', TriStateCheckboxType::class, [ - 'label' => false, - 'required' => false, - ]); - } } public function finishView(FormView $view, FormInterface $form, array $options): void diff --git a/src/Form/Part/EDA/BatchEdaType.php b/src/Form/Part/EDA/BatchEdaType.php deleted file mode 100644 index 28fc4a41..00000000 --- a/src/Form/Part/EDA/BatchEdaType.php +++ /dev/null @@ -1,116 +0,0 @@ -add('reference_prefix', TextType::class, [ - 'label' => 'eda_info.reference_prefix', - 'required' => false, - 'attr' => ['placeholder' => t('eda_info.reference_prefix.placeholder')], - ]) - ->add('apply_reference_prefix', CheckboxType::class, [ - 'label' => 'batch_eda.apply', - 'required' => false, - 'mapped' => false, - ]) - ->add('value', TextType::class, [ - 'label' => 'eda_info.value', - 'required' => false, - 'attr' => ['placeholder' => t('eda_info.value.placeholder')], - ]) - ->add('apply_value', CheckboxType::class, [ - 'label' => 'batch_eda.apply', - 'required' => false, - 'mapped' => false, - ]) - ->add('kicad_symbol', KicadFieldAutocompleteType::class, [ - 'label' => 'eda_info.kicad_symbol', - 'type' => KicadFieldAutocompleteType::TYPE_SYMBOL, - 'required' => false, - 'attr' => ['placeholder' => t('eda_info.kicad_symbol.placeholder')], - ]) - ->add('apply_kicad_symbol', CheckboxType::class, [ - 'label' => 'batch_eda.apply', - 'required' => false, - 'mapped' => false, - ]) - ->add('kicad_footprint', KicadFieldAutocompleteType::class, [ - 'label' => 'eda_info.kicad_footprint', - 'type' => KicadFieldAutocompleteType::TYPE_FOOTPRINT, - 'required' => false, - 'attr' => ['placeholder' => t('eda_info.kicad_footprint.placeholder')], - ]) - ->add('apply_kicad_footprint', CheckboxType::class, [ - 'label' => 'batch_eda.apply', - 'required' => false, - 'mapped' => false, - ]) - ->add('visibility', TriStateCheckboxType::class, [ - 'label' => 'eda_info.visibility', - 'required' => false, - ]) - ->add('apply_visibility', CheckboxType::class, [ - 'label' => 'batch_eda.apply', - 'required' => false, - 'mapped' => false, - ]) - ->add('exclude_from_bom', TriStateCheckboxType::class, [ - 'label' => 'eda_info.exclude_from_bom', - 'required' => false, - ]) - ->add('apply_exclude_from_bom', CheckboxType::class, [ - 'label' => 'batch_eda.apply', - 'required' => false, - 'mapped' => false, - ]) - ->add('exclude_from_board', TriStateCheckboxType::class, [ - 'label' => 'eda_info.exclude_from_board', - 'required' => false, - ]) - ->add('apply_exclude_from_board', CheckboxType::class, [ - 'label' => 'batch_eda.apply', - 'required' => false, - 'mapped' => false, - ]) - ->add('exclude_from_sim', TriStateCheckboxType::class, [ - 'label' => 'eda_info.exclude_from_sim', - 'required' => false, - ]) - ->add('apply_exclude_from_sim', CheckboxType::class, [ - 'label' => 'batch_eda.apply', - 'required' => false, - 'mapped' => false, - ]) - ->add('submit', SubmitType::class, [ - 'label' => 'batch_eda.submit', - 'attr' => ['class' => 'btn btn-primary'], - ]); - } - - public function configureOptions(OptionsResolver $resolver): void - { - $resolver->setDefaults([ - 'data_class' => null, - ]); - } -} diff --git a/src/Form/Part/OrderdetailType.php b/src/Form/Part/OrderdetailType.php index 6a0dd940..ca295c7e 100644 --- a/src/Form/Part/OrderdetailType.php +++ b/src/Form/Part/OrderdetailType.php @@ -79,11 +79,6 @@ class OrderdetailType extends AbstractType 'label' => 'orderdetails.edit.prices_includes_vat', ]); - $builder->add('eda_visibility', TriStateCheckboxType::class, [ - 'required' => false, - 'label' => 'orderdetails.edit.eda_visibility', - ]); - //Add pricedetails after we know the data, so we can set the default currency $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options): void { /** @var Orderdetail $orderdetail */ diff --git a/src/Helpers/RandomizeUseragentHttpClient.php b/src/Helpers/RandomizeUseragentHttpClient.php deleted file mode 100644 index bca91c79..00000000 --- a/src/Helpers/RandomizeUseragentHttpClient.php +++ /dev/null @@ -1,100 +0,0 @@ -. - */ - -declare(strict_types=1); - - -namespace App\Helpers; - -use Symfony\Contracts\HttpClient\HttpClientInterface; -use Symfony\Contracts\HttpClient\ResponseInterface; -use Symfony\Contracts\HttpClient\ResponseStreamInterface; - -/** - * HttpClient wrapper that randomizes the user agent for each request, to make it harder for servers to detect and block us. - * When we get a 503, 403 or 429, we assume that the server is blocking us and try again with a different user agent, until we run out of retries. - */ -final class RandomizeUseragentHttpClient implements HttpClientInterface -{ - public const USER_AGENTS = [ - "Mozilla/5.0 (Windows; U; Windows NT 10.0; Win64; x64) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/52.0.1359.302 Safari/600.6 Edge/15.25690", - "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299", - "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 8_8_3) Gecko/20100101 Firefox/51.6", - "Mozilla/5.0 (Android; Android 4.4.4; E:number:20-23:00 Build/24.0.B.1.34) AppleWebKit/603.18 (KHTML, like Gecko) Chrome/47.0.1559.384 Mobile Safari/600.5", - "Mozilla/5.0 (compatible; MSIE 9.0; Windows; Windows NT 6.3; WOW64 Trident/5.0)", - "Mozilla/5.0 (Windows; Windows NT 6.0; Win64; x64) AppleWebKit/602.21 (KHTML, like Gecko) Chrome/51.0.3187.154 Safari/536", - "Mozilla/5.0 (iPhone; CPU iPhone OS 9_4_2; like Mac OS X) AppleWebKit/537.24 (KHTML, like Gecko) Chrome/51.0.2432.275 Mobile Safari/535.6", - "Mozilla/5.0 (U; Linux i680 ) Gecko/20100101 Firefox/57.5", - "Mozilla/5.0 (Macintosh; Intel Mac OS X 8_8_6; en-US) Gecko/20100101 Firefox/53.9", - "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 8_6_7) AppleWebKit/534.46 (KHTML, like Gecko) Chrome/55.0.3276.345 Safari/535", - "Mozilla/5.0 (Windows; Windows NT 10.5;) AppleWebKit/535.42 (KHTML, like Gecko) Chrome/53.0.1176.353 Safari/534.0 Edge/11.95743", - "Mozilla/5.0 (Linux; Android 5.1.1; MOTO G Build/LPH223) AppleWebKit/600.27 (KHTML, like Gecko) Chrome/47.0.1604.204 Mobile Safari/535.1", - "Mozilla/5.0 (iPod; CPU iPod OS 7_4_8; like Mac OS X) AppleWebKit/534.17 (KHTML, like Gecko) Chrome/50.0.1632.146 Mobile Safari/600.4", - "Mozilla/5.0 (Linux; U; Linux i570 ; en-US) Gecko/20100101 Firefox/49.9", - "Mozilla/5.0 (Windows NT 10.2; WOW64; en-US) AppleWebKit/603.2 (KHTML, like Gecko) Chrome/55.0.1299.311 Safari/535", - "Mozilla/5.0 (Windows; Windows NT 10.5; x64; en-US) AppleWebKit/603.39 (KHTML, like Gecko) Chrome/52.0.1443.139 Safari/536.6 Edge/13.79436", - "Mozilla/5.0 (Linux; U; Android 5.1; SM-G9350T Build/MMB29M) AppleWebKit/537.15 (KHTML, like Gecko) Chrome/55.0.2552.307 Mobile Safari/600.8", - "Mozilla/5.0 (Android; Android 6.0; SAMSUNG SM-D9350V Build/MDB08L) AppleWebKit/535.30 (KHTML, like Gecko) Chrome/53.0.1345.278 Mobile Safari/537.4", - "Mozilla/5.0 (Windows; Windows NT 10.0;) AppleWebKit/534.44 (KHTML, like Gecko) Chrome/47.0.3503.387 Safari/601", - ]; - - public function __construct( - private readonly HttpClientInterface $client, - private readonly array $userAgents = self::USER_AGENTS, - private readonly int $repeatOnFailure = 1, - ) { - } - - public function getRandomUserAgent(): string - { - return $this->userAgents[array_rand($this->userAgents)]; - } - - public function request(string $method, string $url, array $options = []): ResponseInterface - { - $repeatsLeft = $this->repeatOnFailure; - do { - $modifiedOptions = $options; - if (!isset($modifiedOptions['headers']['User-Agent'])) { - $modifiedOptions['headers']['User-Agent'] = $this->getRandomUserAgent(); - } - $response = $this->client->request($method, $url, $modifiedOptions); - - //When we get a 503, 403 or 429, we assume that the server is blocking us and try again with a different user agent - if (!in_array($response->getStatusCode(), [403, 429, 503], true)) { - return $response; - } - - //Otherwise we try again with a different user agent, until we run out of retries - } while ($repeatsLeft-- > 0); - - return $response; - } - - public function stream(iterable|ResponseInterface $responses, ?float $timeout = null): ResponseStreamInterface - { - return $this->client->stream($responses, $timeout); - } - - public function withOptions(array $options): static - { - return new self($this->client->withOptions($options), $this->userAgents, $this->repeatOnFailure); - } -} diff --git a/src/Serializer/PartNormalizer.php b/src/Serializer/PartNormalizer.php index 8486a634..775df77f 100644 --- a/src/Serializer/PartNormalizer.php +++ b/src/Serializer/PartNormalizer.php @@ -55,15 +55,6 @@ class PartNormalizer implements NormalizerInterface, DenormalizerInterface, Norm 'spn' => 'supplier_part_number', 'supplier_product_number' => 'supplier_part_number', 'storage_location' => 'storelocation', - //EDA/KiCad field aliases - 'kicad_symbol' => 'eda_kicad_symbol', - 'kicad_footprint' => 'eda_kicad_footprint', - 'kicad_reference' => 'eda_reference_prefix', - 'kicad_value' => 'eda_value', - 'eda_exclude_bom' => 'eda_exclude_from_bom', - 'eda_exclude_board' => 'eda_exclude_from_board', - 'eda_exclude_sim' => 'eda_exclude_from_sim', - 'eda_invisible' => 'eda_visibility', ]; public function __construct( @@ -199,45 +190,9 @@ class PartNormalizer implements NormalizerInterface, DenormalizerInterface, Norm } } - //Handle EDA/KiCad fields - $this->applyEdaFields($object, $data); - return $object; } - /** - * Apply EDA/KiCad fields from CSV data to the Part's EDAPartInfo. - */ - private function applyEdaFields(Part $part, array $data): void - { - $edaInfo = $part->getEdaInfo(); - - if (!empty($data['eda_kicad_symbol'])) { - $edaInfo->setKicadSymbol(trim((string) $data['eda_kicad_symbol'])); - } - if (!empty($data['eda_kicad_footprint'])) { - $edaInfo->setKicadFootprint(trim((string) $data['eda_kicad_footprint'])); - } - if (!empty($data['eda_reference_prefix'])) { - $edaInfo->setReferencePrefix(trim((string) $data['eda_reference_prefix'])); - } - if (!empty($data['eda_value'])) { - $edaInfo->setValue(trim((string) $data['eda_value'])); - } - if (isset($data['eda_exclude_from_bom']) && $data['eda_exclude_from_bom'] !== '') { - $edaInfo->setExcludeFromBom(filter_var($data['eda_exclude_from_bom'], FILTER_VALIDATE_BOOLEAN)); - } - if (isset($data['eda_exclude_from_board']) && $data['eda_exclude_from_board'] !== '') { - $edaInfo->setExcludeFromBoard(filter_var($data['eda_exclude_from_board'], FILTER_VALIDATE_BOOLEAN)); - } - if (isset($data['eda_exclude_from_sim']) && $data['eda_exclude_from_sim'] !== '') { - $edaInfo->setExcludeFromSim(filter_var($data['eda_exclude_from_sim'], FILTER_VALIDATE_BOOLEAN)); - } - if (isset($data['eda_visibility']) && $data['eda_visibility'] !== '') { - $edaInfo->setVisibility(filter_var($data['eda_visibility'], FILTER_VALIDATE_BOOLEAN)); - } - } - /** * @return bool[] */ diff --git a/src/Services/EDA/KiCadHelper.php b/src/Services/EDA/KiCadHelper.php index be4532ce..3a613fe7 100644 --- a/src/Services/EDA/KiCadHelper.php +++ b/src/Services/EDA/KiCadHelper.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace App\Services\EDA; -use App\Entity\Attachments\Attachment; use App\Entity\Parts\Category; use App\Entity\Parts\Footprint; use App\Entity\Parts\Part; @@ -44,9 +43,6 @@ class KiCadHelper /** @var int The maximum level of the shown categories. 0 Means only the top level categories are shown. -1 means only a single one containing */ private readonly int $category_depth; - /** @var bool Whether to resolve actual datasheet PDF URLs (true) or use Part-DB page links (false) */ - private readonly bool $datasheetAsPdf; - public function __construct( private readonly NodesListBuilder $nodesListBuilder, private readonly TagAwareCacheInterface $kicadCache, @@ -55,10 +51,9 @@ class KiCadHelper private readonly UrlGeneratorInterface $urlGenerator, private readonly EntityURLGenerator $entityURLGenerator, private readonly TranslatorInterface $translator, - private readonly KiCadEDASettings $kiCadEDASettings, + KiCadEDASettings $kiCadEDASettings, ) { $this->category_depth = $kiCadEDASettings->categoryDepth; - $this->datasheetAsPdf = $kiCadEDASettings->datasheetAsPdf ?? true; } /** @@ -120,16 +115,11 @@ class KiCadHelper } //Format the category for KiCAD - // Use the category comment as description if available, otherwise use the Part-DB URL - $description = $category->getComment(); - if ($description === null || $description === '') { - $description = $this->entityURLGenerator->listPartsURL($category); - } - $result[] = [ 'id' => (string)$category->getId(), 'name' => $category->getFullPath('/'), - 'description' => $description, + //Show the category link as the category description, this also fixes an segfault in KiCad see issue #878 + 'description' => $this->entityURLGenerator->listPartsURL($category), ]; } @@ -141,13 +131,11 @@ class KiCadHelper * Returns an array of objects containing all parts for the given category in the format required by KiCAD. * The result is cached for performance and invalidated on category or part changes. * @param Category|null $category - * @param bool $minimal If true, only return id and name (faster for symbol chooser listing) * @return array */ - public function getCategoryParts(?Category $category, bool $minimal = false): array + public function getCategoryParts(?Category $category): array { - $cacheKey = 'kicad_category_parts_'.($category?->getID() ?? 0) . '_' . $this->category_depth . ($minimal ? '_min' : ''); - return $this->kicadCache->get($cacheKey, + return $this->kicadCache->get('kicad_category_parts_'.($category?->getID() ?? 0) . '_' . $this->category_depth, function (ItemInterface $item) use ($category) { $item->tag([ $this->tagGenerator->getElementTypeCacheTag(Category::class), @@ -210,22 +198,14 @@ class KiCadHelper $result["fields"]["value"] = $this->createField($part->getEdaInfo()->getValue() ?? $part->getName(), true); $result["fields"]["keywords"] = $this->createField($part->getTags()); - //Use the part info page as Part-DB link. It must be an absolute URL. - $partUrl = $this->urlGenerator->generate( - 'part_info', - ['id' => $part->getId()], - UrlGeneratorInterface::ABSOLUTE_URL + //Use the part info page as datasheet link. It must be an absolute URL. + $result["fields"]["datasheet"] = $this->createField( + $this->urlGenerator->generate( + 'part_info', + ['id' => $part->getId()], + UrlGeneratorInterface::ABSOLUTE_URL) ); - //Try to find an actual datasheet attachment (configurable: PDF URL vs Part-DB page link) - if ($this->datasheetAsPdf) { - $datasheetUrl = $this->findDatasheetUrl($part); - $result["fields"]["datasheet"] = $this->createField($datasheetUrl ?? $partUrl); - } else { - $result["fields"]["datasheet"] = $this->createField($partUrl); - } - $result["fields"]["Part-DB URL"] = $this->createField($partUrl); - //Add basic fields $result["fields"]["description"] = $this->createField($part->getDescription()); if ($part->getCategory() !== null) { @@ -265,7 +245,32 @@ class KiCadHelper $result["fields"]["Part-DB IPN"] = $this->createField($part->getIpn()); } - //Add KiCost manufacturer fields (always present, independent of orderdetails) + // Add supplier information from orderdetails (include obsolete orderdetails) + if ($part->getOrderdetails(false)->count() > 0) { + $supplierCounts = []; + + foreach ($part->getOrderdetails(false) as $orderdetail) { + if ($orderdetail->getSupplier() !== null && $orderdetail->getSupplierPartNr() !== '') { + $supplierName = $orderdetail->getSupplier()->getName(); + + $supplierName .= " SPN"; // Append "SPN" to the supplier name to indicate Supplier Part Number + + if (!isset($supplierCounts[$supplierName])) { + $supplierCounts[$supplierName] = 0; + } + $supplierCounts[$supplierName]++; + + // Create field name with sequential number if more than one from same supplier (e.g. "Mouser", "Mouser 2", etc.) + $fieldName = $supplierCounts[$supplierName] > 1 + ? $supplierName . ' ' . $supplierCounts[$supplierName] + : $supplierName; + + $result["fields"][$fieldName] = $this->createField($orderdetail->getSupplierPartNr()); + } + } + } + + //Add fields for KiCost: if ($part->getManufacturer() !== null) { $result["fields"]["manf"] = $this->createField($part->getManufacturer()->getName()); } @@ -273,74 +278,13 @@ class KiCadHelper $result['fields']['manf#'] = $this->createField($part->getManufacturerProductNumber()); } - // Add supplier information from orderdetails (include obsolete orderdetails) - // If any orderdetail has eda_visibility explicitly set to true, only export those; - // otherwise export all (backward compat when no flags are set) - $allOrderdetails = $part->getOrderdetails(false); - if ($allOrderdetails->count() > 0) { - $hasExplicitEdaVisibility = false; - foreach ($allOrderdetails as $od) { - if ($od->isEdaVisibility() !== null) { - $hasExplicitEdaVisibility = true; - break; - } - } - - $supplierCounts = []; - foreach ($allOrderdetails as $orderdetail) { + //For each supplier, add a field with the supplier name and the supplier part number for KiCost + if ($part->getOrderdetails(false)->count() > 0) { + foreach ($part->getOrderdetails(false) as $orderdetail) { if ($orderdetail->getSupplier() !== null && $orderdetail->getSupplierPartNr() !== '') { - // When explicit flags exist, filter by resolved visibility - $resolvedVisibility = $orderdetail->isEdaVisibility() ?? $this->kiCadEDASettings->defaultOrderdetailsVisibility; - if ($hasExplicitEdaVisibility && !$resolvedVisibility) { - continue; - } - - $supplierName = $orderdetail->getSupplier()->getName() . ' SPN'; - - if (!isset($supplierCounts[$supplierName])) { - $supplierCounts[$supplierName] = 0; - } - $supplierCounts[$supplierName]++; - - // Create field name with sequential number if more than one from same supplier - $fieldName = $supplierCounts[$supplierName] > 1 - ? $supplierName . ' ' . $supplierCounts[$supplierName] - : $supplierName; + $fieldName = mb_strtolower($orderdetail->getSupplier()->getName()) . '#'; $result["fields"][$fieldName] = $this->createField($orderdetail->getSupplierPartNr()); - - //Also add a KiCost-compatible field (supplier_name# = SPN) - $kicostFieldName = mb_strtolower($orderdetail->getSupplier()->getName()) . '#'; - $result["fields"][$kicostFieldName] = $this->createField($orderdetail->getSupplierPartNr()); - } - } - } - - //Add stock quantity and storage locations (only count non-expired lots with known quantity) - $totalStock = 0; - $locations = []; - foreach ($part->getPartLots() as $lot) { - $isAvailable = !$lot->isInstockUnknown() && $lot->isExpired() !== true; - if ($isAvailable) { - $totalStock += $lot->getAmount(); - if ($lot->getAmount() > 0 && $lot->getStorageLocation() !== null) { - $locations[] = $lot->getStorageLocation()->getName(); - } - } - } - $result['fields']['Stock'] = $this->createField($totalStock); - if ($locations !== []) { - $result['fields']['Storage Location'] = $this->createField(implode(', ', array_unique($locations))); - } - - //Add parameters marked for EDA export (explicit true, or system default when null) - foreach ($part->getParameters() as $parameter) { - $paramVisibility = $parameter->isEdaVisibility() ?? $this->kiCadEDASettings->defaultParameterVisibility; - if ($paramVisibility && $parameter->getName() !== '') { - $fieldName = $parameter->getName(); - //Don't overwrite hardcoded fields - if (!isset($result['fields'][$fieldName])) { - $result['fields'][$fieldName] = $this->createField($parameter->getFormattedValue()); } } } @@ -400,7 +344,7 @@ class KiCadHelper //If the user set a visibility, then use it if ($eda_info->getVisibility() !== null) { - return $eda_info->getVisibility(); + return $part->getEdaInfo()->getVisibility(); } //If the part has a category, then use the category visibility if possible @@ -451,64 +395,4 @@ class KiCadHelper 'visible' => $this->boolToKicadBool($visible), ]; } - - /** - * Finds the URL to the actual datasheet file for the given part. - * Searches attachments by type name, attachment name, and file extension. - * @return string|null The datasheet URL, or null if no datasheet was found. - */ - private function findDatasheetUrl(Part $part): ?string - { - $firstPdf = null; - - foreach ($part->getAttachments() as $attachment) { - //Check if the attachment type name contains "datasheet" - $typeName = $attachment->getAttachmentType()?->getName() ?? ''; - if (str_contains(mb_strtolower($typeName), 'datasheet')) { - return $this->getAttachmentUrl($attachment); - } - - //Check if the attachment name contains "datasheet" - $name = mb_strtolower($attachment->getName()); - if (str_contains($name, 'datasheet') || str_contains($name, 'data sheet')) { - return $this->getAttachmentUrl($attachment); - } - - //Track first PDF as fallback (check internal extension or external URL path) - if ($firstPdf === null) { - $extension = $attachment->getExtension(); - if ($extension === null && $attachment->hasExternal()) { - $urlPath = parse_url($attachment->getExternalPath(), PHP_URL_PATH); - $extension = is_string($urlPath) ? strtolower(pathinfo($urlPath, PATHINFO_EXTENSION)) : null; - } - if ($extension === 'pdf') { - $firstPdf = $attachment; - } - } - } - - //Use first PDF attachment as fallback - if ($firstPdf !== null) { - return $this->getAttachmentUrl($firstPdf); - } - - return null; - } - - /** - * Returns an absolute URL for viewing the given attachment. - * Prefers the external URL (direct link) over the internal view route. - */ - private function getAttachmentUrl(Attachment $attachment): string - { - if ($attachment->hasExternal()) { - return $attachment->getExternalPath(); - } - - return $this->urlGenerator->generate( - 'attachment_view', - ['id' => $attachment->getId()], - UrlGeneratorInterface::ABSOLUTE_URL - ); - } -} +} \ No newline at end of file diff --git a/src/Services/ImportExportSystem/BOMImporter.php b/src/Services/ImportExportSystem/BOMImporter.php index e6518687..abf72d74 100644 --- a/src/Services/ImportExportSystem/BOMImporter.php +++ b/src/Services/ImportExportSystem/BOMImporter.php @@ -396,14 +396,10 @@ class BOMImporter } } - // Create unique key for this entry. - // When linked to a Part-DB part, use the part ID as key (merges footprint variants). - // Otherwise, use name (which includes package) to avoid merging unrelated components. - $entry_key = $part !== null - ? 'part:' . $part->getID() - : 'name:' . $name; + // Create unique key for this entry (name + part ID) + $entry_key = $name . '|' . ($part ? $part->getID() : 'null'); - // Check if we already have an entry with the same key + // Check if we already have an entry with the same name and part if (isset($entries_by_key[$entry_key])) { // Merge with existing entry $existing_entry = $entries_by_key[$entry_key]; @@ -417,22 +413,14 @@ class BOMImporter $existing_quantity = $existing_entry->getQuantity(); $existing_entry->setQuantity($existing_quantity + $quantity); - // Track footprint variants in comment when merging entries with different packages - $currentPackage = trim($mapped_entry['Package'] ?? ''); - if ($currentPackage !== '' && !str_contains($existing_entry->getComment(), $currentPackage)) { - $comment = $existing_entry->getComment(); - $existing_entry->setComment($comment . ', Footprint variant: ' . $currentPackage); - } - $this->logger->info('Merged duplicate BOM entry', [ 'name' => $name, - 'part_id' => $part?->getID(), + 'part_id' => $part ? $part->getID() : null, 'original_quantity' => $existing_quantity, 'added_quantity' => $quantity, 'new_quantity' => $existing_quantity + $quantity, 'original_mountnames' => $existing_mountnames, 'added_mountnames' => $designator, - 'package' => $currentPackage, ]); continue; // Skip creating new entry diff --git a/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php b/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php index bd6d30e6..ada72ea2 100644 --- a/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php +++ b/src/Services/InfoProviderSystem/Providers/GenericWebProvider.php @@ -24,7 +24,6 @@ declare(strict_types=1); namespace App\Services\InfoProviderSystem\Providers; use App\Exceptions\ProviderIDNotSupportedException; -use App\Helpers\RandomizeUseragentHttpClient; use App\Services\InfoProviderSystem\DTOs\ParameterDTO; use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; use App\Services\InfoProviderSystem\DTOs\PriceDTO; @@ -55,8 +54,11 @@ class GenericWebProvider implements InfoProviderInterface private readonly ProviderRegistry $providerRegistry, private readonly PartInfoRetriever $infoRetriever, ) { - $this->httpClient = (new RandomizeUseragentHttpClient($httpClient))->withOptions( + $this->httpClient = $httpClient->withOptions( [ + 'headers' => [ + 'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', + ], 'timeout' => 15, ] ); diff --git a/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php b/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php index 81f0a449..88bf33cb 100644 --- a/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php +++ b/src/Services/InfoProviderSystem/Providers/ReicheltProvider.php @@ -23,7 +23,6 @@ declare(strict_types=1); namespace App\Services\InfoProviderSystem\Providers; -use App\Helpers\RandomizeUseragentHttpClient; use App\Services\InfoProviderSystem\DTOs\FileDTO; use App\Services\InfoProviderSystem\DTOs\ParameterDTO; use App\Services\InfoProviderSystem\DTOs\PartDetailDTO; @@ -31,6 +30,7 @@ use App\Services\InfoProviderSystem\DTOs\PriceDTO; use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO; use App\Services\InfoProviderSystem\DTOs\SearchResultDTO; use App\Settings\InfoProviderSystem\ReicheltSettings; +use Symfony\Component\DependencyInjection\Attribute\Autowire; use Symfony\Component\DomCrawler\Crawler; use Symfony\Contracts\HttpClient\HttpClientInterface; @@ -39,13 +39,10 @@ class ReicheltProvider implements InfoProviderInterface public const DISTRIBUTOR_NAME = "Reichelt"; - private readonly HttpClientInterface $client; - - public function __construct(HttpClientInterface $client, + public function __construct(private readonly HttpClientInterface $client, private readonly ReicheltSettings $settings, ) { - $this->client = new RandomizeUseragentHttpClient($client); } public function getProviderInfo(): array diff --git a/src/Services/Parts/PartsTableActionHandler.php b/src/Services/Parts/PartsTableActionHandler.php index b0353e29..945cff7b 100644 --- a/src/Services/Parts/PartsTableActionHandler.php +++ b/src/Services/Parts/PartsTableActionHandler.php @@ -127,15 +127,6 @@ implode(',', array_map(static fn (PartLot $lot) => $lot->getID(), $part->getPart ); } - if ($action === 'batch_edit_eda') { - $ids = implode(',', array_map(static fn (Part $part) => $part->getID(), $selected_parts)); - return new RedirectResponse( - $this->urlGenerator->generate('batch_eda_edit', [ - 'ids' => $ids, - '_redirect' => $redirect_url - ]) - ); - } //Iterate over the parts and apply the action to it: foreach ($selected_parts as $part) { diff --git a/src/Settings/BehaviorSettings/PartTableColumns.php b/src/Settings/BehaviorSettings/PartTableColumns.php index 3b30e0a4..2ea66525 100644 --- a/src/Settings/BehaviorSettings/PartTableColumns.php +++ b/src/Settings/BehaviorSettings/PartTableColumns.php @@ -51,13 +51,6 @@ enum PartTableColumns : string implements TranslatableInterface case GTIN = "gtin"; case TAGS = "tags"; case ATTACHMENTS = "attachments"; - - case EDA_REFERENCE = "eda_reference"; - - case EDA_VALUE = "eda_value"; - - case EDA_STATUS = "eda_status"; - case EDIT = "edit"; public function trans(TranslatorInterface $translator, ?string $locale = null): string diff --git a/src/Settings/MiscSettings/KiCadEDASettings.php b/src/Settings/MiscSettings/KiCadEDASettings.php index cf31bd95..d8f1026d 100644 --- a/src/Settings/MiscSettings/KiCadEDASettings.php +++ b/src/Settings/MiscSettings/KiCadEDASettings.php @@ -43,23 +43,4 @@ class KiCadEDASettings envVar: "int:EDA_KICAD_CATEGORY_DEPTH", envVarMode: EnvVarMode::OVERWRITE)] #[Assert\Range(min: -1)] public int $categoryDepth = 0; - - #[SettingsParameter(label: new TM("settings.misc.kicad_eda.datasheet_link"), - description: new TM("settings.misc.kicad_eda.datasheet_link.help") - )] - public ?bool $datasheetAsPdf = true; - - #[SettingsParameter( - label: new TM("settings.misc.kicad_eda.default_parameter_visibility"), - description: new TM("settings.misc.kicad_eda.default_parameter_visibility.help"), - - )] - public bool $defaultParameterVisibility = false; - - #[SettingsParameter( - label: new TM("settings.misc.kicad_eda.default_orderdetails_visibility"), - description: new TM("settings.misc.kicad_eda.default_orderdetails_visibility.help"), - - )] - public bool $defaultOrderdetailsVisibility = false; -} +} \ No newline at end of file diff --git a/templates/base.html.twig b/templates/base.html.twig index afc7a8bf..62f0ce53 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -2,7 +2,7 @@ @@ -73,17 +73,9 @@ {{ encore_entry_script_tags('webauthn_tfa') }} {% endblock %} - - -{# Listen for the special #} -{% if is_granted("@tools.label_scanner") %} -
- -
-{% endif %} - {% block body %}
@@ -129,13 +121,13 @@ {# Must be outside of the sidebar or it will be hidden too #} diff --git a/templates/components/datatables.macro.html.twig b/templates/components/datatables.macro.html.twig index 90f8a3e1..d7873498 100644 --- a/templates/components/datatables.macro.html.twig +++ b/templates/components/datatables.macro.html.twig @@ -62,9 +62,6 @@ - - - diff --git a/templates/parts/batch_eda_edit.html.twig b/templates/parts/batch_eda_edit.html.twig deleted file mode 100644 index b1ca533c..00000000 --- a/templates/parts/batch_eda_edit.html.twig +++ /dev/null @@ -1,88 +0,0 @@ -{% extends "main_card.html.twig" %} - -{% block title %}{% trans %}batch_eda.title{% endtrans %}{% endblock %} - -{% block card_title %} - {% trans %}batch_eda.title{% endtrans %} -{% endblock %} - -{% block card_content %} -
-

{% trans with {'%count%': parts|length} %}batch_eda.description{% endtrans %}

-
- {% trans %}batch_eda.show_parts{% endtrans %} - -
-
- - {{ form_start(form) }} - -

{% trans %}batch_eda.apply_hint{% endtrans %}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{% trans %}batch_eda.apply{% endtrans %}{% trans %}batch_eda.field{% endtrans %}{% trans %}batch_eda.value{% endtrans %}
{{ form_widget(form.apply_reference_prefix) }}{{ form_label(form.reference_prefix) }}{{ form_widget(form.reference_prefix, {'attr': {'class': 'form-control-sm'}}) }}{{ form_errors(form.reference_prefix) }}
{{ form_widget(form.apply_value) }}{{ form_label(form.value) }}{{ form_widget(form.value, {'attr': {'class': 'form-control-sm'}}) }}{{ form_errors(form.value) }}
{{ form_widget(form.apply_kicad_symbol) }}{{ form_label(form.kicad_symbol) }}{{ form_widget(form.kicad_symbol) }}{{ form_errors(form.kicad_symbol) }}
{{ form_widget(form.apply_kicad_footprint) }}{{ form_label(form.kicad_footprint) }}{{ form_widget(form.kicad_footprint) }}{{ form_errors(form.kicad_footprint) }}
{{ form_widget(form.apply_visibility) }}{{ form_label(form.visibility) }}{{ form_widget(form.visibility) }}
{{ form_widget(form.apply_exclude_from_bom) }}{{ form_label(form.exclude_from_bom) }}{{ form_widget(form.exclude_from_bom) }}
{{ form_widget(form.apply_exclude_from_board) }}{{ form_label(form.exclude_from_board) }}{{ form_widget(form.exclude_from_board) }}
{{ form_widget(form.apply_exclude_from_sim) }}{{ form_label(form.exclude_from_sim) }}{{ form_widget(form.exclude_from_sim) }}
- -
- {% if redirect_url %} - {% trans %}batch_eda.cancel{% endtrans %} - {% else %} - {% trans %}batch_eda.cancel{% endtrans %} - {% endif %} - {{ form_widget(form.submit) }} -
- - {{ form_end(form) }} -{% endblock %} diff --git a/templates/parts/edit/_specifications.html.twig b/templates/parts/edit/_specifications.html.twig index 6f631b9f..25b00133 100644 --- a/templates/parts/edit/_specifications.html.twig +++ b/templates/parts/edit/_specifications.html.twig @@ -14,7 +14,6 @@ {% trans %}specifications.unit{% endtrans %} {% trans %}specifications.text{% endtrans %} {% trans %}specifications.group{% endtrans %} - diff --git a/templates/parts/edit/edit_form_styles.html.twig b/templates/parts/edit/edit_form_styles.html.twig index 9e989c92..844c8700 100644 --- a/templates/parts/edit/edit_form_styles.html.twig +++ b/templates/parts/edit/edit_form_styles.html.twig @@ -33,7 +33,6 @@ {{ form_row(form.supplier_product_url, {'attr': {'class': 'form-control-sm'}}) }} {{ form_widget(form.obsolete) }} {{ form_widget(form.pricesIncludesVAT) }} - {{ form_widget(form.eda_visibility) }}
@@ -80,9 +79,6 @@ {{ form_widget(form.unit, {"attr": {"data-pages--parameters-autocomplete-target": "unit", "data-pages--latex-preview-target": "input"}}) }}{{ form_errors(form.unit) }} {{ form_widget(form.value_text) }}{{ form_errors(form.value_text) }} {{ form_widget(form.group) }}{{ form_errors(form.group) }} - {% if form.eda_visibility is defined %} - {{ form_widget(form.eda_visibility) }} - {% endif %}