custom prefix

This commit is contained in:
Yuri Kuznetsov
2024-02-15 16:20:51 +02:00
parent 0db4a9c672
commit 9f743b718a
10 changed files with 64 additions and 20 deletions
@@ -66,7 +66,7 @@ class EntityManager
* @throws Error
* @throws Conflict
*/
public function postActionCreateEntity(Request $request): bool
public function postActionCreateEntity(Request $request): stdClass
{
$data = $request->getParsedBody();
@@ -142,9 +142,9 @@ class EntityManager
$params['kanbanStatusIgnoreList'] = $data['kanbanStatusIgnoreList'];
}
$this->entityManagerTool->create($name, $type, $params);
$name = $this->entityManagerTool->create($name, $type, $params);
return true;
return (object) ['name' => $name];
}
/**
@@ -100,18 +100,18 @@ class FieldManager
$fieldManagerTool = $this->fieldManagerTool;
$fieldManagerTool->create($scope, $name, get_object_vars($data));
$name = $fieldManagerTool->create($scope, $name, get_object_vars($data));
try {
$this->dataManager->rebuild([$scope]);
}
catch (Error $e) {
$fieldManagerTool->delete($scope, $data->name);
$fieldManagerTool->delete($scope, $name);
throw new Error($e->getMessage());
}
return $fieldManagerTool->read($scope, $data->name);
return $fieldManagerTool->read($scope, $name);
}
/**
@@ -288,5 +288,6 @@ return [
'phoneNumberPreferredCountryList' => ['us', 'de'],
'adminUpgradeDisabled' => false,
'wysiwygCodeEditorDisabled' => false,
'customPrefixDisabled' => false,
'isInstalled' => false,
];
@@ -205,6 +205,7 @@ return [
'authAnotherUserDisabled',
'emailAddressEntityLookupDefaultOrder',
'phoneNumberEntityLookupDefaultOrder',
'customPrefixDisabled',
'latestVersion',
],
'superAdminItems' => [
@@ -71,11 +71,12 @@ class EntityManager
/**
* @param array<string, mixed> $params
* @return string An actual name.
* @throws BadRequest
* @throws Error
* @throws Conflict
*/
public function create(string $name, string $type, array $params = [], ?CreateParams $createParams = null): void
public function create(string $name, string $type, array $params = [], ?CreateParams $createParams = null): string
{
$createParams ??= new CreateParams();
@@ -97,6 +98,8 @@ class EntityManager
throw new Error("Type '$type' is not creatable.");
}
$name = $this->nameUtil->addCustomPrefix($name, true);
if ($this->nameUtil->nameIsBad($name)) {
throw new Error("Entity name should contain only letters and numbers, " .
"start with an upper case letter.");
@@ -285,6 +288,8 @@ class EntityManager
}
$this->dataManager->rebuild();
return $name;
}
/**
@@ -29,6 +29,7 @@
namespace Espo\Tools\EntityManager;
use Espo\Core\Utils\Config;
use Espo\Core\Utils\Metadata;
use Espo\Core\Utils\Route;
use Espo\Core\Utils\Util;
@@ -94,7 +95,8 @@ class NameUtil
private Metadata $metadata,
private ServiceFactory $serviceFactory,
private EntityManager $entityManager,
private Route $routeUtil
private Route $routeUtil,
private Config $config
) {}
public function nameIsBad(string $name): bool
@@ -244,4 +246,15 @@ class NameUtil
return false;
}
public function addCustomPrefix(string $name, bool $ucFirst = false): string
{
if ($this->config->get('customPrefixDisabled')) {
return $name;
}
$prefix = $ucFirst ? 'C' : 'c';
return $prefix . ucfirst($name);
}
}
@@ -40,6 +40,7 @@ use Espo\Core\Exceptions\Error;
use Espo\Core\Utils\Metadata\Helper as MetadataHelper;
use Espo\Core\Utils\Util;
use Espo\Tools\EntityManager\NameUtil;
use RuntimeException;
use stdClass;
@@ -87,7 +88,8 @@ class FieldManager
private Metadata $metadata,
private Language $language,
private Language $baseLanguage,
private MetadataHelper $metadataHelper
private MetadataHelper $metadataHelper,
private NameUtil $nameUtil
) {}
/**
@@ -113,16 +115,21 @@ class FieldManager
/**
* @param array<string, mixed> $fieldDefs
* @return string An actual name.
* @throws BadRequest
* @throws Conflict
* @throws Error
*/
public function create(string $scope, string $name, array $fieldDefs): void
public function create(string $scope, string $name, array $fieldDefs): string
{
if (strlen($name) === 0) {
throw new BadRequest("Empty field name.");
}
if (!$this->isScopeCustom($scope)) {
$name = $this->nameUtil->addCustomPrefix($name);
}
if (strlen(Util::camelCaseToUnderscore($name)) > self::MAX_NAME_LENGTH) {
throw Error::createWithBody(
"Field name should not be longer than " . self::MAX_NAME_LENGTH . ".",
@@ -199,6 +206,8 @@ class FieldManager
}
$this->update($scope, $name, $fieldDefs, true);
return $name;
}
/**
@@ -124,6 +124,8 @@ class LinkManager
$params['relationName'] :
lcfirst($entity) . $entityForeign;
$relationName = $this->nameUtil->addCustomPrefix($relationName);
if ($this->isNameTooLong($relationName)) {
throw new Error("Relation name is too long.");
}
@@ -141,6 +143,14 @@ class LinkManager
}
}
if (!$this->isScopeCustom($entity)) {
$link = $this->nameUtil->addCustomPrefix($link);
}
if (!$entityForeign || !$this->isScopeCustom($entityForeign)) {
$linkForeign = $this->nameUtil->addCustomPrefix($linkForeign);
}
$linkParams = LinkParams::createBuilder()
->setType($linkType)
->setEntityType($entity)
@@ -150,6 +160,10 @@ class LinkManager
->setName($relationName)
->build();
if (is_numeric($link[0]) || is_numeric($linkForeign[0])) {
throw new Error('Bad link name.');
}
if (
$this->isNameTooLong($link) ||
$this->isNameTooLong($linkForeign)
@@ -157,10 +171,6 @@ class LinkManager
throw new Error("Link name is too long.");
}
if (is_numeric($link[0]) || is_numeric($linkForeign[0])) {
throw new Error('Bad link name.');
}
if (preg_match('/[^a-z]/', $link[0])) {
throw new Error("Link name should start with a lower case letter.");
}
@@ -1089,4 +1099,9 @@ class LinkManager
$this->baseLanguage->save();
}
}
private function isScopeCustom(string $scope): bool
{
return (bool) $this->metadata->get("scopes.$scope.isCustom");
}
}
@@ -641,7 +641,7 @@ class EntityManagerEditView extends View {
Espo.Ui.notify(this.translate('pleaseWait', 'messages'));
Espo.Ajax.postRequest(url, data).then(() => {
Espo.Ajax.postRequest(url, data).then(/** Record */response => {
this.model.fetchedAttributes = this.model.getClonedAttributes();
this.scope ?
@@ -685,7 +685,7 @@ class EntityManagerEditView extends View {
this.getRecordView().setIsNotChanged();
if (this.isNew) {
this.getRouter().navigate('#Admin/entityManager/scope=' + name, {trigger: true});
this.getRouter().navigate(`#Admin/entityManager/scope=${response.name}`, {trigger: true});
}
});
})
@@ -60,7 +60,7 @@ class SanitizeTest extends BaseTestCase
'sicCode' => ' ',
'phoneNumber' => '+380 9044 433 11',
'description' => '',
'array' => [
'cArray' => [
' test ',
'hello',
],
@@ -73,7 +73,7 @@ class SanitizeTest extends BaseTestCase
$this->assertEquals('Test 1', $account->getName());
$this->assertEquals(null, $account->get('sicCode'));
$this->assertEquals(null, $account->get('description'));
$this->assertEquals(['test', 'hello'], $account->get('array'));
$this->assertEquals(['test', 'hello'], $account->get('cArray'));
/** @noinspection PhpUnhandledExceptionInspection */
/** @var Account $account */
@@ -88,11 +88,11 @@ class SanitizeTest extends BaseTestCase
],
],
'description' => 'Test',
'array' => null,
'cArray' => null,
], CreateParams::create());
$this->assertEquals('Test', $account->get('description'));
$this->assertEquals([], $account->get('array'));
$this->assertEquals([], $account->get('cArray'));
$numbers = $account->getPhoneNumberGroup()->getNumberList();
$this->assertCount(2, $numbers);