Compare commits

...

5 Commits

Author SHA1 Message Date
d3c7bfcf79 Ensure form validation is displayed on template input entries, especially those marked as read-only
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 1m30s
Create Docker Image / Build Docker Image (arm64) (push) Successful in 2m43s
Create Docker Image / Final Docker Image Manifest (push) Successful in 9s
2025-06-22 09:40:45 +10:00
43c92e542c Fix regression introduce in 31e3c7 when adding a new objectclass to a new entry, newoc shouldnt be passed as a form value 2025-06-22 09:23:06 +10:00
7352293880 Fix rendering updated attributes on entries that trigger a template 2025-06-22 09:11:47 +10:00
bc4490a075 Framework and javascript dependancies update 2025-06-22 09:11:47 +10:00
05b2651ef4 Update README with v2.2 updates, as well as updating the home page 2025-06-22 09:11:47 +10:00
8 changed files with 309 additions and 139 deletions

View File

@ -1,4 +1,10 @@
# phpLDAPadmin # phpLDAPadmin
![GitHub commit activity](https://img.shields.io/github/commit-activity/m/leenooks/phpldapadmin)
![Docker Pulls](https://img.shields.io/docker/pulls/phpldapadmin/phpldapadmin)
![GitHub Downloads (all assets, all releases)](https://img.shields.io/github/downloads/leenooks/phpldapadmin/total)
![GitHub Release Date](https://img.shields.io/github/release-date/leenooks/phpldapadmin)
![GitHub commits since latest release](https://img.shields.io/github/commits-since/leenooks/phpldapadmin/latest)
phpLDAPadmin is a web based LDAP data management tool for system administrators. It is commonly known and referred by many as "PLA". phpLDAPadmin is a web based LDAP data management tool for system administrators. It is commonly known and referred by many as "PLA".
PLA is designed to be compliant with LDAP RFCs, enabling it to be used with any LDAP server. PLA is designed to be compliant with LDAP RFCs, enabling it to be used with any LDAP server.
@ -27,38 +33,29 @@ Take a look at the [Docker Container](https://github.com/leenooks/phpLDAPadmin/w
> >
> Open an issue (details below) with enough information for me to be able to recreate the problem. An `LDIF` will be invaluable if it is not handling data correctly. > Open an issue (details below) with enough information for me to be able to recreate the problem. An `LDIF` will be invaluable if it is not handling data correctly.
## Version 2 Progress ## Templates
Starting with v2.2, PLA reintroduces the template engine. Each point release going forward will improve the template
functionality. Check [releases](releases) for details.
The update to v2 is progressing well - here is a list of work to do and done: Templates in v2 are in JSON format (in v1 they were XML format). If you want to create your own templates you can use
the [example.json](blob/master/templates/example.json) template as a guide. Place your custom templates in a subdirectory
under `templates`, eg: `templates/custom`, and they wont be overwritten by an update.
- [X] Creating new LDAP entries ## Outstanding items
- [X] Delete existing LDAP entries Compare to v1.x, there are a couple of outstanding items to address
- [X] Updating existing LDAP Entries
- [X] Password attributes Entry Editing:
- [X] Support different password hash options
- [X] Validate password is correct
- [ ] JpegPhoto Create/Delete - [ ] JpegPhoto Create/Delete
- [ ] Binary attribute upload - [ ] Binary attribute upload
- [X] JpegPhoto Display - [ ] If removing an objectClass, remove all attributes that only that objectclass provided
- [X] ObjectClass Add/Remove
- [X] Add additional required attributes (for ObjectClass Addition)
- [ ] Remove existing required attributes (for ObjectClass Removal)
- [X] Add additional values to Attributes that support multiple values
- [X] Delete extra values for Attributes that support multiple values
- [ ] Delete Attributes
- [ ] Templates to enable entries to conform to a custom standard
- [ ] Autopopulate attribute values
- [X] Login to LDAP server
- [X] Configure login by a specific attribute
- [X] Logout LDAP server
- [X] Export entries as an LDAP
- [X] Import LDIF
- [X] Schema Browser
- [X] Searching
- [ ] Enforcing attribute uniqueness
- [ ] Is there something missing?
Support is known for these LDAP servers: Templates Engine
- [ ] Present SELECT lists when an attribute is marked as `type=select`
- [ ] Enforcing attribute uniqueness
Raise a [feature request](issues/new) if there is a capability that you would like to see added to PLA.
## Support is known for these LDAP servers:
- [X] OpenLDAP - [X] OpenLDAP
- [X] OpenDJ - [X] OpenDJ
- [ ] Microsoft Active Directory - [ ] Microsoft Active Directory

165
composer.lock generated
View File

@ -8,16 +8,16 @@
"packages": [ "packages": [
{ {
"name": "brick/math", "name": "brick/math",
"version": "0.12.3", "version": "0.13.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/brick/math.git", "url": "https://github.com/brick/math.git",
"reference": "866551da34e9a618e64a819ee1e01c20d8a588ba" "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/brick/math/zipball/866551da34e9a618e64a819ee1e01c20d8a588ba", "url": "https://api.github.com/repos/brick/math/zipball/fc7ed316430118cc7836bf45faff18d5dfc8de04",
"reference": "866551da34e9a618e64a819ee1e01c20d8a588ba", "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -56,7 +56,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/brick/math/issues", "issues": "https://github.com/brick/math/issues",
"source": "https://github.com/brick/math/tree/0.12.3" "source": "https://github.com/brick/math/tree/0.13.1"
}, },
"funding": [ "funding": [
{ {
@ -64,7 +64,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-02-28T13:11:00+00:00" "time": "2025-03-29T13:50:30+00:00"
}, },
{ {
"name": "carbonphp/carbon-doctrine-types", "name": "carbonphp/carbon-doctrine-types",
@ -288,16 +288,16 @@
}, },
{ {
"name": "directorytree/ldaprecord-laravel", "name": "directorytree/ldaprecord-laravel",
"version": "v3.4.1", "version": "v3.4.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/DirectoryTree/LdapRecord-Laravel.git", "url": "https://github.com/DirectoryTree/LdapRecord-Laravel.git",
"reference": "15f56e01319852d41023633d3688ac4aa139aa6e" "reference": "28c5a7aa42aa3fa631f9c0f0c8236fd19bc7b00c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/DirectoryTree/LdapRecord-Laravel/zipball/15f56e01319852d41023633d3688ac4aa139aa6e", "url": "https://api.github.com/repos/DirectoryTree/LdapRecord-Laravel/zipball/28c5a7aa42aa3fa631f9c0f0c8236fd19bc7b00c",
"reference": "15f56e01319852d41023633d3688ac4aa139aa6e", "reference": "28c5a7aa42aa3fa631f9c0f0c8236fd19bc7b00c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -343,7 +343,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/DirectoryTree/LdapRecord-Laravel/issues", "issues": "https://github.com/DirectoryTree/LdapRecord-Laravel/issues",
"source": "https://github.com/DirectoryTree/LdapRecord-Laravel/tree/v3.4.1" "source": "https://github.com/DirectoryTree/LdapRecord-Laravel/tree/v3.4.2"
}, },
"funding": [ "funding": [
{ {
@ -351,7 +351,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-03-21T19:16:44+00:00" "time": "2025-06-13T15:46:25+00:00"
}, },
{ {
"name": "doctrine/inflector", "name": "doctrine/inflector",
@ -1199,20 +1199,20 @@
}, },
{ {
"name": "laravel/framework", "name": "laravel/framework",
"version": "v12.16.0", "version": "v12.19.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/framework.git", "url": "https://github.com/laravel/framework.git",
"reference": "293bb1c70224faebfd3d4328e201c37115da055f" "reference": "4e6ec689ef704bb4bd282f29d9dd658dfb4fb262"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/293bb1c70224faebfd3d4328e201c37115da055f", "url": "https://api.github.com/repos/laravel/framework/zipball/4e6ec689ef704bb4bd282f29d9dd658dfb4fb262",
"reference": "293bb1c70224faebfd3d4328e201c37115da055f", "reference": "4e6ec689ef704bb4bd282f29d9dd658dfb4fb262",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"brick/math": "^0.11|^0.12", "brick/math": "^0.11|^0.12|^0.13",
"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",
@ -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-27T15:49:44+00:00" "time": "2025-06-18T12:56:23+00:00"
}, },
{ {
"name": "laravel/prompts", "name": "laravel/prompts",
@ -2315,16 +2315,16 @@
}, },
{ {
"name": "nesbot/carbon", "name": "nesbot/carbon",
"version": "3.9.1", "version": "3.10.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/CarbonPHP/carbon.git", "url": "https://github.com/CarbonPHP/carbon.git",
"reference": "ced71f79398ece168e24f7f7710462f462310d4d" "reference": "c1397390dd0a7e0f11660f0ae20f753d88c1f3d9"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/ced71f79398ece168e24f7f7710462f462310d4d", "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/c1397390dd0a7e0f11660f0ae20f753d88c1f3d9",
"reference": "ced71f79398ece168e24f7f7710462f462310d4d", "reference": "c1397390dd0a7e0f11660f0ae20f753d88c1f3d9",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2332,7 +2332,7 @@
"ext-json": "*", "ext-json": "*",
"php": "^8.1", "php": "^8.1",
"psr/clock": "^1.0", "psr/clock": "^1.0",
"symfony/clock": "^6.3 || ^7.0", "symfony/clock": "^6.3.12 || ^7.0",
"symfony/polyfill-mbstring": "^1.0", "symfony/polyfill-mbstring": "^1.0",
"symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0" "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0"
}, },
@ -2342,14 +2342,13 @@
"require-dev": { "require-dev": {
"doctrine/dbal": "^3.6.3 || ^4.0", "doctrine/dbal": "^3.6.3 || ^4.0",
"doctrine/orm": "^2.15.2 || ^3.0", "doctrine/orm": "^2.15.2 || ^3.0",
"friendsofphp/php-cs-fixer": "^3.57.2", "friendsofphp/php-cs-fixer": "^3.75.0",
"kylekatarnls/multi-tester": "^2.5.3", "kylekatarnls/multi-tester": "^2.5.3",
"ondrejmirtes/better-reflection": "^6.25.0.4",
"phpmd/phpmd": "^2.15.0", "phpmd/phpmd": "^2.15.0",
"phpstan/extension-installer": "^1.3.1", "phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan": "^1.11.2", "phpstan/phpstan": "^2.1.17",
"phpunit/phpunit": "^10.5.20", "phpunit/phpunit": "^10.5.46",
"squizlabs/php_codesniffer": "^3.9.0" "squizlabs/php_codesniffer": "^3.13.0"
}, },
"bin": [ "bin": [
"bin/carbon" "bin/carbon"
@ -2417,7 +2416,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-05-01T19:51:51+00:00" "time": "2025-06-12T10:24:28+00:00"
}, },
{ {
"name": "nette/schema", "name": "nette/schema",
@ -2483,16 +2482,16 @@
}, },
{ {
"name": "nette/utils", "name": "nette/utils",
"version": "v4.0.6", "version": "v4.0.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nette/utils.git", "url": "https://github.com/nette/utils.git",
"reference": "ce708655043c7050eb050df361c5e313cf708309" "reference": "e67c4061eb40b9c113b218214e42cb5a0dda28f2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nette/utils/zipball/ce708655043c7050eb050df361c5e313cf708309", "url": "https://api.github.com/repos/nette/utils/zipball/e67c4061eb40b9c113b218214e42cb5a0dda28f2",
"reference": "ce708655043c7050eb050df361c5e313cf708309", "reference": "e67c4061eb40b9c113b218214e42cb5a0dda28f2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2563,9 +2562,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/nette/utils/issues", "issues": "https://github.com/nette/utils/issues",
"source": "https://github.com/nette/utils/tree/v4.0.6" "source": "https://github.com/nette/utils/tree/v4.0.7"
}, },
"time": "2025-03-30T21:06:30+00:00" "time": "2025-06-03T04:55:08+00:00"
}, },
{ {
"name": "nunomaduro/termwind", "name": "nunomaduro/termwind",
@ -3263,16 +3262,16 @@
}, },
{ {
"name": "ramsey/uuid", "name": "ramsey/uuid",
"version": "4.8.0", "version": "4.8.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/ramsey/uuid.git", "url": "https://github.com/ramsey/uuid.git",
"reference": "6700833915c00f890615fbcb653faed513836836" "reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/ramsey/uuid/zipball/6700833915c00f890615fbcb653faed513836836", "url": "https://api.github.com/repos/ramsey/uuid/zipball/fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28",
"reference": "6700833915c00f890615fbcb653faed513836836", "reference": "fdf4dd4e2ff1813111bd0ad58d7a1ddbb5b56c28",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3336,9 +3335,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/ramsey/uuid/issues", "issues": "https://github.com/ramsey/uuid/issues",
"source": "https://github.com/ramsey/uuid/tree/4.8.0" "source": "https://github.com/ramsey/uuid/tree/4.8.1"
}, },
"time": "2025-06-01T02:32:15+00:00" "time": "2025-06-01T06:28:46+00:00"
}, },
{ {
"name": "symfony/clock", "name": "symfony/clock",
@ -6076,16 +6075,16 @@
}, },
{ {
"name": "filp/whoops", "name": "filp/whoops",
"version": "2.18.0", "version": "2.18.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/filp/whoops.git", "url": "https://github.com/filp/whoops.git",
"reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e" "reference": "59a123a3d459c5a23055802237cb317f609867e5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e", "url": "https://api.github.com/repos/filp/whoops/zipball/59a123a3d459c5a23055802237cb317f609867e5",
"reference": "a7de6c3c6c3c022f5cfc337f8ede6a14460cf77e", "reference": "59a123a3d459c5a23055802237cb317f609867e5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -6135,7 +6134,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/filp/whoops/issues", "issues": "https://github.com/filp/whoops/issues",
"source": "https://github.com/filp/whoops/tree/2.18.0" "source": "https://github.com/filp/whoops/tree/2.18.3"
}, },
"funding": [ "funding": [
{ {
@ -6143,7 +6142,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-03-15T12:00:00+00:00" "time": "2025-06-16T00:02:10+00:00"
}, },
{ {
"name": "hamcrest/hamcrest-php", "name": "hamcrest/hamcrest-php",
@ -6399,23 +6398,23 @@
}, },
{ {
"name": "nunomaduro/collision", "name": "nunomaduro/collision",
"version": "v8.8.0", "version": "v8.8.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/nunomaduro/collision.git", "url": "https://github.com/nunomaduro/collision.git",
"reference": "4cf9f3b47afff38b139fb79ce54fc71799022ce8" "reference": "44ccb82e3e21efb5446748d2a3c81a030ac22bd5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/nunomaduro/collision/zipball/4cf9f3b47afff38b139fb79ce54fc71799022ce8", "url": "https://api.github.com/repos/nunomaduro/collision/zipball/44ccb82e3e21efb5446748d2a3c81a030ac22bd5",
"reference": "4cf9f3b47afff38b139fb79ce54fc71799022ce8", "reference": "44ccb82e3e21efb5446748d2a3c81a030ac22bd5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"filp/whoops": "^2.18.0", "filp/whoops": "^2.18.1",
"nunomaduro/termwind": "^2.3.0", "nunomaduro/termwind": "^2.3.1",
"php": "^8.2.0", "php": "^8.2.0",
"symfony/console": "^7.2.5" "symfony/console": "^7.3.0"
}, },
"conflict": { "conflict": {
"laravel/framework": "<11.44.2 || >=13.0.0", "laravel/framework": "<11.44.2 || >=13.0.0",
@ -6423,15 +6422,15 @@
}, },
"require-dev": { "require-dev": {
"brianium/paratest": "^7.8.3", "brianium/paratest": "^7.8.3",
"larastan/larastan": "^3.2", "larastan/larastan": "^3.4.2",
"laravel/framework": "^11.44.2 || ^12.6", "laravel/framework": "^11.44.2 || ^12.18",
"laravel/pint": "^1.21.2", "laravel/pint": "^1.22.1",
"laravel/sail": "^1.41.0", "laravel/sail": "^1.43.1",
"laravel/sanctum": "^4.0.8", "laravel/sanctum": "^4.1.1",
"laravel/tinker": "^2.10.1", "laravel/tinker": "^2.10.1",
"orchestra/testbench-core": "^9.12.0 || ^10.1", "orchestra/testbench-core": "^9.12.0 || ^10.4",
"pestphp/pest": "^3.8.0", "pestphp/pest": "^3.8.2",
"sebastian/environment": "^7.2.0 || ^8.0" "sebastian/environment": "^7.2.1 || ^8.0"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
@ -6494,7 +6493,7 @@
"type": "patreon" "type": "patreon"
} }
], ],
"time": "2025-04-03T14:33:09+00:00" "time": "2025-06-11T01:04:21+00:00"
}, },
{ {
"name": "phar-io/manifest", "name": "phar-io/manifest",
@ -6686,16 +6685,16 @@
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
"version": "11.0.9", "version": "11.0.10",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7" "reference": "1a800a7446add2d79cc6b3c01c45381810367d76"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/14d63fbcca18457e49c6f8bebaa91a87e8e188d7", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1a800a7446add2d79cc6b3c01c45381810367d76",
"reference": "14d63fbcca18457e49c6f8bebaa91a87e8e188d7", "reference": "1a800a7446add2d79cc6b3c01c45381810367d76",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -6752,15 +6751,27 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.9" "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/show"
}, },
"funding": [ "funding": [
{ {
"url": "https://github.com/sebastianbergmann", "url": "https://github.com/sebastianbergmann",
"type": "github" "type": "github"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage",
"type": "tidelift"
} }
], ],
"time": "2025-02-25T13:26:39+00:00" "time": "2025-06-18T08:56:18+00:00"
}, },
{ {
"name": "phpunit/php-file-iterator", "name": "phpunit/php-file-iterator",
@ -7009,16 +7020,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "11.5.21", "version": "11.5.24",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "d565e2cdc21a7db9dc6c399c1fc2083b8010f289" "reference": "6b07ab1047155cf38f82dd691787a277782271dd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d565e2cdc21a7db9dc6c399c1fc2083b8010f289", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6b07ab1047155cf38f82dd691787a277782271dd",
"reference": "d565e2cdc21a7db9dc6c399c1fc2083b8010f289", "reference": "6b07ab1047155cf38f82dd691787a277782271dd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -7032,7 +7043,7 @@
"phar-io/manifest": "^2.0.4", "phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1", "phar-io/version": "^3.2.1",
"php": ">=8.2", "php": ">=8.2",
"phpunit/php-code-coverage": "^11.0.9", "phpunit/php-code-coverage": "^11.0.10",
"phpunit/php-file-iterator": "^5.1.0", "phpunit/php-file-iterator": "^5.1.0",
"phpunit/php-invoker": "^5.0.1", "phpunit/php-invoker": "^5.0.1",
"phpunit/php-text-template": "^4.0.1", "phpunit/php-text-template": "^4.0.1",
@ -7090,7 +7101,7 @@
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy", "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.21" "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.24"
}, },
"funding": [ "funding": [
{ {
@ -7114,7 +7125,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2025-05-21T12:35:00+00:00" "time": "2025-06-20T11:31:02+00:00"
}, },
{ {
"name": "sebastian/cli-parser", "name": "sebastian/cli-parser",

193
package-lock.json generated
View File

@ -2800,6 +2800,21 @@
"postcss": "^8.1.0" "postcss": "^8.1.0"
} }
}, },
"node_modules/available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
"license": "MIT",
"dependencies": {
"possible-typed-array-names": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/axios": { "node_modules/axios": {
"version": "1.10.0", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz",
@ -3312,9 +3327,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001723", "version": "1.0.30001724",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001724.tgz",
"integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==", "integrity": "sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -4325,9 +4340,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/electron-to-chromium": { "node_modules/electron-to-chromium": {
"version": "1.5.170", "version": "1.5.171",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.170.tgz", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.171.tgz",
"integrity": "sha512-GP+M7aeluQo9uAyiTCxgIj/j+PrWhMlY7LFVj8prlsPljd0Fdg9AprlfUi+OCSFWy9Y5/2D/Jrj9HS8Z4rpKWA==", "integrity": "sha512-scWpzXEJEMrGJa4Y6m/tVotb0WuvNmasv3wWVzUAeCgKU0ToFOhUW6Z+xWnRQANMYGxN4ngJXIThgBJOqzVPCQ==",
"license": "ISC" "license": "ISC"
}, },
"node_modules/elliptic": { "node_modules/elliptic": {
@ -4908,6 +4923,21 @@
} }
} }
}, },
"node_modules/for-each": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
"integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
"license": "MIT",
"dependencies": {
"is-callable": "^1.2.7"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/form-data": { "node_modules/form-data": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz",
@ -5731,6 +5761,18 @@
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/is-callable": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-core-module": { "node_modules/is-core-module": {
"version": "2.16.1", "version": "2.16.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
@ -5836,6 +5878,21 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/is-typed-array": {
"version": "1.1.15",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
"integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
"license": "MIT",
"dependencies": {
"which-typed-array": "^1.1.16"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-what": { "node_modules/is-what": {
"version": "3.14.1", "version": "3.14.1",
"resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
@ -7051,21 +7108,53 @@
} }
}, },
"node_modules/pbkdf2": { "node_modules/pbkdf2": {
"version": "3.1.2", "version": "3.1.3",
"resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.3.tgz",
"integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", "integrity": "sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"create-hash": "^1.1.2", "create-hash": "~1.1.3",
"create-hmac": "^1.1.4", "create-hmac": "^1.1.7",
"ripemd160": "^2.0.1", "ripemd160": "=2.0.1",
"safe-buffer": "^5.0.1", "safe-buffer": "^5.2.1",
"sha.js": "^2.4.8" "sha.js": "^2.4.11",
"to-buffer": "^1.2.0"
}, },
"engines": { "engines": {
"node": ">=0.12" "node": ">=0.12"
} }
}, },
"node_modules/pbkdf2/node_modules/create-hash": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
"integrity": "sha512-snRpch/kwQhcdlnZKYanNF1m0RDlrCdSKQaH87w1FCFPVPNCQ/Il9QJKAX2jVBZddRdaHBMC+zXa9Gw9tmkNUA==",
"license": "MIT",
"dependencies": {
"cipher-base": "^1.0.1",
"inherits": "^2.0.1",
"ripemd160": "^2.0.0",
"sha.js": "^2.4.0"
}
},
"node_modules/pbkdf2/node_modules/hash-base": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
"integrity": "sha512-0TROgQ1/SxE6KmxWSvXHvRj90/Xo1JvZShofnYF+f6ZsGtR4eES7WfrQzPalmyagfKZCXpVnitiRebZulWsbiw==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.1"
}
},
"node_modules/pbkdf2/node_modules/ripemd160": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
"integrity": "sha512-J7f4wutN8mdbV08MJnXibYpCOPHR+yzy+iQ/AsjMv2j8cLavQ8VGagDFUwwTAdF8FmRKVeNpbTTEwNHCW1g94w==",
"license": "MIT",
"dependencies": {
"hash-base": "^2.0.0",
"inherits": "^2.0.1"
}
},
"node_modules/pe7-icon": { "node_modules/pe7-icon": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/pe7-icon/-/pe7-icon-1.0.4.tgz", "resolved": "https://registry.npmjs.org/pe7-icon/-/pe7-icon-1.0.4.tgz",
@ -7117,6 +7206,15 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/possible-typed-array-names": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
"integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.5.6", "version": "8.5.6",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
@ -8996,9 +9094,9 @@
} }
}, },
"node_modules/terser": { "node_modules/terser": {
"version": "5.43.0", "version": "5.43.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.43.0.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz",
"integrity": "sha512-CqNNxKSGKSZCunSvwKLTs8u8sGGlp27sxNZ4quGh0QeNuyHM0JSEM/clM9Mf4zUp6J+tO2gUXhgXT2YMMkwfKQ==", "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==",
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"@jridgewell/source-map": "^0.3.3", "@jridgewell/source-map": "^0.3.3",
@ -9130,6 +9228,26 @@
"integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/to-buffer": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.1.tgz",
"integrity": "sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==",
"license": "MIT",
"dependencies": {
"isarray": "^2.0.5",
"safe-buffer": "^5.2.1",
"typed-array-buffer": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/to-buffer/node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
"license": "MIT"
},
"node_modules/to-regex-range": { "node_modules/to-regex-range": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@ -9176,6 +9294,20 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/typed-array-buffer": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
"integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.3",
"es-errors": "^1.3.0",
"is-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/undici-types": { "node_modules/undici-types": {
"version": "7.8.0", "version": "7.8.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
@ -9791,9 +9923,9 @@
} }
}, },
"node_modules/webpack/node_modules/webpack-sources": { "node_modules/webpack/node_modules/webpack-sources": {
"version": "3.3.2", "version": "3.3.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.2.tgz", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz",
"integrity": "sha512-ykKKus8lqlgXX/1WjudpIEjqsafjOTcOJqxnAbMLAu/KCsDCJ6GBtvscewvTkrn24HsnvFwrSCbenFrhtcCsAA==", "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=10.13.0" "node": ">=10.13.0"
@ -9855,6 +9987,27 @@
"node": ">= 8" "node": ">= 8"
} }
}, },
"node_modules/which-typed-array": {
"version": "1.1.19",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
"integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
"license": "MIT",
"dependencies": {
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.8",
"call-bound": "^1.0.4",
"for-each": "^0.3.5",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/wildcard": { "node_modules/wildcard": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz",

View File

@ -5,9 +5,12 @@
@foreach($o->langtags as $langtag) @foreach($o->langtags as $langtag)
<span @class(['tab-pane','active'=>$loop->index === 0]) id="langtag-{{ $o->name_lc }}-{{ $langtag }}" role="tabpanel"> <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))
<div class="input-group has-validation"> <div class="input-group has-validation">
@if($edit && (! $o->is_rdn))
<input type="text" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! ($tv=$o->tagValuesOld($langtag))->contains($value),'bg-success-subtle'=>$updated]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ ! is_null($x=$tv->get($loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(! $new) @disabled($o->isDynamic())> <input type="text" @class(['form-control','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','border-focus'=>! ($tv=$o->tagValuesOld($langtag))->contains($value),'bg-success-subtle'=>$updated]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" placeholder="{{ ! is_null($x=$tv->get($loop->index)) ? $x : '['.__('NEW').']' }}" @readonly(! $new) @disabled($o->isDynamic())>
@else
<input type="text" @class(['form-control','noedit','is-invalid'=>($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index)),'mb-1','bg-success-subtle'=>$updated]) name="{{ $o->name_lc }}[{{ $langtag }}][]" value="{{ $value }}" readonly>
@endif
<div class="invalid-feedback pb-2"> <div class="invalid-feedback pb-2">
@if($e) @if($e)
@ -15,10 +18,6 @@
@endif @endif
</div> </div>
</div> </div>
@else
<input type="text" @class(['form-control','mb-1','bg-success-subtle'=>$updated]) value="{{ $value }}" disabled>
@endif
@endforeach @endforeach
</span> </span>
@endforeach @endforeach

View File

@ -38,7 +38,7 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<x-form.select id="newoc" name="newoc" :label="__('Select from').'...'"/> <x-form.select id="newoc" :label="__('Select from').'...'"/>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">

View File

@ -6,10 +6,10 @@
<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()->get('updated') ?: collect()))
@foreach($o->getVisibleAttributes()->filter(fn($item)=>$template->attributes->map('strtolower')->contains($item->name_lc)) as $ao) @foreach($o->getVisibleAttributes()->filter(fn($item)=>$template->attributes->map('strtolower')->contains($item->name_lc)) as $ao)
<x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :template="$template" :updated="$up->contains($ao->name_lc)"/> <x-attribute-type :o="$ao" :edit="TRUE" :new="FALSE" :template="$template" :updated="$up->contains($ao->name)"/>
@endforeach @endforeach
</div> </div>
</div> </div>

View File

@ -106,6 +106,10 @@
if (rdn_attr && ($(this)[0].name === rdn_attr+'[]')) if (rdn_attr && ($(this)[0].name === rdn_attr+'[]'))
return; return;
// Exclude attributes marked as noedit
if ($(this).hasClass('noedit'))
return;
$(this).attr('readonly',false); $(this).attr('readonly',false);
}); });

View File

@ -44,6 +44,12 @@
<li class="ps-0 p-1"> <li class="ps-0 p-1">
<i class="fas fa-fw fa-sitemap me-2"></i> Hierarchical Tree View <i class="fas fa-fw fa-sitemap me-2"></i> Hierarchical Tree View
</li> </li>
<li class="ps-0 p-1">
<i class="fas fa-fw fa-clone me-2"></i> Creation and Modification Templates
</li>
<li class="ps-0 p-1">
<i class="fas fa-fw fa-magnifying-glass-chart me-2"></i> Data Rich Attribute Values
</li>
<li class="ps-0 p-1"> <li class="ps-0 p-1">
<i class="fas fa-fw fa-language me-2"></i> Multi-language Support <i class="fas fa-fw fa-language me-2"></i> Multi-language Support
</li> </li>