Compare commits

...

3 Commits

Author SHA1 Message Date
6599bb7f4f Fix deprecation message introduced by 3d511f3
All checks were successful
Create Docker Image / Test Application (x86_64) (push) Successful in 27s
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 1m24s
Create Docker Image / Build Docker Image (arm64) (push) Successful in 2m48s
Create Docker Image / Final Docker Image Manifest (push) Successful in 10s
2025-06-01 16:08:11 +10:00
d623f3c26d Move langtag rendering from dn/Entry into Attribute - more enhancements for #16,
Reduce use of style= tags,
Cosmetic layout changes,
Layout change to enable rendering template views,
<attribute> id tags are now lowecase
2025-06-01 16:08:11 +10:00
bd40ab0e84 Framework upgrade to Laravel 12 and javascript updates 2025-06-01 16:08:11 +10:00
46 changed files with 1036 additions and 998 deletions

View File

@ -3,7 +3,7 @@ run-name: ${{ gitea.actor }} Building Docker Image 🐳
on: [push] on: [push]
env: env:
DOCKER_HOST: tcp://127.0.0.1:2375 DOCKER_HOST: tcp://127.0.0.1:2375
ASSETS: 10eca55 ASSETS: 3fcb8707
jobs: jobs:
test: test:

View File

@ -148,6 +148,13 @@ class Attribute implements \Countable, \ArrayAccess
'description' => $this->schema ? $this->schema->{$key} : NULL, 'description' => $this->schema ? $this->schema->{$key} : NULL,
// Attribute hints // Attribute hints
'hints' => $this->hints(), 'hints' => $this->hints(),
// Attribute language tags
'langtags' => ($this->no_attr_tags || (! $this->_values->count()))
? collect(Entry::TAG_NOTAG)
: $this->_values
->keys()
->filter(fn($item)=>($item === Entry::TAG_NOTAG) || preg_match(sprintf('/%s;?/',Entry::TAG_CHARS_LANG),$item))
->sortBy(fn($item)=>($item === Entry::TAG_NOTAG) ? NULL : $item),
// Can this attribute be edited // Can this attribute be edited
'is_editable' => $this->schema ? $this->schema->{$key} : NULL, 'is_editable' => $this->schema ? $this->schema->{$key} : NULL,
// Is this an internal attribute // Is this an internal attribute
@ -198,17 +205,23 @@ class Attribute implements \Countable, \ArrayAccess
public function count(): int public function count(): int
{ {
return $this->_values->dot()->count(); return $this->_values
->dot()
->count();
} }
public function offsetExists(mixed $offset): bool public function offsetExists(mixed $offset): bool
{ {
return $this->_values->dot()->has($offset); return $this->_values
->dot()
->has($offset);
} }
public function offsetGet(mixed $offset): mixed public function offsetGet(mixed $offset): mixed
{ {
return $this->_values->dot()->get($offset); return $this->_values
->dot()
->get($offset);
} }
public function offsetSet(mixed $offset, mixed $value): void public function offsetSet(mixed $offset, mixed $value): void
@ -315,11 +328,10 @@ class Attribute implements \Countable, \ArrayAccess
* @param bool $edit Render an edit form * @param bool $edit Render an edit form
* @param bool $old Use old value * @param bool $old Use old value
* @param bool $new Enable adding values * @param bool $new Enable adding values
* @param string $langtag Langtag to use when rendering these attribute values
* @param bool $updated Has the entry been updated (uses rendering highlights)) * @param bool $updated Has the entry been updated (uses rendering highlights))
* @return View * @return View
*/ */
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
if ($this->is_internal) if ($this->is_internal)
// @note Internal attributes cannot be edited // @note Internal attributes cannot be edited
@ -340,7 +352,6 @@ class Attribute implements \Countable, \ArrayAccess
->with('edit',$edit) ->with('edit',$edit)
->with('old',$old) ->with('old',$old)
->with('new',$new) ->with('new',$new)
->with('langtag',$langtag)
->with('updated',$updated); ->with('updated',$updated);
} }
@ -376,7 +387,7 @@ class Attribute implements \Countable, \ArrayAccess
* *
* @return Collection * @return Collection
*/ */
public function required(): Collection private function required(): Collection
{ {
// If we dont have any objectclasses then we cant know if it is required // If we dont have any objectclasses then we cant know if it is required
return $this->oc->count() return $this->oc->count()

View File

@ -15,14 +15,13 @@ final class JpegPhoto extends Binary
{ {
use MD5Updates; use MD5Updates;
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
return view('components.attribute.binary.jpegphoto') return view('components.attribute.binary.jpegphoto')
->with('o',$this) ->with('o',$this)
->with('edit',$edit) ->with('edit',$edit)
->with('old',$old) ->with('old',$old)
->with('new',$new) ->with('new',$new)
->with('langtag',$langtag)
->with('updated',$updated) ->with('updated',$updated)
->with('f',new \finfo); ->with('f',new \finfo);
} }

View File

@ -12,7 +12,7 @@ use App\Ldap\Entry;
*/ */
final class Timestamp extends Internal final class Timestamp extends Internal
{ {
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
// @note Internal attributes cannot be edited // @note Internal attributes cannot be edited
return view('components.attribute.internal.timestamp') return view('components.attribute.internal.timestamp')

View File

@ -17,7 +17,7 @@ final class KrbPrincipalKey extends Attribute
protected(set) bool $no_attr_tags = TRUE; protected(set) bool $no_attr_tags = TRUE;
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
return view('components.attribute.krbprincipalkey') return view('components.attribute.krbprincipalkey')
->with('o',$this) ->with('o',$this)

View File

@ -50,7 +50,7 @@ final class KrbTicketFlags extends Attribute
return $helpers; return $helpers;
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
return view('components.attribute.krbticketflags') return view('components.attribute.krbticketflags')
->with('o',$this) ->with('o',$this)

View File

@ -70,7 +70,7 @@ final class ObjectClass extends Attribute
->contains($value); ->contains($value);
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
return view('components.attribute.objectclass') return view('components.attribute.objectclass')
->with('o',$this) ->with('o',$this)

View File

@ -80,7 +80,7 @@ final class Password extends Attribute
return ($helpers=static::helpers())->has($id) ? new ($helpers->get($id)) : NULL; return ($helpers=static::helpers())->has($id) ? new ($helpers->get($id)) : NULL;
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
return view('components.attribute.password') return view('components.attribute.password')
->with('o',$this) ->with('o',$this)

View File

@ -14,6 +14,9 @@ use App\Ldap\Entry;
final class RDN extends Attribute final class RDN extends Attribute
{ {
private string $base; private string $base;
protected(set) bool $no_attr_tags = TRUE;
private Collection $attrs; private Collection $attrs;
public function __get(string $key): mixed public function __get(string $key): mixed
@ -32,7 +35,7 @@ final class RDN extends Attribute
]); ]);
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
return view('components.attribute.rdn') return view('components.attribute.rdn')
->with('o',$this); ->with('o',$this);

View File

@ -54,7 +54,7 @@ abstract class Schema extends Attribute
__('No description available, can you help with one?')); __('No description available, can you help with one?'));
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
// @note Schema attributes cannot be edited // @note Schema attributes cannot be edited
return view('components.attribute.internal') return view('components.attribute.internal')

View File

@ -12,7 +12,7 @@ use App\Ldap\Entry;
*/ */
class Generic extends Schema class Generic extends Schema
{ {
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
// @note Schema attributes cannot be edited // @note Schema attributes cannot be edited
return view('components.attribute.schema.generic') return view('components.attribute.schema.generic')

View File

@ -34,7 +34,7 @@ final class Mechanisms extends Schema
return parent::_get(config_path('ldap_supported_saslmechanisms.txt'),$string,$key); return parent::_get(config_path('ldap_supported_saslmechanisms.txt'),$string,$key);
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
// @note Schema attributes cannot be edited // @note Schema attributes cannot be edited
return view('components.attribute.schema.mechanisms') return view('components.attribute.schema.mechanisms')

View File

@ -35,7 +35,7 @@ final class OID extends Schema
return parent::_get(config_path('ldap_supported_oids.txt'),$string,$key); return parent::_get(config_path('ldap_supported_oids.txt'),$string,$key);
} }
public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE): View public function render(bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE): View
{ {
// @note Schema attributes cannot be edited // @note Schema attributes cannot be edited
return view('components.attribute.schema.oid') return view('components.attribute.schema.oid')

View File

@ -356,7 +356,9 @@ class HomeController extends Controller
return Redirect::to('/') return Redirect::to('/')
->withInput() ->withInput()
->with('updated',collect($dirty) ->with('updated',collect($dirty)
->map(fn($item,$key)=>$o->getObject(collect(explode(';',$key))->first()))); ->map(fn($item,$key)=>$o->getObject(collect(explode(';',$key))->first()))
->values()
->unique());
} }
/** /**

View File

@ -21,11 +21,16 @@ use App\Exceptions\InvalidUsage;
class Entry extends Model class Entry extends Model
{ {
private const TAG_CHARS = 'a-zA-Z0-9-'; private const TAG_CHARS = 'a-zA-Z0-9-';
private const TAG_CHARS_LANG = 'lang-['.self::TAG_CHARS.']'; public const LANG_TAG_PREFIX = 'lang-';
public const TAG_CHARS_LANG = self::LANG_TAG_PREFIX.'['.self::TAG_CHARS.']+';
public const TAG_NOTAG = '_null_'; public const TAG_NOTAG = '_null_';
// Our Attribute objects // Our Attribute objects
private Collection $objects; private Collection $objects;
// Templates that apply to this entry
private(set) Collection $templates;
// For new entries, this is the container that this entry will be stored in // For new entries, this is the container that this entry will be stored in
private string $rdnbase; private string $rdnbase;
@ -34,6 +39,7 @@ class Entry extends Model
public function __construct(array $attributes = []) public function __construct(array $attributes = [])
{ {
$this->objects = collect(); $this->objects = collect();
$this->templates = collect(['default'=>__('LDAP Entry')]);
parent::__construct($attributes); parent::__construct($attributes);
} }
@ -308,14 +314,7 @@ class Entry extends Model
public function getLangTags(): Collection public function getLangTags(): Collection
{ {
return $this->getObjects() return $this->getObjects()
->filter(fn($item)=>! $item->no_attr_tags) ->map(fn($item)=>$item->langtags);
->map(fn($item)=>$item
->values
->keys()
->filter(fn($item)=>preg_match(sprintf('/%s+;?/',self::TAG_CHARS_LANG),$item))
->map(fn($item)=>preg_replace('/lang-/','',$item))
)
->filter(fn($item)=>$item->count());
} }
/** /**
@ -373,7 +372,7 @@ class Entry extends Model
$item && collect(explode(';',$item))->filter( $item && collect(explode(';',$item))->filter(
fn($item)=> fn($item)=>
(! preg_match(sprintf('/^%s$/',self::TAG_NOTAG),$item)) (! preg_match(sprintf('/^%s$/',self::TAG_NOTAG),$item))
&& (! preg_match(sprintf('/^%s+$/',self::TAG_CHARS_LANG),$item)) && (! preg_match(sprintf('/^%s$/',self::TAG_CHARS_LANG),$item))
) )
->count()) ->count())
) )

View File

@ -6,7 +6,6 @@ use Illuminate\Contracts\View\View;
use Illuminate\View\Component; use Illuminate\View\Component;
use App\Classes\LDAP\Attribute as LDAPAttribute; use App\Classes\LDAP\Attribute as LDAPAttribute;
use App\Ldap\Entry;
class Attribute extends Component class Attribute extends Component
{ {
@ -14,18 +13,17 @@ class Attribute extends Component
public bool $edit; public bool $edit;
public bool $new; public bool $new;
public bool $old; public bool $old;
public string $langtag; public bool $updated;
/** /**
* Create a new component instance. * Create a new component instance.
*/ */
public function __construct(?LDAPAttribute $o,bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,string $langtag=Entry::TAG_NOTAG,bool $updated=FALSE) public function __construct(?LDAPAttribute $o,bool $edit=FALSE,bool $old=FALSE,bool $new=FALSE,bool $updated=FALSE)
{ {
$this->o = $o; $this->o = $o;
$this->edit = $edit; $this->edit = $edit;
$this->old = $old; $this->old = $old;
$this->new = $new; $this->new = $new;
$this->langtag = $langtag;
$this->updated = $updated; $this->updated = $updated;
} }
@ -38,7 +36,7 @@ class Attribute extends Component
{ {
return $this->o return $this->o
? $this->o ? $this->o
->render(edit: $this->edit,old: $this->old,new: $this->new,langtag: $this->langtag,updated: $this->updated) ->render(edit: $this->edit,old: $this->old,new: $this->new,updated: $this->updated)
: __('Unknown'); : __('Unknown');
} }
} }

View File

@ -10,7 +10,7 @@
"ext-openssl": "*", "ext-openssl": "*",
"php": "^8.4", "php": "^8.4",
"directorytree/ldaprecord-laravel": "^3.0", "directorytree/ldaprecord-laravel": "^3.0",
"laravel/framework": "^11.9", "laravel/framework": "^12.0",
"laravel/sanctum": "^4.0", "laravel/sanctum": "^4.0",
"laravel/ui": "^4.5" "laravel/ui": "^4.5"
}, },

389
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "ddfbe582d0c27ef08ff1410102ccda28", "content-hash": "fe524438312a0b5d565ad83c191eac6a",
"packages": [ "packages": [
{ {
"name": "brick/math", "name": "brick/math",
@ -1199,20 +1199,20 @@
}, },
{ {
"name": "laravel/framework", "name": "laravel/framework",
"version": "v11.45.0", "version": "v12.16.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/framework.git", "url": "https://github.com/laravel/framework.git",
"reference": "d0730deb427632004d24801be7ca1ed2c10fbc4e" "reference": "293bb1c70224faebfd3d4328e201c37115da055f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/d0730deb427632004d24801be7ca1ed2c10fbc4e", "url": "https://api.github.com/repos/laravel/framework/zipball/293bb1c70224faebfd3d4328e201c37115da055f",
"reference": "d0730deb427632004d24801be7ca1ed2c10fbc4e", "reference": "293bb1c70224faebfd3d4328e201c37115da055f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", "brick/math": "^0.11|^0.12",
"composer-runtime-api": "^2.2", "composer-runtime-api": "^2.2",
"doctrine/inflector": "^2.0.5", "doctrine/inflector": "^2.0.5",
"dragonmantank/cron-expression": "^3.4", "dragonmantank/cron-expression": "^3.4",
@ -1227,32 +1227,32 @@
"fruitcake/php-cors": "^1.3", "fruitcake/php-cors": "^1.3",
"guzzlehttp/guzzle": "^7.8.2", "guzzlehttp/guzzle": "^7.8.2",
"guzzlehttp/uri-template": "^1.0", "guzzlehttp/uri-template": "^1.0",
"laravel/prompts": "^0.1.18|^0.2.0|^0.3.0", "laravel/prompts": "^0.3.0",
"laravel/serializable-closure": "^1.3|^2.0", "laravel/serializable-closure": "^1.3|^2.0",
"league/commonmark": "^2.7", "league/commonmark": "^2.7",
"league/flysystem": "^3.25.1", "league/flysystem": "^3.25.1",
"league/flysystem-local": "^3.25.1", "league/flysystem-local": "^3.25.1",
"league/uri": "^7.5.1", "league/uri": "^7.5.1",
"monolog/monolog": "^3.0", "monolog/monolog": "^3.0",
"nesbot/carbon": "^2.72.6|^3.8.4", "nesbot/carbon": "^3.8.4",
"nunomaduro/termwind": "^2.0", "nunomaduro/termwind": "^2.0",
"php": "^8.2", "php": "^8.2",
"psr/container": "^1.1.1|^2.0.1", "psr/container": "^1.1.1|^2.0.1",
"psr/log": "^1.0|^2.0|^3.0", "psr/log": "^1.0|^2.0|^3.0",
"psr/simple-cache": "^1.0|^2.0|^3.0", "psr/simple-cache": "^1.0|^2.0|^3.0",
"ramsey/uuid": "^4.7", "ramsey/uuid": "^4.7",
"symfony/console": "^7.0.3", "symfony/console": "^7.2.0",
"symfony/error-handler": "^7.0.3", "symfony/error-handler": "^7.2.0",
"symfony/finder": "^7.0.3", "symfony/finder": "^7.2.0",
"symfony/http-foundation": "^7.2.0", "symfony/http-foundation": "^7.2.0",
"symfony/http-kernel": "^7.0.3", "symfony/http-kernel": "^7.2.0",
"symfony/mailer": "^7.0.3", "symfony/mailer": "^7.2.0",
"symfony/mime": "^7.0.3", "symfony/mime": "^7.2.0",
"symfony/polyfill-php83": "^1.31", "symfony/polyfill-php83": "^1.31",
"symfony/process": "^7.0.3", "symfony/process": "^7.2.0",
"symfony/routing": "^7.0.3", "symfony/routing": "^7.2.0",
"symfony/uid": "^7.0.3", "symfony/uid": "^7.2.0",
"symfony/var-dumper": "^7.0.3", "symfony/var-dumper": "^7.2.0",
"tijsverkoyen/css-to-inline-styles": "^2.2.5", "tijsverkoyen/css-to-inline-styles": "^2.2.5",
"vlucas/phpdotenv": "^5.6.1", "vlucas/phpdotenv": "^5.6.1",
"voku/portable-ascii": "^2.0.2" "voku/portable-ascii": "^2.0.2"
@ -1316,17 +1316,17 @@
"league/flysystem-read-only": "^3.25.1", "league/flysystem-read-only": "^3.25.1",
"league/flysystem-sftp-v3": "^3.25.1", "league/flysystem-sftp-v3": "^3.25.1",
"mockery/mockery": "^1.6.10", "mockery/mockery": "^1.6.10",
"orchestra/testbench-core": "^9.13.2", "orchestra/testbench-core": "^10.0.0",
"pda/pheanstalk": "^5.0.6", "pda/pheanstalk": "^5.0.6|^7.0.0",
"php-http/discovery": "^1.15", "php-http/discovery": "^1.15",
"phpstan/phpstan": "^2.0", "phpstan/phpstan": "^2.0",
"phpunit/phpunit": "^10.5.35|^11.3.6|^12.0.1", "phpunit/phpunit": "^10.5.35|^11.5.3|^12.0.1",
"predis/predis": "^2.3", "predis/predis": "^2.3|^3.0",
"resend/resend-php": "^0.10.0", "resend/resend-php": "^0.10.0",
"symfony/cache": "^7.0.3", "symfony/cache": "^7.2.0",
"symfony/http-client": "^7.0.3", "symfony/http-client": "^7.2.0",
"symfony/psr-http-message-bridge": "^7.0.3", "symfony/psr-http-message-bridge": "^7.2.0",
"symfony/translation": "^7.0.3" "symfony/translation": "^7.2.0"
}, },
"suggest": { "suggest": {
"ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).",
@ -1352,22 +1352,22 @@
"mockery/mockery": "Required to use mocking (^1.6).", "mockery/mockery": "Required to use mocking (^1.6).",
"pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).",
"php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).",
"phpunit/phpunit": "Required to use assertions and run tests (^10.5.35|^11.3.6|^12.0.1).", "phpunit/phpunit": "Required to use assertions and run tests (^10.5.35|^11.5.3|^12.0.1).",
"predis/predis": "Required to use the predis connector (^2.3).", "predis/predis": "Required to use the predis connector (^2.3|^3.0).",
"psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).",
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).",
"resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).",
"symfony/cache": "Required to PSR-6 cache bridge (^7.0).", "symfony/cache": "Required to PSR-6 cache bridge (^7.2).",
"symfony/filesystem": "Required to enable support for relative symbolic links (^7.0).", "symfony/filesystem": "Required to enable support for relative symbolic links (^7.2).",
"symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.0).", "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.2).",
"symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.0).", "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.2).",
"symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.0).", "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.2).",
"symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.0)." "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.2)."
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "11.x-dev" "dev-master": "12.x-dev"
} }
}, },
"autoload": { "autoload": {
@ -1410,7 +1410,7 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "source": "https://github.com/laravel/framework"
}, },
"time": "2025-05-20T15:15:58+00:00" "time": "2025-05-27T15:49:44+00:00"
}, },
{ {
"name": "laravel/prompts", "name": "laravel/prompts",
@ -3263,20 +3263,20 @@
}, },
{ {
"name": "ramsey/uuid", "name": "ramsey/uuid",
"version": "4.7.6", "version": "4.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/ramsey/uuid.git", "url": "https://github.com/ramsey/uuid.git",
"reference": "91039bc1faa45ba123c4328958e620d382ec7088" "reference": "6700833915c00f890615fbcb653faed513836836"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", "url": "https://api.github.com/repos/ramsey/uuid/zipball/6700833915c00f890615fbcb653faed513836836",
"reference": "91039bc1faa45ba123c4328958e620d382ec7088", "reference": "6700833915c00f890615fbcb653faed513836836",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13",
"ext-json": "*", "ext-json": "*",
"php": "^8.0", "php": "^8.0",
"ramsey/collection": "^1.2 || ^2.0" "ramsey/collection": "^1.2 || ^2.0"
@ -3285,26 +3285,23 @@
"rhumsaa/uuid": "self.version" "rhumsaa/uuid": "self.version"
}, },
"require-dev": { "require-dev": {
"captainhook/captainhook": "^5.10", "captainhook/captainhook": "^5.25",
"captainhook/plugin-composer": "^5.3", "captainhook/plugin-composer": "^5.3",
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "dealerdirect/phpcodesniffer-composer-installer": "^1.0",
"doctrine/annotations": "^1.8", "ergebnis/composer-normalize": "^2.47",
"ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.6",
"mockery/mockery": "^1.3",
"paragonie/random-lib": "^2", "paragonie/random-lib": "^2",
"php-mock/php-mock": "^2.2", "php-mock/php-mock": "^2.6",
"php-mock/php-mock-mockery": "^1.3", "php-mock/php-mock-mockery": "^1.5",
"php-parallel-lint/php-parallel-lint": "^1.1", "php-parallel-lint/php-parallel-lint": "^1.4.0",
"phpbench/phpbench": "^1.0", "phpbench/phpbench": "^1.2.14",
"phpstan/extension-installer": "^1.1", "phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "^1.8", "phpstan/phpstan": "^2.1",
"phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-mockery": "^2.0",
"phpstan/phpstan-phpunit": "^1.1", "phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^8.5 || ^9", "phpunit/phpunit": "^9.6",
"ramsey/composer-repl": "^1.4", "slevomat/coding-standard": "^8.18",
"slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.13"
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^4.9"
}, },
"suggest": { "suggest": {
"ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.",
@ -3339,23 +3336,13 @@
], ],
"support": { "support": {
"issues": "https://github.com/ramsey/uuid/issues", "issues": "https://github.com/ramsey/uuid/issues",
"source": "https://github.com/ramsey/uuid/tree/4.7.6" "source": "https://github.com/ramsey/uuid/tree/4.8.0"
}, },
"funding": [ "time": "2025-06-01T02:32:15+00:00"
{
"url": "https://github.com/ramsey",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/ramsey/uuid",
"type": "tidelift"
}
],
"time": "2024-04-27T21:32:50+00:00"
}, },
{ {
"name": "symfony/clock", "name": "symfony/clock",
"version": "v7.2.0", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/clock.git", "url": "https://github.com/symfony/clock.git",
@ -3409,7 +3396,7 @@
"time" "time"
], ],
"support": { "support": {
"source": "https://github.com/symfony/clock/tree/v7.2.0" "source": "https://github.com/symfony/clock/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -3429,23 +3416,24 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v7.2.6", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218" "reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/0e2e3f38c192e93e622e41ec37f4ca70cfedf218", "url": "https://api.github.com/repos/symfony/console/zipball/66c1440edf6f339fd82ed6c7caa76cb006211b44",
"reference": "0e2e3f38c192e93e622e41ec37f4ca70cfedf218", "reference": "66c1440edf6f339fd82ed6c7caa76cb006211b44",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=8.2", "php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/service-contracts": "^2.5|^3", "symfony/service-contracts": "^2.5|^3",
"symfony/string": "^6.4|^7.0" "symfony/string": "^7.2"
}, },
"conflict": { "conflict": {
"symfony/dependency-injection": "<6.4", "symfony/dependency-injection": "<6.4",
@ -3502,7 +3490,7 @@
"terminal" "terminal"
], ],
"support": { "support": {
"source": "https://github.com/symfony/console/tree/v7.2.6" "source": "https://github.com/symfony/console/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -3518,11 +3506,11 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-04-07T19:09:28+00:00" "time": "2025-05-24T10:34:04+00:00"
}, },
{ {
"name": "symfony/css-selector", "name": "symfony/css-selector",
"version": "v7.2.0", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/css-selector.git", "url": "https://github.com/symfony/css-selector.git",
@ -3567,7 +3555,7 @@
"description": "Converts CSS selectors to XPath expressions", "description": "Converts CSS selectors to XPath expressions",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/css-selector/tree/v7.2.0" "source": "https://github.com/symfony/css-selector/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -3587,16 +3575,16 @@
}, },
{ {
"name": "symfony/deprecation-contracts", "name": "symfony/deprecation-contracts",
"version": "v3.5.1", "version": "v3.6.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git", "url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62",
"reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3609,7 +3597,7 @@
"name": "symfony/contracts" "name": "symfony/contracts"
}, },
"branch-alias": { "branch-alias": {
"dev-main": "3.5-dev" "dev-main": "3.6-dev"
} }
}, },
"autoload": { "autoload": {
@ -3634,7 +3622,7 @@
"description": "A generic function and convention to trigger deprecation notices", "description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0"
}, },
"funding": [ "funding": [
{ {
@ -3650,20 +3638,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-25T14:20:29+00:00" "time": "2024-09-25T14:21:43+00:00"
}, },
{ {
"name": "symfony/error-handler", "name": "symfony/error-handler",
"version": "v7.2.5", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/error-handler.git", "url": "https://github.com/symfony/error-handler.git",
"reference": "102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b" "reference": "cf68d225bc43629de4ff54778029aee6dc191b83"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/error-handler/zipball/102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b", "url": "https://api.github.com/repos/symfony/error-handler/zipball/cf68d225bc43629de4ff54778029aee6dc191b83",
"reference": "102be5e6a8e4f4f3eb3149bcbfa33a80d1ee374b", "reference": "cf68d225bc43629de4ff54778029aee6dc191b83",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3676,9 +3664,11 @@
"symfony/http-kernel": "<6.4" "symfony/http-kernel": "<6.4"
}, },
"require-dev": { "require-dev": {
"symfony/console": "^6.4|^7.0",
"symfony/deprecation-contracts": "^2.5|^3", "symfony/deprecation-contracts": "^2.5|^3",
"symfony/http-kernel": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0",
"symfony/serializer": "^6.4|^7.0" "symfony/serializer": "^6.4|^7.0",
"symfony/webpack-encore-bundle": "^1.0|^2.0"
}, },
"bin": [ "bin": [
"Resources/bin/patch-type-declarations" "Resources/bin/patch-type-declarations"
@ -3709,7 +3699,7 @@
"description": "Provides tools to manage errors and ease debugging PHP code", "description": "Provides tools to manage errors and ease debugging PHP code",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/error-handler/tree/v7.2.5" "source": "https://github.com/symfony/error-handler/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -3725,20 +3715,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-03-03T07:12:39+00:00" "time": "2025-05-29T07:19:49+00:00"
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v7.2.0", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" "reference": "497f73ac996a598c92409b44ac43b6690c4f666d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d",
"reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", "reference": "497f73ac996a598c92409b44ac43b6690c4f666d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3789,7 +3779,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -3805,20 +3795,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-25T14:21:43+00:00" "time": "2025-04-22T09:11:45+00:00"
}, },
{ {
"name": "symfony/event-dispatcher-contracts", "name": "symfony/event-dispatcher-contracts",
"version": "v3.5.1", "version": "v3.6.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher-contracts.git", "url": "https://github.com/symfony/event-dispatcher-contracts.git",
"reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" "reference": "59eb412e93815df44f05f342958efa9f46b1e586"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586",
"reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", "reference": "59eb412e93815df44f05f342958efa9f46b1e586",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3832,7 +3822,7 @@
"name": "symfony/contracts" "name": "symfony/contracts"
}, },
"branch-alias": { "branch-alias": {
"dev-main": "3.5-dev" "dev-main": "3.6-dev"
} }
}, },
"autoload": { "autoload": {
@ -3865,7 +3855,7 @@
"standards" "standards"
], ],
"support": { "support": {
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0"
}, },
"funding": [ "funding": [
{ {
@ -3881,20 +3871,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-25T14:20:29+00:00" "time": "2024-09-25T14:21:43+00:00"
}, },
{ {
"name": "symfony/finder", "name": "symfony/finder",
"version": "v7.2.2", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/finder.git", "url": "https://github.com/symfony/finder.git",
"reference": "87a71856f2f56e4100373e92529eed3171695cfb" "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", "url": "https://api.github.com/repos/symfony/finder/zipball/ec2344cf77a48253bbca6939aa3d2477773ea63d",
"reference": "87a71856f2f56e4100373e92529eed3171695cfb", "reference": "ec2344cf77a48253bbca6939aa3d2477773ea63d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3929,7 +3919,7 @@
"description": "Finds files and directories via an intuitive fluent interface", "description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/finder/tree/v7.2.2" "source": "https://github.com/symfony/finder/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -3945,20 +3935,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-12-30T19:00:17+00:00" "time": "2024-12-30T19:00:26+00:00"
}, },
{ {
"name": "symfony/http-foundation", "name": "symfony/http-foundation",
"version": "v7.2.6", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-foundation.git", "url": "https://github.com/symfony/http-foundation.git",
"reference": "6023ec7607254c87c5e69fb3558255aca440d72b" "reference": "4236baf01609667d53b20371486228231eb135fd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/6023ec7607254c87c5e69fb3558255aca440d72b", "url": "https://api.github.com/repos/symfony/http-foundation/zipball/4236baf01609667d53b20371486228231eb135fd",
"reference": "6023ec7607254c87c5e69fb3558255aca440d72b", "reference": "4236baf01609667d53b20371486228231eb135fd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3975,6 +3965,7 @@
"doctrine/dbal": "^3.6|^4", "doctrine/dbal": "^3.6|^4",
"predis/predis": "^1.1|^2.0", "predis/predis": "^1.1|^2.0",
"symfony/cache": "^6.4.12|^7.1.5", "symfony/cache": "^6.4.12|^7.1.5",
"symfony/clock": "^6.4|^7.0",
"symfony/dependency-injection": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0",
"symfony/expression-language": "^6.4|^7.0", "symfony/expression-language": "^6.4|^7.0",
"symfony/http-kernel": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0",
@ -4007,7 +3998,7 @@
"description": "Defines an object-oriented layer for the HTTP specification", "description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/http-foundation/tree/v7.2.6" "source": "https://github.com/symfony/http-foundation/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -4023,20 +4014,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-04-09T08:14:01+00:00" "time": "2025-05-12T14:48:23+00:00"
}, },
{ {
"name": "symfony/http-kernel", "name": "symfony/http-kernel",
"version": "v7.2.6", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-kernel.git", "url": "https://github.com/symfony/http-kernel.git",
"reference": "f9dec01e6094a063e738f8945ef69c0cfcf792ec" "reference": "ac7b8e163e8c83dce3abcc055a502d4486051a9f"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/f9dec01e6094a063e738f8945ef69c0cfcf792ec", "url": "https://api.github.com/repos/symfony/http-kernel/zipball/ac7b8e163e8c83dce3abcc055a502d4486051a9f",
"reference": "f9dec01e6094a063e738f8945ef69c0cfcf792ec", "reference": "ac7b8e163e8c83dce3abcc055a502d4486051a9f",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4044,8 +4035,8 @@
"psr/log": "^1|^2|^3", "psr/log": "^1|^2|^3",
"symfony/deprecation-contracts": "^2.5|^3", "symfony/deprecation-contracts": "^2.5|^3",
"symfony/error-handler": "^6.4|^7.0", "symfony/error-handler": "^6.4|^7.0",
"symfony/event-dispatcher": "^6.4|^7.0", "symfony/event-dispatcher": "^7.3",
"symfony/http-foundation": "^6.4|^7.0", "symfony/http-foundation": "^7.3",
"symfony/polyfill-ctype": "^1.8" "symfony/polyfill-ctype": "^1.8"
}, },
"conflict": { "conflict": {
@ -4121,7 +4112,7 @@
"description": "Provides a structured process for converting a Request into a Response", "description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/http-kernel/tree/v7.2.6" "source": "https://github.com/symfony/http-kernel/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -4137,20 +4128,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-05-02T09:04:03+00:00" "time": "2025-05-29T07:47:32+00:00"
}, },
{ {
"name": "symfony/mailer", "name": "symfony/mailer",
"version": "v7.2.6", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/mailer.git", "url": "https://github.com/symfony/mailer.git",
"reference": "998692469d6e698c6eadc7ef37a6530a9eabb356" "reference": "0f375bbbde96ae8c78e4aa3e63aabd486e33364c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/mailer/zipball/998692469d6e698c6eadc7ef37a6530a9eabb356", "url": "https://api.github.com/repos/symfony/mailer/zipball/0f375bbbde96ae8c78e4aa3e63aabd486e33364c",
"reference": "998692469d6e698c6eadc7ef37a6530a9eabb356", "reference": "0f375bbbde96ae8c78e4aa3e63aabd486e33364c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4201,7 +4192,7 @@
"description": "Helps sending emails", "description": "Helps sending emails",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/mailer/tree/v7.2.6" "source": "https://github.com/symfony/mailer/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -4217,20 +4208,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-04-04T09:50:51+00:00" "time": "2025-04-04T09:51:09+00:00"
}, },
{ {
"name": "symfony/mime", "name": "symfony/mime",
"version": "v7.2.6", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/mime.git", "url": "https://github.com/symfony/mime.git",
"reference": "706e65c72d402539a072d0d6ad105fff6c161ef1" "reference": "0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/706e65c72d402539a072d0d6ad105fff6c161ef1", "url": "https://api.github.com/repos/symfony/mime/zipball/0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9",
"reference": "706e65c72d402539a072d0d6ad105fff6c161ef1", "reference": "0e7b19b2f399c31df0cdbe5d8cbf53f02f6cfcd9",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4285,7 +4276,7 @@
"mime-type" "mime-type"
], ],
"support": { "support": {
"source": "https://github.com/symfony/mime/tree/v7.2.6" "source": "https://github.com/symfony/mime/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -4301,7 +4292,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-04-27T13:34:41+00:00" "time": "2025-02-19T08:51:26+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
@ -4942,16 +4933,16 @@
}, },
{ {
"name": "symfony/process", "name": "symfony/process",
"version": "v7.2.5", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/process.git", "url": "https://github.com/symfony/process.git",
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d" "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d", "url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
"reference": "87b7c93e57df9d8e39a093d32587702380ff045d", "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4983,7 +4974,7 @@
"description": "Executes commands in sub-processes", "description": "Executes commands in sub-processes",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/process/tree/v7.2.5" "source": "https://github.com/symfony/process/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -4999,20 +4990,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-03-13T12:21:46+00:00" "time": "2025-04-17T09:11:12+00:00"
}, },
{ {
"name": "symfony/routing", "name": "symfony/routing",
"version": "v7.2.3", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/routing.git", "url": "https://github.com/symfony/routing.git",
"reference": "ee9a67edc6baa33e5fae662f94f91fd262930996" "reference": "8e213820c5fea844ecea29203d2a308019007c15"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/ee9a67edc6baa33e5fae662f94f91fd262930996", "url": "https://api.github.com/repos/symfony/routing/zipball/8e213820c5fea844ecea29203d2a308019007c15",
"reference": "ee9a67edc6baa33e5fae662f94f91fd262930996", "reference": "8e213820c5fea844ecea29203d2a308019007c15",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5064,7 +5055,7 @@
"url" "url"
], ],
"support": { "support": {
"source": "https://github.com/symfony/routing/tree/v7.2.3" "source": "https://github.com/symfony/routing/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -5080,20 +5071,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-01-17T10:56:55+00:00" "time": "2025-05-24T20:43:28+00:00"
}, },
{ {
"name": "symfony/service-contracts", "name": "symfony/service-contracts",
"version": "v3.5.1", "version": "v3.6.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/service-contracts.git", "url": "https://github.com/symfony/service-contracts.git",
"reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
"reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5111,7 +5102,7 @@
"name": "symfony/contracts" "name": "symfony/contracts"
}, },
"branch-alias": { "branch-alias": {
"dev-main": "3.5-dev" "dev-main": "3.6-dev"
} }
}, },
"autoload": { "autoload": {
@ -5147,7 +5138,7 @@
"standards" "standards"
], ],
"support": { "support": {
"source": "https://github.com/symfony/service-contracts/tree/v3.5.1" "source": "https://github.com/symfony/service-contracts/tree/v3.6.0"
}, },
"funding": [ "funding": [
{ {
@ -5163,20 +5154,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-25T14:20:29+00:00" "time": "2025-04-25T09:37:31+00:00"
}, },
{ {
"name": "symfony/string", "name": "symfony/string",
"version": "v7.2.6", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/string.git", "url": "https://github.com/symfony/string.git",
"reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931" "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/string/zipball/a214fe7d62bd4df2a76447c67c6b26e1d5e74931", "url": "https://api.github.com/repos/symfony/string/zipball/f3570b8c61ca887a9e2938e85cb6458515d2b125",
"reference": "a214fe7d62bd4df2a76447c67c6b26e1d5e74931", "reference": "f3570b8c61ca887a9e2938e85cb6458515d2b125",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5234,7 +5225,7 @@
"utf8" "utf8"
], ],
"support": { "support": {
"source": "https://github.com/symfony/string/tree/v7.2.6" "source": "https://github.com/symfony/string/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -5250,20 +5241,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-04-20T20:18:16+00:00" "time": "2025-04-20T20:19:01+00:00"
}, },
{ {
"name": "symfony/translation", "name": "symfony/translation",
"version": "v7.2.6", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation.git", "url": "https://github.com/symfony/translation.git",
"reference": "e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6" "reference": "4aba29076a29a3aa667e09b791e5f868973a8667"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6", "url": "https://api.github.com/repos/symfony/translation/zipball/4aba29076a29a3aa667e09b791e5f868973a8667",
"reference": "e7fd8e2a4239b79a0fd9fb1fef3e0e7f969c6dc6", "reference": "4aba29076a29a3aa667e09b791e5f868973a8667",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5273,6 +5264,7 @@
"symfony/translation-contracts": "^2.5|^3.0" "symfony/translation-contracts": "^2.5|^3.0"
}, },
"conflict": { "conflict": {
"nikic/php-parser": "<5.0",
"symfony/config": "<6.4", "symfony/config": "<6.4",
"symfony/console": "<6.4", "symfony/console": "<6.4",
"symfony/dependency-injection": "<6.4", "symfony/dependency-injection": "<6.4",
@ -5286,7 +5278,7 @@
"symfony/translation-implementation": "2.3|3.0" "symfony/translation-implementation": "2.3|3.0"
}, },
"require-dev": { "require-dev": {
"nikic/php-parser": "^4.18|^5.0", "nikic/php-parser": "^5.0",
"psr/log": "^1|^2|^3", "psr/log": "^1|^2|^3",
"symfony/config": "^6.4|^7.0", "symfony/config": "^6.4|^7.0",
"symfony/console": "^6.4|^7.0", "symfony/console": "^6.4|^7.0",
@ -5329,7 +5321,7 @@
"description": "Provides tools to internationalize your application", "description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/translation/tree/v7.2.6" "source": "https://github.com/symfony/translation/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -5345,20 +5337,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-04-07T19:09:28+00:00" "time": "2025-05-29T07:19:49+00:00"
}, },
{ {
"name": "symfony/translation-contracts", "name": "symfony/translation-contracts",
"version": "v3.5.1", "version": "v3.6.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation-contracts.git", "url": "https://github.com/symfony/translation-contracts.git",
"reference": "4667ff3bd513750603a09c8dedbea942487fb07c" "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/df210c7a2573f1913b2d17cc95f90f53a73d8f7d",
"reference": "4667ff3bd513750603a09c8dedbea942487fb07c", "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5371,7 +5363,7 @@
"name": "symfony/contracts" "name": "symfony/contracts"
}, },
"branch-alias": { "branch-alias": {
"dev-main": "3.5-dev" "dev-main": "3.6-dev"
} }
}, },
"autoload": { "autoload": {
@ -5407,7 +5399,7 @@
"standards" "standards"
], ],
"support": { "support": {
"source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" "source": "https://github.com/symfony/translation-contracts/tree/v3.6.0"
}, },
"funding": [ "funding": [
{ {
@ -5423,20 +5415,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-25T14:20:29+00:00" "time": "2024-09-27T08:32:26+00:00"
}, },
{ {
"name": "symfony/uid", "name": "symfony/uid",
"version": "v7.2.0", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/uid.git", "url": "https://github.com/symfony/uid.git",
"reference": "2d294d0c48df244c71c105a169d0190bfb080426" "reference": "7beeb2b885cd584cd01e126c5777206ae4c3c6a3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/uid/zipball/2d294d0c48df244c71c105a169d0190bfb080426", "url": "https://api.github.com/repos/symfony/uid/zipball/7beeb2b885cd584cd01e126c5777206ae4c3c6a3",
"reference": "2d294d0c48df244c71c105a169d0190bfb080426", "reference": "7beeb2b885cd584cd01e126c5777206ae4c3c6a3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5481,7 +5473,7 @@
"uuid" "uuid"
], ],
"support": { "support": {
"source": "https://github.com/symfony/uid/tree/v7.2.0" "source": "https://github.com/symfony/uid/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -5497,24 +5489,25 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2024-09-25T14:21:43+00:00" "time": "2025-05-24T14:28:13+00:00"
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v7.2.6", "version": "v7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "9c46038cd4ed68952166cf7001b54eb539184ccb" "reference": "548f6760c54197b1084e1e5c71f6d9d523f2f78e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/9c46038cd4ed68952166cf7001b54eb539184ccb", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/548f6760c54197b1084e1e5c71f6d9d523f2f78e",
"reference": "9c46038cd4ed68952166cf7001b54eb539184ccb", "reference": "548f6760c54197b1084e1e5c71f6d9d523f2f78e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=8.2", "php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0" "symfony/polyfill-mbstring": "~1.0"
}, },
"conflict": { "conflict": {
@ -5564,7 +5557,7 @@
"dump" "dump"
], ],
"support": { "support": {
"source": "https://github.com/symfony/var-dumper/tree/v7.2.6" "source": "https://github.com/symfony/var-dumper/tree/v7.3.0"
}, },
"funding": [ "funding": [
{ {
@ -5580,7 +5573,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-04-09T08:14:01+00:00" "time": "2025-04-27T18:39:23+00:00"
}, },
{ {
"name": "tijsverkoyen/css-to-inline-styles", "name": "tijsverkoyen/css-to-inline-styles",
@ -6270,16 +6263,16 @@
}, },
{ {
"name": "nikic/php-parser", "name": "nikic/php-parser",
"version": "v5.4.0", "version": "v5.5.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nikic/PHP-Parser.git", "url": "https://github.com/nikic/PHP-Parser.git",
"reference": "447a020a1f875a434d62f2a401f53b82a396e494" "reference": "ae59794362fe85e051a58ad36b289443f57be7a9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ae59794362fe85e051a58ad36b289443f57be7a9",
"reference": "447a020a1f875a434d62f2a401f53b82a396e494", "reference": "ae59794362fe85e051a58ad36b289443f57be7a9",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -6322,9 +6315,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/nikic/PHP-Parser/issues", "issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" "source": "https://github.com/nikic/PHP-Parser/tree/v5.5.0"
}, },
"time": "2024-12-30T11:07:19+00:00" "time": "2025-05-31T08:24:38+00:00"
}, },
{ {
"name": "nunomaduro/collision", "name": "nunomaduro/collision",

1082
package-lock.json generated

File diff suppressed because it is too large Load Diff

20
public/css/custom.css vendored
View File

@ -1,23 +1,24 @@
/** ensure our userpassword has select is next to the password input */ /** ensure our userpassword has select is next to the password input */
attribute#userPassword .select2-container--bootstrap-5 .select2-selection { attribute#userpassword .select2-container--bootstrap-5 .select2-selection {
font-size: inherit; font-size: inherit;
width: 9em; width: 9em;
border: var(--bs-gray-500) 1px solid; border: var(--bs-gray-500) 1px solid;
background-color: #f0f0f0; background-color: #f0f0f0;
} }
.input-group:first-child .select2-container--bootstrap-5 .select2-selection { /* render the structural inside the input box */
border-bottom-right-radius: unset; attribute#objectclass .input-group-end:not(input.form-control) {
border-top-right-radius: unset;
}
attribute#objectClass .input-group-end:not(input.form-control) {
position: absolute; position: absolute;
right: 1em; right: 1em;
top: 0.5em; top: 0.5em;
z-index: 5; z-index: 5;
} }
.input-group:first-child .select2-container--bootstrap-5 .select2-selection {
border-bottom-right-radius: unset;
border-top-right-radius: unset;
}
input.form-control.input-group-end { input.form-control.input-group-end {
border-bottom-right-radius: 4px !important; border-bottom-right-radius: 4px !important;
border-top-right-radius: 4px !important; border-top-right-radius: 4px !important;
@ -83,3 +84,8 @@ input.form-control.input-group-end {
.page-title-wrapper .page-title-items .page-title-status .alert { .page-title-wrapper .page-title-items .page-title-status .alert {
font-size: 0.80em; font-size: 0.80em;
} }
/* Square UL items */
ul.square {
list-style-type: square;
}

View File

@ -90,6 +90,14 @@
font-size: 1.3rem !important; font-size: 1.3rem !important;
} }
.font-size-xs {
font-size: .6rem !important;
}
.font-size-sm {
font-size: .8rem !important;
}
.font-size-md { .font-size-md {
font-size: .9rem !important; font-size: .9rem !important;
} }

View File

@ -38,7 +38,7 @@
<span></span> <span></span>
<div id="searching" class="d-none"><i class="fas fa-fw fa-spinner fa-pulse text-light"></i></div> <div id="searching" class="d-none"><i class="fas fa-fw fa-spinner fa-pulse text-light"></i></div>
</button> </button>
<div id="search_results" style="height: 300px; overflow: scroll"></div> <div id="search_results" class="overflow-scroll" style="height: 300px;"></div>
</div> </div>
<button class="btn-close"></button> <button class="btn-close"></button>
</div> </div>
@ -139,7 +139,7 @@
<div class="btn-group"> <div class="btn-group">
<a data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="p-0 btn"> <a data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false" class="p-0 btn">
<i class="fas fa-angle-down ms-2 opacity-8"></i> <i class="fas fa-angle-down ms-2 opacity-8"></i>
<img width="35" height="35" class="rounded-circle" src="{{ url('user/image') }}" alt="" style="background-color: #eee;padding: 2px;"> <img width="35" height="35" class="rounded-circle p-1 bg-light" src="{{ url('user/image') }}" alt="">
</a> </a>
<div tabindex="-1" role="menu" aria-hidden="true" class="dropdown-menu dropdown-menu-right"> <div tabindex="-1" role="menu" aria-hidden="true" class="dropdown-menu dropdown-menu-right">
@if ($user->exists) @if ($user->exists)

View File

@ -1,4 +1,4 @@
<div class="alert alert-danger p-0" style="font-size: .80em;"> <div class="alert alert-danger font-size-sm p-0">
<table class="table table-borderless table-danger p-0 m-0"> <table class="table table-borderless table-danger p-0 m-0">
<tr> <tr>
<td class="align-top" style="width: 5%;"><i class="fas fa-fw fa-2x fa-exclamation-triangle"></i></td> <td class="align-top" style="width: 5%;"><i class="fas fa-fw fa-2x fa-exclamation-triangle"></i></td>

View File

@ -1,23 +1,53 @@
@use(App\Ldap\Entry)
<div class="row pb-3"> <div class="row pb-3">
<div class="col-12 col-sm-1 col-md-2"></div> <div class="col-12 offset-lg-1 col-lg-10">
<div class="col-12 col-sm-10 col-md-8">
<div class="row"> <div class="row">
<div class="col-12 bg-light text-dark p-2"> <div class="col-12 bg-light text-dark p-2 rounded-2">
<strong><abbr title="{{ $o->description }}">{{ $o->name }}</abbr></strong> <span class="d-flex justify-content-between">
<!-- Attribute Hints --> <span style="width: 20em;">
@if($updated) <strong class="align-middle"><abbr title="{{ $o->description }}">{{ $o->name }}</abbr></strong>
<span class="float-end small text-success ms-2" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip-success" title="@lang('Updated')"><i class="fas fa-fw fa-marker"></i> </span> @if($o->hints->count())
@endif <sup>
<span class="float-end small"> [
@foreach($o->hints as $name => $description) @foreach($o->hints as $name => $description)
@if ($loop->index),@endif @if ($loop->index),@endif
<abbr title="{{ $description }}">{{ $name }}</abbr> <abbr title="{{ $description }}">{{ $name }}</abbr>
@endforeach @endforeach
]
</sup>
@endif
<!-- Attribute Hints -->
@if($updated)
<span class=" small text-success ms-2" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip-success" title="@lang('Updated')"><i class="fas fa-fw fa-marker"></i> </span>
@endif
</span>
<div role="group" class="btn-group-sm nav btn-group">
@if((! $o->no_attr_tags) && ($has_default=$o->langtags->contains(Entry::TAG_NOTAG)))
<span data-bs-toggle="tab" href="#langtag-{{ $o->name_lc }}-{{ Entry::TAG_NOTAG }}" @class(['btn','btn-outline-light','border-dark-subtle','active','addable d-none'=>$o->langtags->count() === 1])>
<i class="fas fa-fw fa-border-none" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip" aria-label="No Lang Tag" data-bs-original-title="No Lang Tag"></i>
</span>
@endif
@if((! $o->no_attr_tags) && (! $o->is_rdn))
<span data-bs-toggle="tab" href="#langtag-{{ $o->name_lc }}-+" class="bg-primary-subtle btn btn-outline-primary border-primary addable d-none">
<i class="fas fa-fw fa-plus text-dark" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip" aria-label="Add Lang Tag" data-bs-original-title="Add Lang Tag"></i>
</span>
@endif
@foreach(($langtags=$o->langtags->filter(fn($item)=>$item !== Entry::TAG_NOTAG)) as $langtag)
<span data-bs-toggle="tab" href="#langtag-{{ $o->name_lc }}-{{ $langtag }}" @class(['btn','btn-outline-light','border-dark-subtle','active'=>(! isset($has_default)) || (! $has_default) ])>
<span class="f16" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip" aria-label="{{ $langtag }}" data-bs-original-title="{{ ($x=preg_replace('/'.Entry::LANG_TAG_PREFIX.'/','',$langtag)) }}"><i class="flag {{ $x }}"></i></span>
</span>
@endforeach
</div>
</span> </span>
</div> </div>
</div> </div>
<x-attribute :o="$o" :edit="$edit" :new="$new" :langtag="$langtag" :updated="$updated"/> <x-attribute :o="$o" :edit="$edit" :new="$new" :updated="$updated"/>
</div> </div>
</div> </div>

View File

@ -1,6 +1,9 @@
<!-- $o=Attribute::class --> <!-- $o=Attribute::class -->
<x-attribute.layout :edit="$edit=($edit ?? FALSE)" :new="$new=($new ?? FALSE)" :o="$o"> <x-attribute.layout :edit="$edit=($edit ?? FALSE)" :new="$new=($new ?? FALSE)" :o="$o">
<div class="col-12"> <div class="col-12">
<div class="tab-content">
@foreach($o->langtags as $langtag)
<span @class(['tab-pane','active'=>$loop->index === 0]) id="langtag-{{ $o->name_lc }}-{{ $langtag }}" role="tabpanel">
@foreach(Arr::get(old($o->name_lc,[$langtag=>$new ? [NULL] : $o->tagValues($langtag)]),$langtag,[]) as $key => $value) @foreach(Arr::get(old($o->name_lc,[$langtag=>$new ? [NULL] : $o->tagValues($langtag)]),$langtag,[]) as $key => $value)
@if($edit && (! $o->is_rdn)) @if($edit && (! $o->is_rdn))
<div class="input-group has-validation"> <div class="input-group has-validation">
@ -17,5 +20,17 @@
<input type="text" @class(['form-control','mb-1','bg-success-subtle'=>$updated]) value="{{ $value }}" disabled> <input type="text" @class(['form-control','mb-1','bg-success-subtle'=>$updated]) value="{{ $value }}" disabled>
@endif @endif
@endforeach @endforeach
</span>
@endforeach
@if($edit && (! $o->is_rdn))
<span @class(['tab-pane']) id="langtag-{{ $o->name_lc }}-+" role="tabpanel">
<span class="d-flex font-size-sm alert alert-warning p-2">
It is not possible to create new language tags at the moment. This functionality should come soon.<br>
You can create them with an LDIF import though.
</span>
</span>
@endif
</div>
</div> </div>
</x-attribute.layout> </x-attribute.layout>

View File

@ -1,3 +1,5 @@
@use(App\Ldap\Entry)
<!-- @todo We are not handling redirect backs yet with updated photos --> <!-- @todo We are not handling redirect backs yet with updated photos -->
<!-- $o=Binary\JpegPhoto::class --> <!-- $o=Binary\JpegPhoto::class -->
<x-attribute.layout :edit="$edit" :new="$new" :o="$o"> <x-attribute.layout :edit="$edit" :new="$new" :o="$o">
@ -8,8 +10,8 @@
@case('image/jpeg') @case('image/jpeg')
@default @default
<td> <td>
<input type="hidden" name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ md5($value) }}"> <input type="hidden" name="{{ $o->name_lc }}[{{ Entry::TAG_NOTAG }}][]" value="{{ md5($value) }}">
<img alt="{{ $o->dn }}" @class(['border','rounded','p-2','m-0','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'bg-success-subtle'=>$updated]) src="data:{{ $x }};base64, {{ base64_encode($value) }}" /> <img alt="{{ $o->dn }}" @class(['border','rounded','p-2','m-0','is-invalid'=>($e=$errors->get($o->name_lc.'.'.Entry::TAG_NOTAG.'.'.$loop->index)),'bg-success-subtle'=>$updated]) src="data:{{ $x }};base64, {{ base64_encode($value) }}" />
@if($edit) @if($edit)
<br> <br>

View File

@ -1,5 +1,6 @@
<!-- $o=KrbPrincipleKey::class --> <!-- $o=KrbPrincipleKey::class -->
<x-attribute.layout :edit="$edit" :new="$new" :o="$o"> <x-attribute.layout :edit="$edit" :new="$new" :o="$o">
@foreach($o->langtags as $langtag)
@foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value) @foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value)
@if($edit) @if($edit)
<div class="input-group has-validation mb-3"> <div class="input-group has-validation mb-3">
@ -15,4 +16,5 @@
{{ $o->render_item_old($langtag.'.'.$key) }} {{ $o->render_item_old($langtag.'.'.$key) }}
@endif @endif
@endforeach @endforeach
@endforeach
</x-attribute.layout> </x-attribute.layout>

View File

@ -1,5 +1,6 @@
<!-- $o=KrbTicketFlags::class --> <!-- $o=KrbTicketFlags::class -->
<x-attribute.layout :edit="$edit" :new="$new" :o="$o"> <x-attribute.layout :edit="$edit" :new="$new" :o="$o">
@foreach($o->langtags as $langtag)
@foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value) @foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value)
@if($edit) @if($edit)
<div id="32"></div> <div id="32"></div>
@ -18,6 +19,7 @@
{{ $o->render_item_old($langtag.'.'.$key) }} {{ $o->render_item_old($langtag.'.'.$key) }}
@endif @endif
@endforeach @endforeach
@endforeach
</x-attribute.layout> </x-attribute.layout>
@section($o->name_lc.'-scripts') @section($o->name_lc.'-scripts')
@ -48,7 +50,7 @@
$('div#32').append(binary(31,16)); $('div#32').append(binary(31,16));
$('div#16').append(binary(15,0)); $('div#16').append(binary(15,0));
$('attribute#krbTicketFlags').find('i') $('attribute#krbticketflags').find('i')
.on('click',function() { .on('click',function() {
var item = $(this); var item = $(this);
if ($('form#dn-edit').attr('readonly')) if ($('form#dn-edit').attr('readonly'))
@ -91,7 +93,7 @@
item.data('old',null); item.data('old',null);
} }
$('attribute#krbTicketFlags').find('input').val(value); $('attribute#krbticketflags').find('input').val(value);
}); });
} }
@ -102,7 +104,7 @@
} else { } else {
krbticketflags(); krbticketflags();
$('attribute#krbTicketFlags').find('i') $('attribute#krbticketflags').find('i')
.tooltip(); .tooltip();
} }
</script> </script>

View File

@ -1,7 +1,7 @@
<div class="row pt-2"> <div class="row pt-2">
<div @class(['col-1','d-none'=>(! $edit) && (! ($detail ?? FALSE))])></div> <div @class(['col-1','d-none'=>(! $edit) && (! ($detail ?? FALSE))])></div>
<div class="col-10"> <div class="col-10">
<attribute id="{{ $o->name }}"> <attribute id="{{ $o->name_lc }}">
{{ $slot }} {{ $slot }}
</attribute> </attribute>

View File

@ -1,5 +1,6 @@
<!-- $o=Attribute/ObjectClass::class --> <!-- $o=Attribute/ObjectClass::class -->
<x-attribute.layout :edit="$edit" :new="$new" :o="$o"> <x-attribute.layout :edit="$edit" :new="$new" :o="$o">
@foreach($o->langtags as $langtag)
@foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value) @foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value)
@if($edit) @if($edit)
<x-attribute.widget.objectclass :o="$o" :edit="$edit" :new="$new" :langtag="$langtag" :updated="$updated" :value="$value" :loop="$loop" /> <x-attribute.widget.objectclass :o="$o" :edit="$edit" :new="$new" :langtag="$langtag" :updated="$updated" :value="$value" :loop="$loop" />
@ -12,4 +13,5 @@
<br> <br>
@endif @endif
@endforeach @endforeach
@endforeach
</x-attribute.layout> </x-attribute.layout>

View File

@ -1,5 +1,6 @@
<!-- $o=Password::class --> <!-- $o=Password::class -->
<x-attribute.layout :edit="$edit" :new="$new" :o="$o"> <x-attribute.layout :edit="$edit" :new="$new" :o="$o">
@foreach($o->langtags as $langtag)
@foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value) @foreach(($o->tagValues($langtag)->count() ? $o->tagValues($langtag) : [$langtag => NULL]) as $key => $value)
@if($edit) @if($edit)
<div class="input-group has-validation mb-3"> <div class="input-group has-validation mb-3">
@ -16,6 +17,7 @@
{{ $o->render_item_old($langtag.'.'.$key) }} {{ $o->render_item_old($langtag.'.'.$key) }}
@endif @endif
@endforeach @endforeach
@endforeach
</x-attribute.layout> </x-attribute.layout>
@if($edit) @if($edit)

View File

@ -11,11 +11,11 @@
@switch(get_class($o)) @switch(get_class($o))
@case(Certificate::class) @case(Certificate::class)
@case(CertificateList::class) @case(CertificateList::class)
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-replace" disabled><i class="fas fa-fw fa-certificate"></i> @lang('Replace')</span> <span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name_lc }}-replace" disabled><i class="fas fa-fw fa-certificate"></i> @lang('Replace')</span>
@section('page-scripts') @section('page-scripts')
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
$('#{{ $o->name }}-replace.addable').click(function(e) { $('attribute#{{ $o->name_lc }}-replace.addable').click(function(e) {
alert('Sorry, not implemented yet'); alert('Sorry, not implemented yet');
e.preventDefault(); e.preventDefault();
return false; return false;
@ -55,7 +55,7 @@
var rendered = false; var rendered = false;
var newadded = []; var newadded = [];
var oc = $('attribute#objectClass input[type=text]') var oc = $('attribute#objectclass input[type=text]')
.map((key,item)=>{return $(item).val()}).toArray(); .map((key,item)=>{return $(item).val()}).toArray();
if (newadded.length) if (newadded.length)
@ -81,7 +81,7 @@
}, },
cache: false, cache: false,
success: function(data) { success: function(data) {
$('#{{ $o->name }}').append(data); $('attribute#{{ $o->name_lc }}').append(data);
}, },
error: function(e) { error: function(e) {
if (e.status !== 412) if (e.status !== 412)
@ -98,13 +98,13 @@
// Render any must attributes // Render any must attributes
if (data.must.length) { if (data.must.length) {
data.must.forEach(function(item) { data.must.forEach(function(item) {
if ($('attribute#'+item).length) if ($('attribute#'+item.toLowerCase()).length)
return; return;
// Add attribute to the page // Add attribute to the page
$.ajax({ $.ajax({
method: 'POST', method: 'POST',
url: '{{ url('entry/attr/add') }}/'+item, url: '{{ url('entry/attr/add') }}/'+item.toLowerCase(),
data: { data: {
value: item, value: item,
objectclasses: oc, objectclasses: oc,
@ -237,11 +237,11 @@
@break @break
@case(JpegPhoto::class) @case(JpegPhoto::class)
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-upload" disabled><i class="fas fa-fw fa-file-arrow-up"></i> @lang('Upload JpegPhoto')</span> <span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name_lc }}-upload" disabled><i class="fas fa-fw fa-file-arrow-up"></i> @lang('Upload JpegPhoto')</span>
@section('page-scripts') @section('page-scripts')
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
$('#{{ $o->name }}-upload.addable').click(function(e) { $('#{{ $o->name_lc }}-upload.addable').click(function(e) {
alert('Sorry, not implemented yet'); alert('Sorry, not implemented yet');
e.preventDefault(); e.preventDefault();
return false; return false;
@ -256,7 +256,7 @@
@if($o->isDynamic()) @break @endif @if($o->isDynamic()) @break @endif
@php($clone=TRUE) @php($clone=TRUE)
@if($o->values_old->count()) @if($o->values_old->count())
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-addnew"><i class="fas fa-fw fa-plus"></i> @lang('Add Value')</span> <span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) data-attribute="{{ $o->name }}" id="{{ $o->name_lc }}-addnew"><i class="fas fa-fw fa-plus"></i> @lang('Add Value')</span>
@endif @endif
@section('page-scripts') @section('page-scripts')
@ -264,13 +264,16 @@
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { $(document).ready(function() {
// Create a new entry when Add Value clicked // Create a new entry when Add Value clicked
$('#{{ $o->name }}-addnew.addable').click(function (item) { $('#{{ $o->name_lc }}-addnew.addable').click(function(item) {
var cln = $(this).parent().parent().find('input:last').parent().clone(); var attribute = $(this).data('attribute');
cln.find('input:last') var active = $('attribute[id='+attribute+']').find('.tab-pane.active');
active.find('input:last')
.clone()
.attr('value','') .attr('value','')
.attr('placeholder','[@lang('NEW')]') .attr('placeholder','[@lang('NEW')]')
.addClass('border-focus') .addClass('border-focus')
.appendTo('#'+item.currentTarget.id.replace('-addnew','')); .appendTo(active);
}); });
}); });
</script> </script>

View File

@ -1,8 +1,10 @@
<!-- $o=Attribute::class --> <!-- $o=Attribute::class -->
<x-attribute.layout :edit="false" :new="false" :o="$o" :detail="true"> <x-attribute.layout :edit="false" :new="false" :o="$o" :detail="true">
@foreach($o->langtags as $langtag)
@foreach(Arr::get(old($o->name_lc,[$langtag=>$o->tagValues($langtag)]),$langtag,[]) as $value) @foreach(Arr::get(old($o->name_lc,[$langtag=>$o->tagValues($langtag)]),$langtag,[]) as $value)
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control mb-1" value="{{ \Carbon\Carbon::createFromTimestamp(strtotime($value))->format(config('pla.datetime_format','Y-m-d H:i:s')) }}" disabled> <input type="text" class="form-control mb-1" value="{{ \Carbon\Carbon::createFromTimestamp(strtotime($value))->format(config('pla.datetime_format','Y-m-d H:i:s')) }}" disabled>
</div> </div>
@endforeach @endforeach
@endforeach
</x-attribute.layout> </x-attribute.layout>

View File

@ -1,8 +1,10 @@
<!-- $o=Attribute::class --> <!-- $o=Attribute::class -->
<x-attribute.layout :edit="false" :new="false" :o="$o" :detail="true"> <x-attribute.layout :edit="false" :new="false" :o="$o" :detail="true">
@foreach($o->langtags as $langtag)
@foreach(Arr::get(old($o->name_lc,[$langtag=>$o->tagValues($langtag)]),$langtag,[]) as $value) @foreach(Arr::get(old($o->name_lc,[$langtag=>$o->tagValues($langtag)]),$langtag,[]) as $value)
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control mb-1" value="{{ $value }}" disabled> <input type="text" class="form-control mb-1" value="{{ $value }}" disabled>
</div> </div>
@endforeach @endforeach
@endforeach
</x-attribute.layout> </x-attribute.layout>

View File

@ -2,7 +2,7 @@
<div class="alert alert-success"> <div class="alert alert-success">
<h4 class="alert-heading"><i class="fas fa-fw fa-thumbs-up"></i> Success!</h4> <h4 class="alert-heading"><i class="fas fa-fw fa-thumbs-up"></i> Success!</h4>
<hr> <hr>
<ul style="list-style-type: square;"> <ul class="square">
@foreach (session()->get('success') as $item) @foreach (session()->get('success') as $item)
<li>{{ $item }}</li> <li>{{ $item }}</li>
@endforeach @endforeach

View File

@ -8,10 +8,10 @@
<input type="hidden" name="name={{ $o->name_lc }}[binary][]" value="{{ md5($value) }}"> <input type="hidden" name="name={{ $o->name_lc }}[binary][]" value="{{ md5($value) }}">
<div class="input-group has-validation mb-3"> <div class="input-group has-validation mb-3">
<textarea class="form-control mb-1 font-monospace" rows="{{ count(explode("\n",$x=$o->certificate())) }}" style="overflow: hidden; font-size: 90%;" disabled>{{ $x }}</textarea> <textarea class="form-control mb-1 font-size-md font-monospace overflow-hidden" rows="{{ count(explode("\n",$x=$o->certificate())) }}" disabled>{{ $x }}</textarea>
<div class="invalid-feedback pb-2"> <div class="invalid-feedback pb-2">
@if($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)) @if($e=$errors->get($o->name_lc.'.binary.'.$loop->index))
{{ join('|',$e) }} {{ join('|',$e) }}
@endif @endif
</div> </div>

View File

@ -1,12 +1,13 @@
<div id="newattrs"></div> <div id="newattrs"></div>
<hr class="opacity-05">
<!-- Add new attributes --> <!-- Add new attributes -->
<div class="row"> <div class="row">
<div class="col-12 col-sm-1 col-md-2"></div> <div class="col-12 offset-lg-1 col-lg-10">
<div class="col-12 col-sm-10 col-md-8"> <div class="d-none round" id="newattr-select">
<div class="d-none" id="newattr-select">
<div class="row"> <div class="row">
<div class="col-12 bg-dark text-light p-2"> <div class="col-12 bg-dark text-light p-2 rounded-2">
<i class="fas fa-plus-circle"></i> Add New Attribute <i class="fas fa-plus-circle"></i> Add New Attribute
</div> </div>
</div> </div>

View File

@ -1,3 +1,5 @@
@use(App\Ldap\Entry)
<table class="table table-borderless"> <table class="table table-borderless">
<tr class="border-bottom line-height-2"> <tr class="border-bottom line-height-2">
<td class="p-1 pt-0" rowspan="2"> <td class="p-1 pt-0" rowspan="2">
@ -6,7 +8,7 @@
<td class="text-end align-bottom pb-0 mb-0 pt-2 pe-3 {{ $x ? 'ps-3' : '' }}"><strong class="user-select-all">{{ $o->getDn() }}</strong></td> <td class="text-end align-bottom pb-0 mb-0 pt-2 pe-3 {{ $x ? 'ps-3' : '' }}"><strong class="user-select-all">{{ $o->getDn() }}</strong></td>
</tr> </tr>
<tr> <tr>
<td class="align-bottom" style="font-size: 55%" colspan="2"> <td class="align-bottom font-size-xs" colspan="2">
<table class="table table-condensed table-borderless w-100"> <table class="table table-condensed table-borderless w-100">
<tr class="mt-1"> <tr class="mt-1">
<td class="p-0 pe-2">Created</td> <td class="p-0 pe-2">Created</td>
@ -26,10 +28,17 @@
<x-attribute :o="$o->getObject('entryuuid')"/> <x-attribute :o="$o->getObject('entryuuid')"/>
</th> </th>
</tr> </tr>
@if($langtags->count()) <!-- It is assumed that langtags contains at least Entry::TAG_NOTAG -->
@if(($x=$o->getLangTags()
->flatMap(fn($item)=>$item->values())
->unique()
->sort()
->filter(fn($item)=>($item !== Entry::TAG_NOTAG))
->map(fn($item)=>preg_replace('/'.Entry::LANG_TAG_PREFIX.'/','',$item)))
->count())
<tr class="mt-1"> <tr class="mt-1">
<td class="p-0 pe-2">Tags</td> <td class="p-0 pe-2">Tags</td>
<th class="p-0">{{ $langtags->join(', ') }}</th> <th class="p-0">{{ $x->join(', ') }}</th>
</tr> </tr>
@endif @endif
</table> </table>

View File

@ -77,7 +77,7 @@
<tbody> <tbody>
<tr> <tr>
<td> <td>
<ul class="ps-3" style="list-style-type: square;"> <ul class="ps-3 square">
@foreach($o->getMustAttrs(TRUE) as $oo) @foreach($o->getMustAttrs(TRUE) as $oo)
<li>{{ $oo->name }} @if($oo->source !== $o->name)[<strong><a class="objectclass" id="{{ strtolower($oo->source) }}" href="#{{ strtolower($oo->source) }}">{{ $oo->source }}</a></strong>]@endif</li> <li>{{ $oo->name }} @if($oo->source !== $o->name)[<strong><a class="objectclass" id="{{ strtolower($oo->source) }}" href="#{{ strtolower($oo->source) }}">{{ $oo->source }}</a></strong>]@endif</li>
@endforeach @endforeach
@ -99,7 +99,7 @@
<tbody> <tbody>
<tr> <tr>
<td> <td>
<ul class="ps-3" style="list-style-type: square;"> <ul class="ps-3 square">
@foreach($o->getMayAttrs(TRUE) as $oo) @foreach($o->getMayAttrs(TRUE) as $oo)
<li>{{ $oo->name }} @if($oo->source !== $o->name)[<strong><a class="objectclass" id="{{ strtolower($oo->source) }}" href="#{{ strtolower($oo->source) }}">{{ $oo->source }}</a></strong>]@endif</li> <li>{{ $oo->name }} @if($oo->source !== $o->name)[<strong><a class="objectclass" id="{{ strtolower($oo->source) }}" href="#{{ strtolower($oo->source) }}">{{ $oo->source }}</a></strong>]@endif</li>
@endforeach @endforeach

View File

@ -3,10 +3,7 @@
@extends('layouts.dn') @extends('layouts.dn')
@section('page_title') @section('page_title')
@include('fragment.dn.header',[ @include('fragment.dn.header',['o'=>($oo=$server->fetch(old('container',$container)))])
'o'=>($oo=$server->fetch(old('container',$container))),
'langtags'=>collect(),
])
@endsection @endsection
@section('page_status') @section('page_status')
@ -50,10 +47,10 @@
@break @break
@case(2) @case(2)
<x-attribute-type :o="$o->getObject('rdn')" :edit="TRUE" :new="FALSE" :langtag="Entry::TAG_NOTAG" :updated="FALSE"/> <x-attribute-type :o="$o->getObject('rdn')" :edit="TRUE" :new="FALSE" :updated="FALSE"/>
@foreach ($o->getVisibleAttributes() as $ao) @foreach ($o->getVisibleAttributes() as $ao)
<x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :langtag="Entry::TAG_NOTAG" :updated="FALSE"/> <x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :updated="FALSE"/>
@endforeach @endforeach
@include('fragment.dn.add_attr') @include('fragment.dn.add_attr')
@ -94,7 +91,7 @@
}); });
// Our password type // Our password type
$('attribute#userPassword .form-select').each(function() { $('attribute#userpassword .form-select').each(function() {
$(this).prop('disabled',false); $(this).prop('disabled',false);
}) })
@ -107,7 +104,7 @@
$(document).ready(function() { $(document).ready(function() {
@if($step === 2) @if($step === 2)
$('#newattr').on('change',function(item) { $('#newattr').on('change',function(item) {
var oc = $('attribute#objectClass input[type=text]') var oc = $('attribute#objectclass input[type=text]')
.map((key,item)=>{return $(item).val()}).toArray(); .map((key,item)=>{return $(item).val()}).toArray();
$.ajax({ $.ajax({

View File

@ -1,15 +1,7 @@
@use(App\Ldap\Entry)
@extends('layouts.dn') @extends('layouts.dn')
@section('page_title') @section('page_title')
@include('fragment.dn.header',[ @include('fragment.dn.header',['o'=>($o ?? $o=$server->fetch($dn))])
'o'=>($o ?? $o=$server->fetch($dn)),
'langtags'=>($langtags=$o->getLangTags()
->flatMap(fn($item)=>$item->values())
->unique()
->sort())
])
@endsection @endsection
@section('page_actions') @section('page_actions')
@ -82,71 +74,52 @@
<div class="tab-content"> <div class="tab-content">
<!-- All Attributes --> <!-- All Attributes -->
<div class="tab-pane active" id="attributes" role="tabpanel"> <div class="tab-pane active" id="attributes" role="tabpanel">
<div class="row pt-3">
<div class="col-12">
<div class="d-flex justify-content-center">
<div role="group" class="btn-group btn-group-sm nav pb-3">
<!-- It is assumed that the entry has atleast 1 template "default" -->
@if($o->templates->count() > 1)
@foreach($o->templates as $template => $name)
<span data-bs-toggle="tab" href="#template-{{$template}}" @class(['btn','btn-outline-focus','active'=>$loop->index === 0])>{{ $name }}</span>
@endforeach
@endif
</div>
</div>
<div class="tab-content">
@foreach($o->templates as $template => $name)
@switch($template)
@case('default')
<div @class(['tab-pane','active'=>$loop->index === 0]) id="template-{{$template}}" role="tabpanel">
<form id="dn-edit" method="POST" class="needs-validation" action="{{ url('entry/update/pending') }}" novalidate readonly> <form id="dn-edit" method="POST" class="needs-validation" action="{{ url('entry/update/pending') }}" novalidate readonly>
@csrf @csrf
<input type="hidden" name="dn" value=""> <input type="hidden" name="dn" value="">
<div class="card-header border-bottom-0">
<div class="btn-actions-pane-right">
<div role="group" class="btn-group-sm nav btn-group">
@php
$langtags->prepend(Entry::TAG_NOTAG);
if (isset($page_actions) && $page_actions->get('edit'))
$langtags->push('+');
@endphp
@foreach($langtags as $tag)
<a data-bs-toggle="tab" href="#tab-lang-{{ $tag ?: '_default' }}" @class(['btn','btn-outline-light','border-dark-subtle','active'=>!$loop->index])>
@switch($tag)
@case(Entry::TAG_NOTAG)
<i class="fas fa-fw fa-border-none" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip" title="@lang('No Lang Tag')"></i>
@break
@case('+')
<!-- @todo To implement -->
<i class="fas fa-fw fa-plus text-dark" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip" title="@lang('Add Lang Tag')"></i>
@break
@default
<span class="f16" data-bs-toggle="tooltip" data-bs-custom-class="custom-tooltip" title="{{ strtoupper($tag) }}"><i class="flag {{ $tag }}"></i></span>
@endswitch
</a>
@endforeach
</div>
</div>
</div>
<div class="card-body"> <div class="card-body">
<div class="tab-content"> <div class="tab-content">
@php($up=(session()->pull('updated') ?: collect())) @php($up=(session()->pull('updated') ?: collect()))
@foreach($langtags as $tag) @foreach($o->getVisibleAttributes() as $ao)
<div class="tab-pane @if(! $loop->index) active @endif" id="tab-lang-{{ $tag ?: '_default' }}" role="tabpanel"> <x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :updated="$up->contains($ao->name_lc)"/>
@switch($tag)
@case(Entry::TAG_NOTAG)
@foreach ($o->getVisibleAttributes($tag) as $ao)
<x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :langtag="$tag" :updated="$up->contains($ao->name_lc)"/>
@endforeach @endforeach
@break
@case('+') @include('fragment.dn.add_attr')
<div class="ms-auto mt-4 alert alert-warning p-2" style="max-width: 30em; font-size: 0.80em;"> </div>
It is not possible to create new language tags at the moment. This functionality should come soon.<br> </div>
You can create them with an LDIF import though. </form>
</div> </div>
@break @break
@default @default
@foreach ($o->getVisibleAttributes($langtag=sprintf('lang-%s',$tag)) as $ao) <div @class(['tab-pane','active'=>$loop->index === 0]) id="template-{{$template}}" role="tabpanel">
<x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :langtag="$langtag" :updated="$up->contains($ao->name_lc)"/> <p>{{$name}}</p>
@endforeach </div>
@endswitch @endswitch
</div>
@endforeach @endforeach
</div> </div>
</div> </div>
</div>
@include('fragment.dn.add_attr')
</form>
<div class="row d-none pt-3"> <div class="row d-none pt-3">
<div class="col-12 offset-sm-2 col-sm-4 col-lg-2"> <div class="col-12 offset-sm-2 col-sm-4 col-lg-2">
@ -159,7 +132,7 @@
<!-- Internal Attributes --> <!-- Internal Attributes -->
<div class="tab-pane mt-3" id="internal" role="tabpanel"> <div class="tab-pane mt-3" id="internal" role="tabpanel">
@foreach($o->getInternalAttributes() as $ao) @foreach($o->getInternalAttributes() as $ao)
<x-attribute-type :o="$ao" :edit="FALSE" :new="FALSE" :langtag="Entry::TAG_NOTAG" :updated="FALSE"/> <x-attribute-type :o="$ao" :edit="FALSE" :new="FALSE" :updated="FALSE"/>
@endforeach @endforeach
</div> </div>
</div> </div>
@ -201,7 +174,7 @@
}); });
// Our password type // Our password type
$('attribute#userPassword .form-select').each(function() { $('attribute#userpassword .form-select').each(function() {
$(this).prop('disabled',false); $(this).prop('disabled',false);
}) })
@ -230,7 +203,7 @@
}); });
$('#newattr').on('change',function(item) { $('#newattr').on('change',function(item) {
var oc = $('attribute#objectClass input[type=text]') var oc = $('attribute#objectclass input[type=text]')
.map((key,item)=>{return $(item).val()}).toArray(); .map((key,item)=>{return $(item).val()}).toArray();
$.ajax({ $.ajax({
@ -278,7 +251,7 @@
if (e.status !== 412) if (e.status !== 412)
alert('That didnt work? Please try again....'); alert('That didnt work? Please try again....');
}, },
}) });
break; break;
case 'entry-export': case 'entry-export':

View File

@ -3,7 +3,7 @@
@section('page_title') @section('page_title')
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td style="border-radius: 5px;"><div class="page-title-icon f32"><i class="fas fa-upload"></i></div></td> <td><div class="page-title-icon f32"><i class="fas fa-upload"></i></div></td>
<td class="top text-start align-text-top p-2"><strong>@lang('LDIF Import')</strong><br><small>@lang('To Server') <strong>{{ $server->name }}</strong></small></td> <td class="top text-start align-text-top p-2"><strong>@lang('LDIF Import')</strong><br><small>@lang('To Server') <strong>{{ $server->name }}</strong></small></td>
</tr> </tr>
</table> </table>

View File

@ -1,7 +1,7 @@
@section('page_title') @section('page_title')
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td style="border-radius: 5px;"><div class="page-title-icon f32"><i class="fas fa-upload"></i></div></td> <td><div class="page-title-icon f32"><i class="fas fa-upload"></i></div></td>
<td class="top text-start align-text-top p-0 pt-2"><strong>@lang('LDIF Import Result')</strong><br><small>@lang('To Server') <strong>{{ $server->name }}</strong></small></td> <td class="top text-start align-text-top p-0 pt-2"><strong>@lang('LDIF Import Result')</strong><br><small>@lang('To Server') <strong>{{ $server->name }}</strong></small></td>
</tr> </tr>
</table> </table>

View File

@ -3,7 +3,7 @@
@section('page_title') @section('page_title')
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td style="border-radius: 5px;"><div class="page-title-icon f32"><i class="fas fa-info"></i></div></td> <td><div class="page-title-icon f32"><i class="fas fa-info"></i></div></td>
<td class="top text-end align-text-top p-2"><strong>@lang('Server Info')</strong><br><small>{{ $server->rootDSE()->entryuuid[0] ?? '' }}</small></td> <td class="top text-end align-text-top p-2"><strong>@lang('Server Info')</strong><br><small>{{ $server->rootDSE()->entryuuid[0] ?? '' }}</small></td>
</tr> </tr>
</table> </table>

View File

@ -3,7 +3,7 @@
@section('page_title') @section('page_title')
<table class="table table-borderless"> <table class="table table-borderless">
<tr> <tr>
<td style="border-radius: 5px;"><div class="page-title-icon f32"><i class="fas fa-fingerprint"></i></div></td> <td><div class="page-title-icon f32"><i class="fas fa-fingerprint"></i></div></td>
<td class="top text-end align-text-top p-2"><strong>{{ $server->schemaDN() }}</strong></td> <td class="top text-end align-text-top p-2"><strong>{{ $server->schemaDN() }}</strong></td>
</tr> </tr>
</table> </table>

View File

@ -1,12 +1,7 @@
@extends('home') @extends('home')
@section('page_title') @section('page_title')
@include('fragment.dn.header',[ @include('fragment.dn.header')
'langtags'=>($langtags=$o->getLangTags()
->flatMap(fn($item)=>$item->values())
->unique()
->sort())
])
@endsection @endsection
@section('page_status') @section('page_status')