* Fix: Correct manifest.json.php for logo handling # FIX: Update manifest.json.php for logo handling All the alternative logo settings were applied only when MAIN_INFO_SOCIETE_LOGO_SQUARRED is true, also implying a duplicate test. It seems more likely that only one of the options is needed. So changed it to a simple else clause (no extra condition) * Qual: Ignore PHPStan notice * Fix: PHPStan notice When `!empty($valuetoshow)` already tests `(string) $valuetoshow != '0'`. * Qual: Fix Phan notices in modulebuilder updates # Qual: Fix Phan notices in modulebuilder updates Fix PhanCompatibleTypedProperty, PhanPluginRedundantReturnComment notices
151 lines
5.2 KiB
PHP
151 lines
5.2 KiB
PHP
<?php
|
||
/* Copyright (C) 2026 ATM Consulting <support@atm-consulting.fr>
|
||
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
|
||
*
|
||
* This program is free software: you can redistribute it and/or modify
|
||
* it under the terms of the GNU 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 General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
*/
|
||
|
||
/**
|
||
* \file htdocs/modulebuilder/class/NamingContract.class.php
|
||
* \ingroup modulebuilder
|
||
* \brief Immutable value object for module/object name substitutions.
|
||
*/
|
||
|
||
/**
|
||
* Immutable value object holding all case variants of a module/object pair.
|
||
*
|
||
* Provides the canonical, ordered substitution map used by modulebuilder template generation.
|
||
* The substitution order in getSubstitutionMap() is deterministic: uppercase and mixed-case
|
||
* tokens always precede lowercase ones, preventing partial matches when str_replace processes
|
||
* entries sequentially on the same string.
|
||
*
|
||
* applyTo() uses str_replace() directly — NOT make_substitutions() — to avoid unintended
|
||
* processing of Dolibarr's __(key)__ and __[key]__ patterns present in raw template content.
|
||
*/
|
||
final class NamingContract
|
||
{
|
||
/** @var string PascalCase module name, e.g. "MyModule" */
|
||
public $moduleNameCase;
|
||
|
||
/** @var string Lowercase module name, e.g. "mymodule" */
|
||
public $moduleNameLower;
|
||
|
||
/** @var string Uppercase module name, e.g. "MYMODULE" */
|
||
public $moduleNameUpper;
|
||
|
||
/** @var string PascalCase object name, e.g. "MyObject" (empty string for module-only contracts) */
|
||
public $objectNameCase;
|
||
|
||
/** @var string Lowercase object name, e.g. "myobject" (empty string for module-only contracts) */
|
||
public $objectNameLower;
|
||
|
||
/** @var string Uppercase object name, e.g. "MYOBJECT" (empty string for module-only contracts) */
|
||
public $objectNameUpper;
|
||
|
||
/**
|
||
* @param string $moduleName Raw module name — accepts any casing, ucfirst() is applied
|
||
* @param string $objectName Raw object name — empty string creates a module-only contract
|
||
* @throws \InvalidArgumentException If module and object names are identical (case-insensitive)
|
||
*/
|
||
public function __construct(string $moduleName, string $objectName = '')
|
||
{
|
||
$this->moduleNameCase = ucfirst($moduleName);
|
||
$this->moduleNameLower = strtolower($moduleName);
|
||
$this->moduleNameUpper = strtoupper($moduleName);
|
||
|
||
if ($objectName === '') {
|
||
$this->objectNameCase = '';
|
||
$this->objectNameLower = '';
|
||
$this->objectNameUpper = '';
|
||
return;
|
||
}
|
||
|
||
if (strtolower($moduleName) === strtolower($objectName)) {
|
||
throw new \InvalidArgumentException(
|
||
'Module and object names cannot be identical (case-insensitive match): "'
|
||
. $moduleName . '" vs "' . $objectName . '"'
|
||
);
|
||
}
|
||
|
||
$this->objectNameCase = ucfirst($objectName);
|
||
$this->objectNameLower = strtolower($objectName);
|
||
$this->objectNameUpper = strtoupper($objectName);
|
||
}
|
||
|
||
/**
|
||
* Returns the canonical, ordered substitution map.
|
||
*
|
||
* Order matters: uppercase and mixed-case tokens precede lowercase tokens so that
|
||
* str_replace sequential processing cannot partially consume a longer token variant.
|
||
* Object tokens (positions 8–12) are omitted for module-only contracts (objectName = '').
|
||
*
|
||
* @return array<string, string>
|
||
*/
|
||
public function getSubstitutionMap(): array
|
||
{
|
||
$map = [
|
||
'MYMODULE' => $this->moduleNameUpper,
|
||
'MyModule' => $this->moduleNameCase,
|
||
'My module' => $this->moduleNameCase,
|
||
'my module' => $this->moduleNameLower,
|
||
'Mon module' => $this->moduleNameCase,
|
||
'mon module' => $this->moduleNameLower,
|
||
'mymodule' => $this->moduleNameLower,
|
||
];
|
||
|
||
if ($this->objectNameLower !== '') {
|
||
$map['MYOBJECT'] = $this->objectNameUpper;
|
||
$map['MyObject'] = $this->objectNameCase;
|
||
$map['My Object'] = $this->objectNameCase;
|
||
$map['my object'] = $this->objectNameLower;
|
||
$map['myobject'] = $this->objectNameLower;
|
||
}
|
||
|
||
return $map;
|
||
}
|
||
|
||
/**
|
||
* Apply the canonical substitution map to a string (file content).
|
||
*
|
||
* @param string $content File content to process
|
||
* @return string Content with substitutions applied
|
||
*/
|
||
public function applyTo(string $content): string
|
||
{
|
||
$map = $this->getSubstitutionMap();
|
||
return str_replace(array_keys($map), array_values($map), $content);
|
||
}
|
||
|
||
/**
|
||
* Apply substitution to a filename (lowercase tokens only).
|
||
*
|
||
* Filenames in Dolibarr are always lowercase — only mymodule/myobject are substituted.
|
||
* For module-only contracts (objectNameLower = ''), myobject is not substituted.
|
||
*
|
||
* @param string $filename Template filename containing mymodule/myobject placeholders
|
||
* @return string File name with substitutions applied
|
||
*/
|
||
public function applyToFilename(string $filename): string
|
||
{
|
||
$search = ['mymodule'];
|
||
$replace = [$this->moduleNameLower];
|
||
|
||
if ($this->objectNameLower !== '') {
|
||
$search[] = 'myobject';
|
||
$replace[] = $this->objectNameLower;
|
||
}
|
||
|
||
return str_replace($search, $replace, $filename);
|
||
}
|
||
}
|