Several pages read a variable that is never defined on that page (copy/paste
from another page), so PHPStan level 10 flags 'Variable $x might not be
defined' and PHP 8 emits an undefined-variable warning with a null value:
- reception/card.php: $reception -> $object (matches the 10 other builddoc
blocks in the same file; otherwise the output PDF language is wrong)
- loan/payment/card.php: $object->id -> $id (page uses $id; matches the
adjacent enabled-button line)
- opensurvey/card.php: ConfirmRemovalOfPoll uses $id -> $numsondage
(otherwise the confirmation message placeholder is empty)
- opensurvey/results.php: guard $expiredate with !empty() (never defined on
this page; still falls back to $object->date_fin)
- projet/card.php: guard $morecss with !empty() (never defined here)
No behaviour change beyond removing the undefined-variable reads.
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
In htdocs/product/stock/stocktransfer/stocktransfer_contact.php the
'addcontact' action assigns $result only inside 'if ($object->id > 0)', but
the success test 'if ($result >= 0)' runs unconditionally. On a POST with no
id/ref the object is not fetched ($object->id == 0), so $result is undefined
and 'null >= 0' evaluates to true, redirecting as if the contact was added.
Initialize $result = -1 at the start of the block so the missing-object case
takes the error branch instead of a false-success redirect. PHPStan level 10
also flagged 'Variable $result might not be defined' here.
* FIX: Escape session list fields
* FIX: Cast nullable session fields before escaping
* Update ChangeLog with new features and fixes
---------
Co-authored-by: f-hoedl <hoefla14@htl-kaindorf.ac.at>
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
The MCP server (htdocs/ai/server/mcp_server.php) loads a service user
from AI_MCP_USER_ID but does not expose it as the PHP global $user.
Several tool classes call 'global $user' to identify the caller --
they therefore see no authenticated user in HTTP MCP context (no PHP
web session exists) and return 'User not authenticated' even though
authentication via X-API-Key/Bearer has already succeeded.
This breaks roughly 40% of the MCP tools shipped by the module when
called from external clients (Claude Desktop Custom Connectors,
Claude Code CLI, MCP Inspector, custom scripts).
Two complementary fixes applied:
1. mcp_server.php: after successfully loading the service user,
assign it to $GLOBALS['user'] and the local $user variable. This
acts as a safety net for any tool (current or third-party) that
relies on the legacy 'global $user' pattern.
2. Three tool classes harmonize their constructor signatures with
the McpHandler contract -- new $className($db, $user, $conf):
- ToolCrudObjects (htdocs/ai/tools/crud_objects.class.php)
- ToolInvoices (htdocs/ai/tools/invoices.class.php)
- ToolReports (htdocs/ai/tools/reports.class.php)
These now accept $user via constructor (matching the pattern
already used in ToolThirdParty, ToolCategories, ToolProducts)
and store it as $this->user. Methods that previously called
'global $user' (execute, validateInvoice, payInvoice) now use
the injected $this->user, with a fallback to the global for
web-session contexts.
Tested with:
- create_other_document (proposal, supplier_invoice): works
- search_invoice, validate_invoice, pay_invoice: works
- get_sales_report, get_purchase_report: works
- AI Assistant web UI: unchanged, no regression
Canvas::display_canvas() (htdocs/core/class/canvas.class.php) includes these
templates from inside a method and only imports $db,$conf,$langs,$user,
$canvas,$form,$formfile via 'global'. $objcanvas and $socid are never
brought into that scope, so they were undefined at runtime (the templates
already reconstruct the thirdparty object from $GLOBALS['objcanvas']).
- Derive $socid from the in-scope thirdparty object ($soc->id / $object->id),
fixing the empty socid used for $filedir/$urlsource/showdocuments().
- Replace the bare $objcanvas->control->object with the already-derived $soc
(company) / $object (individual).
For the company template $socid was previously masked from PHPStan by a
'@var int $socid' docblock; it is now actually defined.
# Qual: Fix database typo (DoliDb -> DoliDB)
The database handler type was updated from `DoliDb` to `DoliDB` in both `bookkeepingtemplate.class.php` and `bookkeepingtemplateline.class.php`.
# Qual: Update PHPDoc for setAsSelect method
- Update the type definition of the $fieldOptions parameter in the setAsSelect method to make the color, picto, labelhtml, and note fields optional.