Change our template attribute processing, to be collections, so we can find attributes using anycase keys
This commit is contained in:
parent
ee3cb395c2
commit
3ad4c446ea
@ -13,7 +13,7 @@ class Template
|
|||||||
private const LOGKEY = 'T--';
|
private const LOGKEY = 'T--';
|
||||||
|
|
||||||
private(set) string $file;
|
private(set) string $file;
|
||||||
private array $template;
|
private Collection $template;
|
||||||
private(set) bool $invalid = FALSE;
|
private(set) bool $invalid = FALSE;
|
||||||
private(set) string $reason = '';
|
private(set) string $reason = '';
|
||||||
private Collection $on_change_target;
|
private Collection $on_change_target;
|
||||||
@ -31,7 +31,7 @@ class Template
|
|||||||
try {
|
try {
|
||||||
// @todo Load in the proper attribute objects and objectclass objects
|
// @todo Load in the proper attribute objects and objectclass objects
|
||||||
// @todo Make sure we have a structural objectclass, or make the template invalid
|
// @todo Make sure we have a structural objectclass, or make the template invalid
|
||||||
$this->template = json_decode($td->get($file),null,512,JSON_OBJECT_AS_ARRAY|JSON_THROW_ON_ERROR);
|
$this->template = collect(json_decode($td->get($file),null,512,JSON_OBJECT_AS_ARRAY|JSON_THROW_ON_ERROR));
|
||||||
|
|
||||||
} catch (\JsonException $e) {
|
} catch (\JsonException $e) {
|
||||||
$this->invalid = TRUE;
|
$this->invalid = TRUE;
|
||||||
@ -42,12 +42,11 @@ class Template
|
|||||||
public function __get(string $key): mixed
|
public function __get(string $key): mixed
|
||||||
{
|
{
|
||||||
return match ($key) {
|
return match ($key) {
|
||||||
'attributes' => collect(Arr::get($this->template,$key))->keys(),
|
'attributes','objectclasses' => collect($this->template->get($key)),
|
||||||
'enabled' => Arr::get($this->template,$key,FALSE) && (! $this->invalid),
|
'enabled' => $this->template->get($key,FALSE) && (! $this->invalid),
|
||||||
'icon','regexp','title' => Arr::get($this->template,$key),
|
'icon','regexp','title' => $this->template->get($key),
|
||||||
'name' => Str::replaceEnd('.json','',$this->file),
|
'name' => Str::replaceEnd('.json','',$this->file),
|
||||||
'objectclasses' => collect(Arr::get($this->template,$key)),
|
'order' => $this->attributes->map(fn($item)=>Arr::get($item,'order')),
|
||||||
'order' => collect(Arr::get($this->template,'attributes'))->map(fn($item)=>$item['order']),
|
|
||||||
|
|
||||||
default => throw new \Exception('Unknown key: '.$key),
|
default => throw new \Exception('Unknown key: '.$key),
|
||||||
};
|
};
|
||||||
@ -55,7 +54,19 @@ class Template
|
|||||||
|
|
||||||
public function __isset(string $key): bool
|
public function __isset(string $key): bool
|
||||||
{
|
{
|
||||||
return array_key_exists($key,$this->template);
|
return $this->template->has($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the configuration for an attribute
|
||||||
|
*
|
||||||
|
* @param string $attribute
|
||||||
|
* @return array|NULL
|
||||||
|
*/
|
||||||
|
public function attribute(string $attribute): Collection|NULL
|
||||||
|
{
|
||||||
|
$key = $this->attributes->search(fn($item,$key)=>! strcasecmp($key,$attribute));
|
||||||
|
return collect($this->attributes->get($key));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,7 +77,7 @@ class Template
|
|||||||
*/
|
*/
|
||||||
public function attributeReadOnly(string $attribute): bool
|
public function attributeReadOnly(string $attribute): bool
|
||||||
{
|
{
|
||||||
return ($x=Arr::get($this->template,'attributes.'.$attribute.'.readonly')) && $x;
|
return ($x=$this->attribute($attribute)?->get('readonly')) && $x;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,7 +88,18 @@ class Template
|
|||||||
*/
|
*/
|
||||||
public function attributeTitle(string $attribute): string|NULL
|
public function attributeTitle(string $attribute): string|NULL
|
||||||
{
|
{
|
||||||
return Arr::get($this->template,'attributes.'.$attribute.'.display');
|
return $this->attribute($attribute)?->get('display');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the title we should use for an attribute
|
||||||
|
*
|
||||||
|
* @param string $attribute
|
||||||
|
* @return string|NULL
|
||||||
|
*/
|
||||||
|
public function attributeType(string $attribute): string|NULL
|
||||||
|
{
|
||||||
|
return $this->attribute($attribute)?->get('type');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,7 +57,7 @@ class HomeController extends Controller
|
|||||||
$o->objectclass = [Entry::TAG_NOTAG=>$template->objectclasses->toArray()];
|
$o->objectclass = [Entry::TAG_NOTAG=>$template->objectclasses->toArray()];
|
||||||
|
|
||||||
foreach ($o->getAvailableAttributes()
|
foreach ($o->getAvailableAttributes()
|
||||||
->filter(fn($item)=>$item->names_lc->intersect($template->attributes->map('strtolower'))->count())
|
->filter(fn($item)=>$item->names_lc->intersect($template->attributes->keys()->map('strtolower'))->count())
|
||||||
->sortBy(fn($item)=>Arr::get($template->order,$item->name)) as $ao)
|
->sortBy(fn($item)=>Arr::get($template->order,$item->name)) as $ao)
|
||||||
{
|
{
|
||||||
$o->{$ao->name} = [Entry::TAG_NOTAG=>''];
|
$o->{$ao->name} = [Entry::TAG_NOTAG=>''];
|
||||||
|
@ -9,13 +9,16 @@
|
|||||||
<strong class="align-middle"><abbr title="{{ (($x=$template?->attributeTitle($o->name)) ? $o->name.': ' : '').$o->description }}">{{ $x ?: $o->name }}</abbr></strong>
|
<strong class="align-middle"><abbr title="{{ (($x=$template?->attributeTitle($o->name)) ? $o->name.': ' : '').$o->description }}">{{ $x ?: $o->name }}</abbr></strong>
|
||||||
@if($new)
|
@if($new)
|
||||||
@if($template?->attributeReadOnly($o->name_lc))
|
@if($template?->attributeReadOnly($o->name_lc))
|
||||||
<sup data-bs-toggle="tooltip" title="@lang('Input disabled by template')"><i class="fas fa-ban"></i></sup>
|
<sup data-bs-toggle="tooltip" title="@lang('Input disabled')"><i class="fas fa-ban"></i></sup>
|
||||||
@endif
|
@endif
|
||||||
@if($template?->onChangeAttribute($o->name_lc))
|
@if($ca=$template?->onChangeAttribute($o->name_lc))
|
||||||
<sup data-bs-toggle="tooltip" title="@lang('Value triggers an update to another attribute by template')"><i class="fas fa-keyboard"></i></sup>
|
<sup data-bs-toggle="tooltip" title="@lang('Value triggers an update to another attribute')"><i class="fas fa-keyboard"></i></sup>
|
||||||
@endif
|
@endif
|
||||||
@if ($template?->onChangeTarget($o->name_lc))
|
@if ($ct=$template?->onChangeTarget($o->name_lc))
|
||||||
<sup data-bs-toggle="tooltip" title="@lang('Value calculated by template')"><i class="fas fa-wand-magic-sparkles"></i></sup>
|
<sup data-bs-toggle="tooltip" title="@lang('Value calculated from another attribute')"><i class="fas fa-wand-magic-sparkles"></i></sup>
|
||||||
|
@endif
|
||||||
|
@if((! $ca) && (! $ct) && $template?->attribute($o->name_lc))
|
||||||
|
<sup data-bs-toggle="tooltip" title="@lang('Attribute controlled by template')"><i class="fas fa-wand-magic"></i></sup>
|
||||||
@endif
|
@endif
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@ -59,7 +62,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@switch($template?->attributeType($o->name))
|
||||||
|
@case('type')
|
||||||
|
@break;
|
||||||
|
|
||||||
|
@default
|
||||||
<x-attribute :o="$o" :edit="(! $template?->attributeReadOnly($o->name)) && $edit" :new="$new" :updated="$updated"/>
|
<x-attribute :o="$o" :edit="(! $template?->attributeReadOnly($o->name)) && $edit" :new="$new" :updated="$updated"/>
|
||||||
|
@endswitch
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,31 +1,32 @@
|
|||||||
{
|
{
|
||||||
"title": "Example entry",
|
"title": "Example entry", // Title shown when selecting tempaltes
|
||||||
"description": "This is the description",
|
"description": "This is the description", // Unused, only for documenting
|
||||||
"enabled": false,
|
"enabled": false, // Whether template is enabled or not
|
||||||
"icon": "fa-star-of-life",
|
"icon": "fa-star-of-life", // Icon shown when rendering an existing entry that identifies as this template
|
||||||
"rdn": "o",
|
"rdn": "o", // @todo not implemented
|
||||||
"regexp": "/^$/",
|
"regexp": "/^$/", // Regular expression that restricts where this template cna be used
|
||||||
|
|
||||||
"objectclasses": [
|
"objectclasses": [ // Objectclasses that entries will have if they use this template
|
||||||
"organization"
|
"organization"
|
||||||
],
|
],
|
||||||
|
|
||||||
"attributes": {
|
"attributes": { // Attribute configuration
|
||||||
"attribute1": {
|
"attribute1": { // LDAP attribute name
|
||||||
"display": "Attribute 1",
|
"display": "Attribute 1", // Displayed when accepting input for this value
|
||||||
"hint": "This is an example",
|
"hint": "This is an example", // @todo not implemented
|
||||||
"order": 1
|
"type": null, // Default is NULL, so use normal Attribute rendering type
|
||||||
|
"order": 1 // Order to show attributes
|
||||||
},
|
},
|
||||||
"attribute2": {
|
"attribute2": {
|
||||||
"display": "Attribute 2",
|
"display": "Attribute 2",
|
||||||
"hint": "This is an example",
|
"hint": "This is an example",
|
||||||
"type": "input", // Default is input
|
"type": "input", // Force attribute to use template input
|
||||||
"order": 2
|
"order": 2
|
||||||
},
|
},
|
||||||
"attribute3": {
|
"attribute3": {
|
||||||
"display": "Attribute 3",
|
"display": "Attribute 3",
|
||||||
"type": "select",
|
"type": "select", // Force attribute to use template select
|
||||||
"options": {
|
"options": { // Select options
|
||||||
"/bin/bash": "Bash",
|
"/bin/bash": "Bash",
|
||||||
"/bin/csh": "C Shell",
|
"/bin/csh": "C Shell",
|
||||||
"/bin/dash": "Dash",
|
"/bin/dash": "Dash",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user