Teamleader Focus
Version 5.2.2
May 27, 2026
Security
- Removed public
$companyId,$dealId, and$userIdproperties from the Formie integration class — these held per-submission state and could risk cross-submission data leakage if Formie hydrated an integration from a stored representation. IDs are now scoped to local variables insendPayload()and passed as parameters to_prepPayload(). (#14)
Added
- Added "Update custom fields partially" option for Contacts to partially update their custom fields. (#24) - Thanks @ishetnogferre
- Added "Update custom fields partially" option for Companies to partially update their custom fields. (#24) - Thanks @ishetnogferre
Fixed
- Fixed
sendPayload()andfetchFormSettings()catching onlyyii\base\Exception, letting\RuntimeException, GuzzleHttp network errors, andIdentityProviderExceptionpropagate uncaught. Catches now broaden to\Exception|\Errorand route through Formie's normal error handling. (#13) - Fixed
_prepPayload()unconditionally overwriting the mapped deal title with the staticdealTitlesetting. Mapped form values are now respected; the static setting is the fallback when the mapped value is empty. (#18) - Fixed
_fetchCustomFields()crashing when the API response omits thedatakey (e.g. 204 responses, partial errors). (#20) - Fixed companies error logs encoding
$contactValuesinstead of$companyValues, making company-related API failures impossible to debug. (#20) - Fixed
getCurrencyOptions()making a live API call on every CP page render. Now cached for 24h on success only — API failures fall back to defaults without polluting the cache. (#21) - Fixed
contacts.linkToCompanyfailing with "already linked" when the contact is already attached to the company. Now checkscompanies.inforelated_contacts first and skips the link call when the contact is already present. (#22) - Thanks @ishetnogferre - Fixed
companies.infoincludesparameter on the already-linked check being sent as a JSON array instead of the documented comma-separated string. Teamleader would not have returned therelated_contactssideload, silently re-introducing the "already linked" error from #22. Now sent as a string.
Changed
- Removed
declare(strict_types=1)fromTeamleaderFocusRefreshTokenGrantper Craft CMS plugin conventions. (#12) - Extracted
API_BASE_URLto apublic conston the auth client class. Integration class and OAuth provider now reference the single source of truth. (#21) - Added
defineRules()to the Formie integration:dealTitleis required whenmapToDealsis enabled;defaultCurrencyis validated as a 3-char string. Existing saved integrations withmapToDeals=trueand an emptydealTitlewill fail validation on next save in the CP. (#21) - Loosened composer PHP constraint from
^8.2.0to^8.2. (#21) - Section headers,
@authorannotations, and PSR-12 formatting brought in line with Craft CMS plugin conventions across the codebase. (#16, #17, #19) - New option "Update custom fields partially" for Contacts and Companies is enabled by default. Existing integrations will switch from full-collection replacement to partial updates on next form submission after upgrade. (#24)
Version 5.2.1
April 2, 2026
Fixed
- Fixed country field only accepting labels (e.g., "Belgium") — now also accepts ISO codes (e.g., "BE") from prefilled dropdowns, with case-insensitive matching. (#8) - Thanks @ishetnogferre
- Fixed tags field only accepting arrays — now also normalizes comma-, semicolon-, and pipe-separated strings from hidden fields. (#10) - Thanks @ishetnogferre
- Fixed empty values in tag arrays not being filtered out, matching the string path behavior.
- Fixed
VatHelper::formatVatNumber()stripping letters from non-Belgian EU VAT numbers (FR, NL, IE, ES, etc.) and applying Belgian-specific dot formatting. Now validates against per-country EU patterns and outputs raw alphanumeric format as expected by the Teamleader Focus API. - Fixed
IdentityProviderExceptionbeing thrown with an empty error message in OAuth clientcheckResponse.
Changed
- Removed unused
$optionsparameter from_prepPayload()and dead$optionsvariable insendPayload(). - Added explicit
privatevisibility to OAuth/API URL constants in auth client (PHP 8.2). - Removed unused static
$pluginproperty from main plugin class — use inherited::getInstance()instead.
Version 5.2.0
January 18, 2026
Added
- Added "Tags" integration field for Contacts
- Added "Tags" integration field for Companies
- Added "Append Tags" option for Contacts to preserve existing tags during updates (uses
contacts.tagendpoint) - Added "Append Tags" option for Companies to preserve existing tags during updates (uses
companies.tagendpoint) - Added "Remarks" integration field for Contacts
- Added "Remarks" integration field for Companies
- Added "Summary" integration field for Deals
- Added
faxfield mapping for both contacts and companies. - Added
currencyfield mapping for deals - allows mapping currency from a form field. - Added
Default Currencysetting for deals - configurable fallback when currency is not mapped from a form field. - Added
CurrencyHelperclass for formatting currency options from Teamleader Focus API. - Added
Client Typecustom Formie field for B2B/B2C workflow differentiation. - B2B (Company) requests create contact + company + deal with linking.
- B2C (Client) requests create contact + deal only, skipping company creation.
- Field displays as radio buttons with configurable labels and default value.
- Added
ClientTypeHelperfor detecting client type from form submissions.
Changed
- Renamed Deals "Extra Information" field to "Summary" with correct API handle
Fixed
- Fixed Deals field using incorrect API handle
remarksinstead ofsummary - Fixed
linkToCompanytoggle having no effect - contacts are now properly linked to companies via thecontacts.linkToCompanyAPI endpoint when both entities exist and the setting is enabled. - Removed
mobile_phonefield from companies mapping - Teamleader Focus API only supportsphoneandfaxfor companies.
Version 5.1.1
January 15, 2026
Fixed
- Fixed custom fields not being sent in the correct API format (now properly structured as
custom_fieldsarray) - Fixed
contact_person_idsending empty string instead of being omitted when not applicable - Fixed
contact_person_idnow only included when customer is a company and a contact person exists - Fixed mobile phone type using
'phone'instead of'mobile'for the telephone type - Removed
contextfrom API payload (internal use only, not an API field)
Version 5.1.0
January 13, 2026
Added
- Added "Remarks" integration field for creating remarks via forms
- Added "estimated_value" integration field for pushing amounts to Teamleader Focus
Changed
- Refactored VAT number formatting into a reusable helper function
- Made email on companies optional to match Teamleader Focus API Specs
Fixed
- Fixed context filters not properly limiting API field results
- Fixed custom fields not saving correctly to Teamleader Focus
- Fixed address generation not conforming to Teamleader Focus API specs
- Fixed mobile_phone mapping incorrectly unsetting
phoneinstead ofmobile_phone - Fixed PHPStan return type in VatHelper::formatVatNumber()
Version 5.0.2
March 10, 2025
Fixed
- Fixed the path of the icon-mask to
teamleader, using an alias looks to the namespace, not the folder structure or plugin handle
Version 5.0.1
February 26, 2025
Fixed
- Fixed the template path of the settings templates to
teamleader-focusas the plugin had to be renamed
Version 5.0.0
February 24, 2025
- Initial Release