+ */
+ private $values;
+
+ /**
+ * @var int
+ */
+ private $size = 0;
+
+ /**
+ * Creates a new enum map.
+ *
+ * @param string $keyType the type of the keys, must extend AbstractEnum
+ * @param string $valueType the type of the values
+ * @param bool $allowNullValues whether to allow null values
+ * @throws IllegalArgumentException when key type does not extend AbstractEnum
+ */
+ public function __construct(string $keyType, string $valueType, bool $allowNullValues)
+ {
+ if (! is_subclass_of($keyType, AbstractEnum::class)) {
+ throw new IllegalArgumentException(sprintf(
+ 'Class %s does not extend %s',
+ $keyType,
+ AbstractEnum::class
+ ));
+ }
+
+ $this->keyType = $keyType;
+ $this->valueType = $valueType;
+ $this->allowNullValues = $allowNullValues;
+ $this->keyUniverse = $keyType::values();
+ $this->values = array_fill(0, count($this->keyUniverse), null);
+ }
+
+ public function __serialize(): array
+ {
+ $values = [];
+
+ foreach ($this->values as $ordinal => $value) {
+ if (null === $value) {
+ continue;
+ }
+
+ $values[$ordinal] = $this->unmaskNull($value);
+ }
+
+ return [
+ 'keyType' => $this->keyType,
+ 'valueType' => $this->valueType,
+ 'allowNullValues' => $this->allowNullValues,
+ 'values' => $values,
+ ];
+ }
+
+ public function __unserialize(array $data): void
+ {
+ $this->unserialize(serialize($data));
+ }
+
+ /**
+ * Checks whether the map types match the supplied ones.
+ *
+ * You should call this method when an EnumMap is passed to you and you want to ensure that it's made up of the
+ * correct types.
+ *
+ * @throws ExpectationException when supplied key type mismatches local key type
+ * @throws ExpectationException when supplied value type mismatches local value type
+ * @throws ExpectationException when the supplied map allows null values, abut should not
+ */
+ public function expect(string $keyType, string $valueType, bool $allowNullValues) : void
+ {
+ if ($keyType !== $this->keyType) {
+ throw new ExpectationException(sprintf(
+ 'Callee expected an EnumMap with key type %s, but got %s',
+ $keyType,
+ $this->keyType
+ ));
+ }
+
+ if ($valueType !== $this->valueType) {
+ throw new ExpectationException(sprintf(
+ 'Callee expected an EnumMap with value type %s, but got %s',
+ $keyType,
+ $this->keyType
+ ));
+ }
+
+ if ($allowNullValues !== $this->allowNullValues) {
+ throw new ExpectationException(sprintf(
+ 'Callee expected an EnumMap with nullable flag %s, but got %s',
+ ($allowNullValues ? 'true' : 'false'),
+ ($this->allowNullValues ? 'true' : 'false')
+ ));
+ }
+ }
+
+ /**
+ * Returns the number of key-value mappings in this map.
+ */
+ public function size() : int
+ {
+ return $this->size;
+ }
+
+ /**
+ * Returns true if this map maps one or more keys to the specified value.
+ */
+ public function containsValue($value) : bool
+ {
+ return in_array($this->maskNull($value), $this->values, true);
+ }
+
+ /**
+ * Returns true if this map contains a mapping for the specified key.
+ */
+ public function containsKey(AbstractEnum $key) : bool
+ {
+ $this->checkKeyType($key);
+ return null !== $this->values[$key->ordinal()];
+ }
+
+ /**
+ * Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
+ *
+ * More formally, if this map contains a mapping from a key to a value, then this method returns the value;
+ * otherwise it returns null (there can be at most one such mapping).
+ *
+ * A return value of null does not necessarily indicate that the map contains no mapping for the key; it's also
+ * possible that hte map explicitly maps the key to null. The {@see self::containsKey()} operation may be used to
+ * distinguish these two cases.
+ *
+ * @return mixed
+ */
+ public function get(AbstractEnum $key)
+ {
+ $this->checkKeyType($key);
+ return $this->unmaskNull($this->values[$key->ordinal()]);
+ }
+
+ /**
+ * Associates the specified value with the specified key in this map.
+ *
+ * If the map previously contained a mapping for this key, the old value is replaced.
+ *
+ * @return mixed the previous value associated with the specified key, or null if there was no mapping for the key.
+ * (a null return can also indicate that the map previously associated null with the specified key.)
+ * @throws IllegalArgumentException when the passed values does not match the internal value type
+ */
+ public function put(AbstractEnum $key, $value)
+ {
+ $this->checkKeyType($key);
+
+ if (! $this->isValidValue($value)) {
+ throw new IllegalArgumentException(sprintf('Value is not of type %s', $this->valueType));
+ }
+
+ $index = $key->ordinal();
+ $oldValue = $this->values[$index];
+ $this->values[$index] = $this->maskNull($value);
+
+ if (null === $oldValue) {
+ ++$this->size;
+ }
+
+ return $this->unmaskNull($oldValue);
+ }
+
+ /**
+ * Removes the mapping for this key frm this map if present.
+ *
+ * @return mixed the previous value associated with the specified key, or null if there was no mapping for the key.
+ * (a null return can also indicate that the map previously associated null with the specified key.)
+ */
+ public function remove(AbstractEnum $key)
+ {
+ $this->checkKeyType($key);
+
+ $index = $key->ordinal();
+ $oldValue = $this->values[$index];
+ $this->values[$index] = null;
+
+ if (null !== $oldValue) {
+ --$this->size;
+ }
+
+ return $this->unmaskNull($oldValue);
+ }
+
+ /**
+ * Removes all mappings from this map.
+ */
+ public function clear() : void
+ {
+ $this->values = array_fill(0, count($this->keyUniverse), null);
+ $this->size = 0;
+ }
+
+ /**
+ * Compares the specified map with this map for quality.
+ *
+ * Returns true if the two maps represent the same mappings.
+ */
+ public function equals(self $other) : bool
+ {
+ if ($this === $other) {
+ return true;
+ }
+
+ if ($this->size !== $other->size) {
+ return false;
+ }
+
+ return $this->values === $other->values;
+ }
+
+ /**
+ * Returns the values contained in this map.
+ *
+ * The array will contain the values in the order their corresponding keys appear in the map, which is their natural
+ * order (the order in which the num constants are declared).
+ */
+ public function values() : array
+ {
+ return array_values(array_map(function ($value) {
+ return $this->unmaskNull($value);
+ }, array_filter($this->values, function ($value) : bool {
+ return null !== $value;
+ })));
+ }
+
+ public function serialize() : string
+ {
+ return serialize($this->__serialize());
+ }
+
+ public function unserialize($serialized) : void
+ {
+ $data = unserialize($serialized);
+ $this->__construct($data['keyType'], $data['valueType'], $data['allowNullValues']);
+
+ foreach ($this->keyUniverse as $key) {
+ if (array_key_exists($key->ordinal(), $data['values'])) {
+ $this->put($key, $data['values'][$key->ordinal()]);
+ }
+ }
+ }
+
+ public function getIterator() : Traversable
+ {
+ foreach ($this->keyUniverse as $key) {
+ if (null === $this->values[$key->ordinal()]) {
+ continue;
+ }
+
+ yield $key => $this->unmaskNull($this->values[$key->ordinal()]);
+ }
+ }
+
+ private function maskNull($value)
+ {
+ if (null === $value) {
+ return NullValue::instance();
+ }
+
+ return $value;
+ }
+
+ private function unmaskNull($value)
+ {
+ if ($value instanceof NullValue) {
+ return null;
+ }
+
+ return $value;
+ }
+
+ /**
+ * @throws IllegalArgumentException when the passed key does not match the internal key type
+ */
+ private function checkKeyType(AbstractEnum $key) : void
+ {
+ if (get_class($key) !== $this->keyType) {
+ throw new IllegalArgumentException(sprintf(
+ 'Object of type %s is not the same type as %s',
+ get_class($key),
+ $this->keyType
+ ));
+ }
+ }
+
+ private function isValidValue($value) : bool
+ {
+ if (null === $value) {
+ if ($this->allowNullValues) {
+ return true;
+ }
+
+ return false;
+ }
+
+ switch ($this->valueType) {
+ case 'mixed':
+ return true;
+
+ case 'bool':
+ case 'boolean':
+ return is_bool($value);
+
+ case 'int':
+ case 'integer':
+ return is_int($value);
+
+ case 'float':
+ case 'double':
+ return is_float($value);
+
+ case 'string':
+ return is_string($value);
+
+ case 'object':
+ return is_object($value);
+
+ case 'array':
+ return is_array($value);
+ }
+
+ return $value instanceof $this->valueType;
+ }
+}
diff --git a/data/web/inc/lib/vendor/dasprid/enum/src/Exception/CloneNotSupportedException.php b/data/web/inc/lib/vendor/dasprid/enum/src/Exception/CloneNotSupportedException.php
new file mode 100644
index 000000000..4b37dbebe
--- /dev/null
+++ b/data/web/inc/lib/vendor/dasprid/enum/src/Exception/CloneNotSupportedException.php
@@ -0,0 +1,10 @@
+
**Environment:**
- LDAP Server Type: [e.g. ActiveDirectory / OpenLDAP / FreeIPA]
- - PHP Version: [e.g. 7.3 / 7.4 / 8.0]
+ - PHP Version: [e.g. 8.1 / 8.2]
**Describe the bug:**
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/ISSUE_TEMPLATE/support---help-request.md b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/ISSUE_TEMPLATE/support---help-request.md
index 731d5cea0..b97a977cb 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/ISSUE_TEMPLATE/support---help-request.md
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/ISSUE_TEMPLATE/support---help-request.md
@@ -17,4 +17,4 @@ assignees: ''
-->
**Environment:**
- LDAP Server Type: [e.g. ActiveDirectory / OpenLDAP / FreeIPA]
- - PHP Version: [e.g. 7.3 / 7.4 / 8.0]
+ - PHP Version: [e.g. 8.1 / 8.2]
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-cs-fix.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-cs-fix.yml
new file mode 100644
index 000000000..80cd34d61
--- /dev/null
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-cs-fix.yml
@@ -0,0 +1,34 @@
+name: run-cs-fix
+
+on:
+ push:
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: true
+ matrix:
+ php: [8.3]
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ extensions: json, dom, curl, libxml, mbstring
+ coverage: none
+
+ - name: Install Pint
+ run: composer global require laravel/pint
+
+ - name: Run Pint
+ run: pint
+
+ - name: Commit linted files
+ uses: stefanzweifel/git-auto-commit-action@v5
+ with:
+ commit_message: "Fix code style"
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-integration-tests.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-integration-tests.yml
index 6a6b2f9e5..de67e91c9 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-integration-tests.yml
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-integration-tests.yml
@@ -1,62 +1,62 @@
name: run-integration-tests
on:
- push:
- pull_request:
- schedule:
- - cron: "0 0 * * *"
+ push:
+ pull_request:
+ schedule:
+ - cron: "0 0 * * *"
jobs:
- run-tests:
- runs-on: ${{ matrix.os }}
+ run-tests:
+ runs-on: ${{ matrix.os }}
- services:
- ldap:
- image: osixia/openldap:1.4.0
- env:
- LDAP_TLS_VERIFY_CLIENT: try
- LDAP_OPENLDAP_UID: 1000
- LDAP_OPENLDAP_GID: 1000
- LDAP_ORGANISATION: Local
- LDAP_DOMAIN: local.com
- LDAP_ADMIN_PASSWORD: secret
- ports:
- - 389:389
- - 636:636
+ services:
+ ldap:
+ image: osixia/openldap:1.4.0
+ env:
+ LDAP_TLS_VERIFY_CLIENT: try
+ LDAP_OPENLDAP_UID: 1000
+ LDAP_OPENLDAP_GID: 1000
+ LDAP_ORGANISATION: Local
+ LDAP_DOMAIN: local.com
+ LDAP_ADMIN_PASSWORD: secret
+ ports:
+ - 389:389
+ - 636:636
- strategy:
- fail-fast: false
- matrix:
- os: [ubuntu-latest]
- php: [8.1, 8.0, 7.4]
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest]
+ php: [8.1, 8.2, 8.3]
- name: ${{ matrix.os }} - P${{ matrix.php }}
+ name: ${{ matrix.os }} - P${{ matrix.php }}
- steps:
- - name: Checkout code
- uses: actions/checkout@v2
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
- - name: Cache dependencies
- uses: actions/cache@v2
- with:
- path: ~/.composer/cache/files
- key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
+ - name: Cache dependencies
+ uses: actions/cache@v3
+ with:
+ path: ~/.composer/cache/files
+ key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
- - name: Set ldap.conf file permissions
- run: sudo chown -R $USER:$USER /etc/ldap/ldap.conf
+ - name: Set ldap.conf file permissions
+ run: sudo chown -R $USER:$USER /etc/ldap/ldap.conf
- - name: Create ldap.conf file disabling TLS verification
- run: sudo echo "TLS_REQCERT never" > "/etc/ldap/ldap.conf"
+ - name: Create ldap.conf file disabling TLS verification
+ run: sudo echo "TLS_REQCERT never" > "/etc/ldap/ldap.conf"
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php }}
- extensions: ldap, json
- coverage: none
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ extensions: ldap, json
+ coverage: none
- - name: Install dependencies
- run: composer update --prefer-dist --no-interaction
+ - name: Install dependencies
+ run: composer update --prefer-dist --no-interaction
- - name: Execute tests
- run: vendor/bin/phpunit --testsuite Integration
+ - name: Execute tests
+ run: vendor/bin/phpunit --testsuite Integration
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-tests.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-tests.yml
index 6aaa3fd4a..8781e918a 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-tests.yml
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/.github/workflows/run-tests.yml
@@ -1,41 +1,41 @@
name: run-tests
on:
- push:
- pull_request:
- schedule:
- - cron: "0 0 * * *"
+ push:
+ pull_request:
+ schedule:
+ - cron: "0 0 * * *"
jobs:
- run-tests:
- runs-on: ${{ matrix.os }}
- name: ${{ matrix.os }} - P${{ matrix.php }}
+ run-tests:
+ runs-on: ${{ matrix.os }}
+ name: ${{ matrix.os }} - P${{ matrix.php }}
- strategy:
- fail-fast: false
- matrix:
- os: [ubuntu-latest, windows-latest]
- php: [8.1, 8.0, 7.4, 7.3]
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, windows-latest]
+ php: [8.1, 8.2, 8.3, 8.4]
- steps:
- - name: Checkout code
- uses: actions/checkout@v2
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
- - name: Cache dependencies
- uses: actions/cache@v2
- with:
- path: ~/.composer/cache/files
- key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
+ - name: Cache dependencies
+ uses: actions/cache@v3
+ with:
+ path: ~/.composer/cache/files
+ key: dependencies-php-${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php }}
- extensions: ldap, json
- coverage: none
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ extensions: ldap, json
+ coverage: none
- - name: Install dependencies
- run: composer update --prefer-dist --no-interaction
+ - name: Install dependencies
+ run: composer update --prefer-dist --no-interaction
- - name: Execute tests
- run: vendor/bin/phpunit --testsuite Unit
+ - name: Execute tests
+ run: vendor/bin/phpunit --testsuite Unit
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.scrutinizer.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/.scrutinizer.yml
deleted file mode 100644
index b3f8f88b2..000000000
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/.scrutinizer.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-filter:
- excluded_paths:
- - tests/*
-build:
- nodes:
- analysis:
- tests:
- override:
- - command: php-scrutinizer-run
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/.styleci.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/.styleci.yml
deleted file mode 100644
index 0285f1790..000000000
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/.styleci.yml
+++ /dev/null
@@ -1 +0,0 @@
-preset: laravel
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/composer.json b/data/web/inc/lib/vendor/directorytree/ldaprecord/composer.json
index 65d7dd8f6..97e84cd5e 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/composer.json
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/composer.json
@@ -29,20 +29,22 @@
}
],
"require": {
- "php": ">=7.3",
+ "php": ">=8.1",
"ext-ldap": "*",
"ext-json": "*",
- "psr/log": "^1.0|^2.0|^3.0",
- "psr/simple-cache": "^1.0|^2.0",
- "nesbot/carbon": "^1.0|^2.0",
- "tightenco/collect": "^5.6|^6.0|^7.0|^8.0|^9.0",
- "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0|^9.0|^10.0",
- "symfony/polyfill-php80": "^1.25"
+ "ext-iconv": "*",
+ "psr/log": "*",
+ "nesbot/carbon": "*",
+ "psr/simple-cache": "^1.0|^2.0|^3.0",
+ "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0",
+ "illuminate/collections": "^8.0|^9.0|^10.0|^11.0|^12.0"
},
"require-dev": {
"phpunit/phpunit": "^9.0",
"mockery/mockery": "^1.0",
- "spatie/ray": "^1.24"
+ "spatie/ray": "^1.24",
+ "laravel/pint": "^1.6",
+ "fakerphp/faker": "^1.21"
},
"archive": {
"exclude": [
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/docker-compose.yml b/data/web/inc/lib/vendor/directorytree/ldaprecord/docker-compose.yml
index de96b1398..1abf0979d 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/docker-compose.yml
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/docker-compose.yml
@@ -1,5 +1,3 @@
-version: '3'
-
services:
ldap:
image: osixia/openldap:1.4.0
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/readme.md b/data/web/inc/lib/vendor/directorytree/ldaprecord/readme.md
index e00f8ef69..4e34bd727 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/readme.md
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/readme.md
@@ -1,25 +1,12 @@
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
@@ -32,9 +19,9 @@
- Quickstart
+ Quickstart
·
- Documentation
+ Documentation
·
Laravel Integration
·
@@ -67,15 +54,15 @@ Active Directory Features
🚪 **Enable / Disable Accounts**
-Detect and assign User Account Control values on accounts with the fluent [Account Control builder](https://ldaprecord.com/docs/core/v2/active-directory/users/#uac).
+Detect and assign User Account Control values on accounts with the fluent [Account Control builder](https://ldaprecord.com/docs/core/v3/active-directory/users/#uac).
🔑 **Reset / Change Passwords**
-Built-in support for [changing](https://ldaprecord.com/docs/core/v2/active-directory/users/#changing-passwords) and [resetting](https://ldaprecord.com/docs/core/v2/active-directory/users/#resetting-passwords) passwords on Active Directory accounts.
+Built-in support for [changing](https://ldaprecord.com/docs/core/v3/active-directory/users/#changing-passwords) and [resetting](https://ldaprecord.com/docs/core/v3/active-directory/users/#resetting-passwords) passwords on Active Directory accounts.
🗑 **Restore Deleted Objects**
-We've all been there -- accidentally deleting a user or group in Active Directory. [Restore them](https://ldaprecord.com/docs/core/v2/models/#restoring-deleted-models) by seamlessly accessing your directory's recycle bin.
+Seamlessly access your Active Directory recycle bin and [restore deleted objects](https://ldaprecord.com/docs/core/v3/models/#restoring-deleted-models).
---
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Event.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Event.php
index 7c1bb3c87..29687dbf2 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Event.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Event.php
@@ -8,33 +8,23 @@ abstract class Event
{
/**
* The connection that the username and password is being bound on.
- *
- * @var LdapInterface
*/
- protected $connection;
+ protected LdapInterface $connection;
/**
* The username that is being used for binding.
- *
- * @var string
*/
- protected $username;
+ protected ?string $username;
/**
* The password that is being used for binding.
- *
- * @var string
*/
- protected $password;
+ protected ?string $password;
/**
* Constructor.
- *
- * @param LdapInterface $connection
- * @param string $username
- * @param string $password
*/
- public function __construct(LdapInterface $connection, $username, $password)
+ public function __construct(LdapInterface $connection, ?string $username = null, ?string $password = null)
{
$this->connection = $connection;
$this->username = $username;
@@ -42,31 +32,25 @@ abstract class Event
}
/**
- * Returns the events connection.
- *
- * @return LdapInterface
+ * Get the event's connection.
*/
- public function getConnection()
+ public function getConnection(): LdapInterface
{
return $this->connection;
}
/**
- * Returns the authentication events username.
- *
- * @return string
+ * Get the authentication event's username.
*/
- public function getUsername()
+ public function getUsername(): ?string
{
return $this->username;
}
/**
- * Returns the authentication events password.
- *
- * @return string
+ * Get the authentication event's password.
*/
- public function getPassword()
+ public function getPassword(): ?string
{
return $this->password;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Failed.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Failed.php
index 7133e4390..b26049169 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Failed.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Events/Failed.php
@@ -2,7 +2,32 @@
namespace LdapRecord\Auth\Events;
+use Exception;
+use LdapRecord\Auth\BindException;
+use LdapRecord\LdapInterface;
+
class Failed extends Event
{
- //
+ /**
+ * The exception that was thrown during the bind attempt.
+ */
+ protected BindException $exception;
+
+ /**
+ * Constructor.
+ */
+ public function __construct(LdapInterface $connection, ?string $username, ?string $password, BindException $exception)
+ {
+ parent::__construct($connection, $username, $password);
+
+ $this->exception = $exception;
+ }
+
+ /**
+ * Get the exception that was thrown during the bind attempt.
+ */
+ public function getException(): BindException
+ {
+ return $this->exception;
+ }
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Guard.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Guard.php
index c00989ae6..d560098b7 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Guard.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Auth/Guard.php
@@ -3,11 +3,6 @@
namespace LdapRecord\Auth;
use Exception;
-use LdapRecord\Auth\Events\Attempting;
-use LdapRecord\Auth\Events\Binding;
-use LdapRecord\Auth\Events\Bound;
-use LdapRecord\Auth\Events\Failed;
-use LdapRecord\Auth\Events\Passed;
use LdapRecord\Configuration\DomainConfiguration;
use LdapRecord\Events\DispatcherInterface;
use LdapRecord\LdapInterface;
@@ -16,30 +11,21 @@ class Guard
{
/**
* The connection to bind to.
- *
- * @var LdapInterface
*/
- protected $connection;
+ protected LdapInterface $connection;
/**
* The domain configuration to utilize.
- *
- * @var DomainConfiguration
*/
- protected $configuration;
+ protected DomainConfiguration $configuration;
/**
* The event dispatcher.
- *
- * @var DispatcherInterface
*/
- protected $events;
+ protected ?DispatcherInterface $events = null;
/**
* Constructor.
- *
- * @param LdapInterface $connection
- * @param DomainConfiguration $configuration
*/
public function __construct(LdapInterface $connection, DomainConfiguration $configuration)
{
@@ -50,15 +36,10 @@ class Guard
/**
* Attempt binding a user to the LDAP server.
*
- * @param string $username
- * @param string $password
- * @param bool $stayBound
- * @return bool
- *
* @throws UsernameRequiredException
* @throws PasswordRequiredException
*/
- public function attempt($username, $password, $stayBound = false)
+ public function attempt(string $username, string $password, bool $stayBound = false): bool
{
switch (true) {
case empty($username):
@@ -67,58 +48,73 @@ class Guard
throw new PasswordRequiredException('A password must be specified.');
}
- $this->fireAttemptingEvent($username, $password);
+ $this->fireAuthEvent('attempting', $username, $password);
try {
$this->bind($username, $password);
- $authenticated = true;
+ $bound = true;
- $this->firePassedEvent($username, $password);
- } catch (BindException $e) {
- $authenticated = false;
+ $this->fireAuthEvent('passed', $username, $password);
+ } catch (BindException) {
+ $bound = false;
}
if (! $stayBound) {
$this->bindAsConfiguredUser();
}
- return $authenticated;
+ return $bound;
}
/**
- * Attempt binding a user to the LDAP server. Supports anonymous binding.
- *
- * @param string|null $username
- * @param string|null $password
+ * Attempt binding a user to the LDAP server. Supports sasl and anonymous binding.
*
* @throws BindException
* @throws \LdapRecord\ConnectionException
*/
- public function bind($username = null, $password = null)
+ public function bind(?string $username = null, ?string $password = null): void
{
- $this->fireBindingEvent($username, $password);
+ $this->fireAuthEvent('binding', $username, $password);
// Prior to binding, we will upgrade our connectivity to TLS on our current
// connection and ensure we are not already bound before upgrading.
// This is to prevent subsequent upgrading on several binds.
- if ($this->connection->isUsingTLS() && ! $this->connection->isBound()) {
+ if ($this->connection->isUsingTLS() && ! $this->connection->isSecure()) {
$this->connection->startTLS();
}
try {
- if (! $this->connection->bind($username, $password)) {
+ if (! $this->authenticate($username, $password)) {
throw new Exception($this->connection->getLastError(), $this->connection->errNo());
}
- $this->fireBoundEvent($username, $password);
+ $this->fireAuthEvent('bound', $username, $password);
} catch (Exception $e) {
- $this->fireFailedEvent($username, $password);
+ $exception = BindException::withDetailedError($e, $this->connection->getDetailedError());
- throw BindException::withDetailedError($e, $this->connection->getDetailedError());
+ $this->fireAuthEvent('failed', $username, $password, $exception);
+
+ throw $exception;
}
}
+ /**
+ * Authenticate by binding to the LDAP server.
+ *
+ * @throws \LdapRecord\ConnectionException
+ */
+ protected function authenticate(?string $username = null, ?string $password = null): bool
+ {
+ if ($this->configuration->get('use_sasl') ?? false) {
+ return $this->connection->saslBind(
+ $username, $password, $this->configuration->get('sasl_options')
+ );
+ }
+
+ return $this->connection->bind($username, $password)->successful();
+ }
+
/**
* Bind to the LDAP server using the configured username and password.
*
@@ -126,7 +122,7 @@ class Guard
* @throws \LdapRecord\ConnectionException
* @throws \LdapRecord\Configuration\ConfigurationException
*/
- public function bindAsConfiguredUser()
+ public function bindAsConfiguredUser(): void
{
$this->bind(
$this->configuration->get('username'),
@@ -136,92 +132,29 @@ class Guard
/**
* Get the event dispatcher instance.
- *
- * @return DispatcherInterface
*/
- public function getDispatcher()
+ public function getDispatcher(): ?DispatcherInterface
{
return $this->events;
}
/**
* Set the event dispatcher instance.
- *
- * @param DispatcherInterface $dispatcher
- * @return void
*/
- public function setDispatcher(DispatcherInterface $dispatcher)
+ public function setDispatcher(?DispatcherInterface $dispatcher = null): void
{
$this->events = $dispatcher;
}
/**
- * Fire the attempting event.
- *
- * @param string $username
- * @param string $password
- * @return void
+ * Fire an authentication event.
*/
- protected function fireAttemptingEvent($username, $password)
+ protected function fireAuthEvent(string $name, ?string $username = null, ?string $password = null, ...$args): void
{
if (isset($this->events)) {
- $this->events->fire(new Attempting($this->connection, $username, $password));
- }
- }
+ $event = implode('\\', [Events::class, ucfirst($name)]);
- /**
- * Fire the passed event.
- *
- * @param string $username
- * @param string $password
- * @return void
- */
- protected function firePassedEvent($username, $password)
- {
- if (isset($this->events)) {
- $this->events->fire(new Passed($this->connection, $username, $password));
- }
- }
-
- /**
- * Fire the failed event.
- *
- * @param string $username
- * @param string $password
- * @return void
- */
- protected function fireFailedEvent($username, $password)
- {
- if (isset($this->events)) {
- $this->events->fire(new Failed($this->connection, $username, $password));
- }
- }
-
- /**
- * Fire the binding event.
- *
- * @param string $username
- * @param string $password
- * @return void
- */
- protected function fireBindingEvent($username, $password)
- {
- if (isset($this->events)) {
- $this->events->fire(new Binding($this->connection, $username, $password));
- }
- }
-
- /**
- * Fire the bound event.
- *
- * @param string $username
- * @param string $password
- * @return void
- */
- protected function fireBoundEvent($username, $password)
- {
- if (isset($this->events)) {
- $this->events->fire(new Bound($this->connection, $username, $password));
+ $this->events->fire(new $event($this->connection, $username, $password, ...$args));
}
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/DomainConfiguration.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/DomainConfiguration.php
index f71f63d87..425fbd9ed 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/DomainConfiguration.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/DomainConfiguration.php
@@ -8,19 +8,15 @@ class DomainConfiguration
{
/**
* The extended configuration options.
- *
- * @var array
*/
- protected static $extended = [];
+ protected static array $extended = [];
/**
* The configuration options array.
*
* The default values for each key indicate the type of value it requires.
- *
- * @var array
*/
- protected $options = [
+ protected array $options = [
// An array of LDAP hosts.
'hosts' => [],
@@ -33,6 +29,9 @@ class DomainConfiguration
// The port to use for connecting to your hosts.
'port' => LdapInterface::PORT,
+ // The protocol to use for connecting to your hosts (ldap:// or ldaps://).
+ 'protocol' => null,
+
// The base distinguished name of your domain.
'base_dn' => '',
@@ -42,13 +41,28 @@ class DomainConfiguration
// The password to use for binding.
'password' => '',
- // Whether or not to use SSL when connecting.
+ // Whether to use SSL when connecting.
'use_ssl' => false,
- // Whether or not to use TLS when connecting.
+ // Whether to use TLS when connecting.
'use_tls' => false,
- // Whether or not follow referrals is enabled when performing LDAP operations.
+ // Whether to use SASL when connecting.
+ 'use_sasl' => false,
+
+ // Whether to allow password changes over plaintext.
+ 'allow_insecure_password_changes' => false,
+
+ // SASL options
+ 'sasl_options' => [
+ 'mech' => null,
+ 'realm' => null,
+ 'authc_id' => null,
+ 'authz_id' => null,
+ 'props' => null,
+ ],
+
+ // Whether follow referrals is enabled when performing LDAP operations.
'follow_referrals' => false,
// Custom LDAP options.
@@ -58,8 +72,6 @@ class DomainConfiguration
/**
* Constructor.
*
- * @param array $options
- *
* @throws ConfigurationException When an option value given is an invalid type.
*/
public function __construct(array $options = [])
@@ -73,32 +85,24 @@ class DomainConfiguration
/**
* Extend the configuration with a custom option, or override an existing.
- *
- * @param string $option
- * @param mixed $default
- * @return void
*/
- public static function extend($option, $default = null)
+ public static function extend(string $option, mixed $default = null): void
{
static::$extended[$option] = $default;
}
/**
* Flush the extended configuration options.
- *
- * @return void
*/
- public static function flushExtended()
+ public static function flushExtended(): void
{
static::$extended = [];
}
/**
* Get all configuration options.
- *
- * @return array
*/
- public function all()
+ public function all(): array
{
return $this->options;
}
@@ -106,12 +110,9 @@ class DomainConfiguration
/**
* Set a configuration option.
*
- * @param string $key
- * @param mixed $value
- *
* @throws ConfigurationException When an option value given is an invalid type.
*/
- public function set($key, $value)
+ public function set(string $key, mixed $value): void
{
if ($this->validate($key, $value)) {
$this->options[$key] = $value;
@@ -119,17 +120,14 @@ class DomainConfiguration
}
/**
- * Returns the value for the specified configuration options.
- *
- * @param string $key
- * @return mixed
+ * Get the value for the specified configuration options.
*
* @throws ConfigurationException When the option specified does not exist.
*/
- public function get($key)
+ public function get(string $key): mixed
{
if (! $this->has($key)) {
- throw new ConfigurationException("Option {$key} does not exist.");
+ throw new ConfigurationException("Option $key does not exist.");
}
return $this->options[$key];
@@ -137,11 +135,8 @@ class DomainConfiguration
/**
* Checks if a configuration option exists.
- *
- * @param string $key
- * @return bool
*/
- public function has($key)
+ public function has(string $key): bool
{
return array_key_exists($key, $this->options);
}
@@ -149,13 +144,9 @@ class DomainConfiguration
/**
* Validate the configuration option.
*
- * @param string $key
- * @param mixed $value
- * @return bool
- *
* @throws ConfigurationException When an option value given is an invalid type.
*/
- protected function validate($key, $value)
+ protected function validate(string $key, mixed $value): bool
{
$default = $this->get($key);
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/ArrayValidator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/ArrayValidator.php
index 4aa43ed46..1324d1681 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/ArrayValidator.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/ArrayValidator.php
@@ -6,15 +6,13 @@ class ArrayValidator extends Validator
{
/**
* The validation exception message.
- *
- * @var string
*/
- protected $message = 'Option [:option] must be an array.';
+ protected string $message = 'Option [:option] must be an array.';
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function passes()
+ public function passes(): bool
{
return is_array($this->value);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/BooleanValidator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/BooleanValidator.php
index 1d25a4b25..1156859d3 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/BooleanValidator.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/BooleanValidator.php
@@ -6,15 +6,13 @@ class BooleanValidator extends Validator
{
/**
* The validation exception message.
- *
- * @var string
*/
- protected $message = 'Option [:option] must be a boolean.';
+ protected string $message = 'Option [:option] must be a boolean.';
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function passes()
+ public function passes(): bool
{
return is_bool($this->value);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/IntegerValidator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/IntegerValidator.php
index 5c4f0f95e..d7015888e 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/IntegerValidator.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/IntegerValidator.php
@@ -6,15 +6,13 @@ class IntegerValidator extends Validator
{
/**
* The validation exception message.
- *
- * @var string
*/
- protected $message = 'Option [:option] must be an integer.';
+ protected string $message = 'Option [:option] must be an integer.';
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function passes()
+ public function passes(): bool
{
return is_numeric($this->value);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/StringOrNullValidator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/StringOrNullValidator.php
index bc2337245..5ca453c74 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/StringOrNullValidator.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/StringOrNullValidator.php
@@ -6,15 +6,13 @@ class StringOrNullValidator extends Validator
{
/**
* The validation exception message.
- *
- * @var string
*/
- protected $message = 'Option [:option] must be a string or null.';
+ protected string $message = 'Option [:option] must be a string or null.';
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function passes()
+ public function passes(): bool
{
return is_string($this->value) || is_null($this->value);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/Validator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/Validator.php
index d107314d5..25aedcbfa 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/Validator.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Configuration/Validators/Validator.php
@@ -8,32 +8,23 @@ abstract class Validator
{
/**
* The configuration key under validation.
- *
- * @var string
*/
- protected $key;
+ protected string $key;
/**
* The configuration value under validation.
- *
- * @var mixed
*/
- protected $value;
+ protected mixed $value;
/**
* The validation exception message.
- *
- * @var string
*/
- protected $message;
+ protected string $message;
/**
* Constructor.
- *
- * @param string $key
- * @param mixed $value
*/
- public function __construct($key, $value)
+ public function __construct(string $key, mixed $value)
{
$this->key = $key;
$this->value = $value;
@@ -41,19 +32,15 @@ abstract class Validator
/**
* Determine if the validation rule passes.
- *
- * @return bool
*/
- abstract public function passes();
+ abstract public function passes(): bool;
/**
* Validate the configuration value.
*
- * @return bool
- *
* @throws ConfigurationException
*/
- public function validate()
+ public function validate(): bool
{
if (! $this->passes()) {
$this->fail();
@@ -65,11 +52,9 @@ abstract class Validator
/**
* Throw a configuration exception.
*
- * @return void
- *
* @throws ConfigurationException
*/
- protected function fail()
+ protected function fail(): void
{
throw new ConfigurationException(
str_replace(':option', $this->key, $this->message)
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Connection.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Connection.php
index 6e55cffc9..e04393a27 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Connection.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Connection.php
@@ -5,6 +5,7 @@ namespace LdapRecord;
use Carbon\Carbon;
use Closure;
use LdapRecord\Auth\Guard;
+use LdapRecord\Configuration\ConfigurationException;
use LdapRecord\Configuration\DomainConfiguration;
use LdapRecord\Events\DispatcherInterface;
use LdapRecord\Query\Builder;
@@ -17,85 +18,64 @@ class Connection
/**
* The underlying LDAP connection.
- *
- * @var Ldap
*/
- protected $ldap;
+ protected LdapInterface $ldap;
/**
* The cache driver.
- *
- * @var Cache|null
*/
- protected $cache;
+ protected ?Cache $cache = null;
/**
* The domain configuration.
- *
- * @var DomainConfiguration
*/
- protected $configuration;
+ protected DomainConfiguration $configuration;
/**
- * The event dispatcher;.
- *
- * @var DispatcherInterface|null
+ * The event dispatcher.
*/
- protected $dispatcher;
+ protected ?DispatcherInterface $dispatcher = null;
/**
- * The current host connected to.
- *
- * @var string
+ * The currently connected host.
*/
- protected $host;
+ protected string $host;
/**
* The configured domain hosts.
- *
- * @var array
*/
- protected $hosts = [];
+ protected array $hosts = [];
/**
* The attempted hosts that failed connecting to.
- *
- * @var array
*/
- protected $attempted = [];
+ protected array $attempted = [];
/**
* The callback to execute upon total connection failure.
- *
- * @var Closure
*/
- protected $failed;
+ protected Closure $failed;
/**
* The authentication guard resolver.
- *
- * @var Closure
*/
- protected $authGuardResolver;
+ protected Closure $authGuardResolver;
/**
* Whether the connection is retrying the initial connection attempt.
- *
- * @var bool
*/
- protected $retryingInitialConnection = false;
+ protected bool $retryingInitialConnection = false;
/**
* Constructor.
*
- * @param array|DomainConfiguration $config
- * @param LdapInterface|null $ldap
+ * @throws ConfigurationException
*/
- public function __construct($config = [], LdapInterface $ldap = null)
+ public function __construct(DomainConfiguration|array $config = [], ?LdapInterface $ldap = null)
{
$this->setConfiguration($config);
- $this->setLdapConnection($ldap ?? new Ldap());
+ $this->setLdapConnection($ldap ?? new Ldap);
$this->failed = function () {
$this->dispatch(new Events\ConnectionFailed($this));
@@ -109,12 +89,9 @@ class Connection
/**
* Set the connection configuration.
*
- * @param array|DomainConfiguration $config
- * @return $this
- *
* @throws Configuration\ConfigurationException
*/
- public function setConfiguration($config = [])
+ public function setConfiguration(DomainConfiguration|array $config = []): void
{
if (! $config instanceof DomainConfiguration) {
$config = new DomainConfiguration($config);
@@ -125,54 +102,50 @@ class Connection
$this->hosts = $this->configuration->get('hosts');
$this->host = reset($this->hosts);
-
- return $this;
}
/**
* Set the LDAP connection.
- *
- * @param LdapInterface $ldap
- * @return $this
*/
- public function setLdapConnection(LdapInterface $ldap)
+ public function setLdapConnection(LdapInterface $ldap): void
{
$this->ldap = $ldap;
-
- return $this;
}
/**
* Set the event dispatcher.
- *
- * @param DispatcherInterface $dispatcher
- * @return $this
*/
- public function setDispatcher(DispatcherInterface $dispatcher)
+ public function setDispatcher(DispatcherInterface $dispatcher): void
{
$this->dispatcher = $dispatcher;
-
- return $this;
}
/**
- * Initializes the LDAP connection.
- *
- * @return void
+ * Get the event dispatcher.
*/
- public function initialize()
+ public function getDispatcher(): ?DispatcherInterface
+ {
+ return $this->dispatcher;
+ }
+
+ /**
+ * Initialize the LDAP connection.
+ */
+ public function initialize(): void
{
$this->configure();
- $this->ldap->connect($this->host, $this->configuration->get('port'));
+ $this->ldap->connect(
+ $this->host,
+ $this->configuration->get('port'),
+ $this->configuration->get('protocol')
+ );
}
/**
* Configure the LDAP connection.
- *
- * @return void
*/
- protected function configure()
+ protected function configure(): void
{
if ($this->configuration->get('use_ssl')) {
$this->ldap->ssl();
@@ -192,60 +165,53 @@ class Connection
/**
* Set the cache store.
- *
- * @param CacheInterface $store
- * @return $this
*/
- public function setCache(CacheInterface $store)
+ public function setCache(CacheInterface $store): void
{
$this->cache = new Cache($store);
-
- return $this;
}
/**
* Get the cache store.
- *
- * @return Cache|null
*/
- public function getCache()
+ public function getCache(): ?Cache
{
return $this->cache;
}
/**
* Get the LDAP configuration instance.
- *
- * @return DomainConfiguration
*/
- public function getConfiguration()
+ public function getConfiguration(): DomainConfiguration
{
return $this->configuration;
}
/**
* Get the LDAP connection instance.
- *
- * @return Ldap
*/
- public function getLdapConnection()
+ public function getLdapConnection(): LdapInterface
{
return $this->ldap;
}
+ /**
+ * Set the auth guard resolver callback.
+ */
+ public function setGuardResolver(Closure $callback): void
+ {
+ $this->authGuardResolver = $callback;
+ }
+
/**
* Bind to the LDAP server.
*
* If no username or password is specified, then the configured credentials are used.
*
- * @param string|null $username
- * @param string|null $password
- * @return Connection
- *
* @throws Auth\BindException
* @throws LdapRecordException
*/
- public function connect($username = null, $password = null)
+ public function connect(?string $username = null, ?string $password = null): void
{
$attempt = function () use ($username, $password) {
$this->dispatch(new Events\Connecting($this));
@@ -266,19 +232,16 @@ class Connection
$this->retryOnNextHost($e, $attempt);
}
-
- return $this;
}
/**
* Reconnect to the LDAP server.
*
- * @return void
- *
* @throws Auth\BindException
* @throws ConnectionException
+ * @throws LdapRecordException
*/
- public function reconnect()
+ public function reconnect(): void
{
$this->reinitialize();
@@ -287,10 +250,8 @@ class Connection
/**
* Reinitialize the connection.
- *
- * @return void
*/
- protected function reinitialize()
+ protected function reinitialize(): void
{
$this->disconnect();
@@ -299,31 +260,24 @@ class Connection
/**
* Clone the connection.
- *
- * @return static
*/
- public function replicate()
+ public function replicate(): static
{
return new static($this->configuration, new $this->ldap);
}
/**
* Disconnect from the LDAP server.
- *
- * @return void
*/
- public function disconnect()
+ public function disconnect(): void
{
$this->ldap->close();
}
/**
* Dispatch an event.
- *
- * @param object $event
- * @return void
*/
- public function dispatch($event)
+ public function dispatch(object $event): void
{
if (isset($this->dispatcher)) {
$this->dispatcher->dispatch($event);
@@ -332,25 +286,20 @@ class Connection
/**
* Get the attempted hosts that failed connecting to.
- *
- * @return array
*/
- public function attempted()
+ public function attempted(): array
{
return $this->attempted;
}
/**
* Perform the operation on the LDAP connection.
- *
- * @param Closure $operation
- * @return mixed
*/
- public function run(Closure $operation)
+ public function run(Closure $operation): mixed
{
try {
// Before running the operation, we will check if the current
- // connection is bound and connect if necessary. Otherwise
+ // connection is bound and connect if necessary. Otherwise,
// some LDAP operations will not be executed properly.
if (! $this->isConnected()) {
$this->connect();
@@ -368,11 +317,8 @@ class Connection
/**
* Perform the operation on an isolated LDAP connection.
- *
- * @param Closure $operation
- * @return mixed
*/
- public function isolate(Closure $operation)
+ public function isolate(Closure $operation): mixed
{
$connection = $this->replicate();
@@ -385,11 +331,8 @@ class Connection
/**
* Attempt to get an exception for the cause of failure.
- *
- * @param LdapRecordException $e
- * @return mixed
*/
- protected function getExceptionForCauseOfFailure(LdapRecordException $e)
+ protected function getExceptionForCauseOfFailure(LdapRecordException $e): ?LdapRecordException
{
switch (true) {
case $this->errorContainsMessage($e->getMessage(), 'Already exists'):
@@ -399,29 +342,22 @@ class Connection
case $this->errorContainsMessage($e->getMessage(), 'Constraint violation'):
return Exceptions\ConstraintViolationException::withDetailedError($e, $e->getDetailedError());
default:
- return;
+ return null;
}
}
/**
* Run the operation callback on the current LDAP connection.
- *
- * @param Closure $operation
- * @return mixed
- *
- * @throws LdapRecordException
*/
- protected function runOperationCallback(Closure $operation)
+ protected function runOperationCallback(Closure $operation): mixed
{
return $operation($this->ldap);
}
/**
* Get a new auth guard instance.
- *
- * @return Auth\Guard
*/
- public function auth()
+ public function auth(): Guard
{
if (! $this->ldap->isConnected()) {
$this->initialize();
@@ -430,7 +366,7 @@ class Connection
$guard = call_user_func($this->authGuardResolver);
$guard->setDispatcher(
- Container::getInstance()->getEventDispatcher()
+ Container::getInstance()->getDispatcher()
);
return $guard;
@@ -438,10 +374,8 @@ class Connection
/**
* Get a new query builder for the connection.
- *
- * @return Query\Builder
*/
- public function query()
+ public function query(): Builder
{
return (new Builder($this))
->setCache($this->cache)
@@ -450,10 +384,8 @@ class Connection
/**
* Determine if the LDAP connection is bound.
- *
- * @return bool
*/
- public function isConnected()
+ public function isConnected(): bool
{
return $this->ldap->isBound();
}
@@ -461,13 +393,9 @@ class Connection
/**
* Attempt to retry an LDAP operation if due to a lost connection.
*
- * @param LdapRecordException $e
- * @param Closure $operation
- * @return mixed
- *
* @throws LdapRecordException
*/
- protected function tryAgainIfCausedByLostConnection(LdapRecordException $e, Closure $operation)
+ protected function tryAgainIfCausedByLostConnection(LdapRecordException $e, Closure $operation): mixed
{
// If the operation failed due to a lost or failed connection,
// we'll attempt reconnecting and running the operation again
@@ -482,12 +410,9 @@ class Connection
/**
* Retry the operation on the current host.
*
- * @param Closure $operation
- * @return mixed
- *
* @throws LdapRecordException
*/
- protected function retry(Closure $operation)
+ protected function retry(Closure $operation): mixed
{
try {
$this->retryingInitialConnection
@@ -503,13 +428,9 @@ class Connection
/**
* Attempt the operation again on the next host.
*
- * @param LdapRecordException $e
- * @param Closure $operation
- * @return mixed
- *
* @throws LdapRecordException
*/
- protected function retryOnNextHost(LdapRecordException $e, Closure $operation)
+ protected function retryOnNextHost(LdapRecordException $e, Closure $operation): mixed
{
$this->attempted[$this->host] = Carbon::now();
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/ConnectionManager.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/ConnectionManager.php
index 0597f1f68..8bef8d150 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/ConnectionManager.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/ConnectionManager.php
@@ -2,7 +2,6 @@
namespace LdapRecord;
-use BadMethodCallException;
use LdapRecord\Events\Dispatcher;
use LdapRecord\Events\DispatcherInterface;
use LdapRecord\Events\Logger;
@@ -10,148 +9,83 @@ use Psr\Log\LoggerInterface;
class ConnectionManager
{
- /**
- * The logger instance.
- *
- * @var LoggerInterface|null
- */
- protected $logger;
-
- /**
- * The event dispatcher instance.
- *
- * @var DispatcherInterface|null
- */
- protected $dispatcher;
-
/**
* The added LDAP connections.
*
* @var Connection[]
*/
- protected $connections = [];
+ protected array $connections = [];
/**
* The name of the default connection.
- *
- * @var string
*/
- protected $default = 'default';
+ protected string $default = 'default';
/**
* The events to register listeners for during initialization.
- *
- * @var array
*/
- protected $listen = [
+ protected array $listen = [
'LdapRecord\Auth\Events\*',
'LdapRecord\Query\Events\*',
'LdapRecord\Models\Events\*',
];
/**
- * The method calls to proxy for compatibility.
- *
- * To be removed in the next major version.
- *
- * @var array
+ * The logger instance.
*/
- protected $proxy = [
- 'reset' => 'flush',
- 'addConnection' => 'add',
- 'getConnection' => 'get',
- 'allConnections' => 'all',
- 'removeConnection' => 'remove',
- 'getDefaultConnection' => 'getDefault',
- 'setDefaultConnection' => 'setDefault',
- 'getEventDispatcher' => 'dispatcher',
- 'setEventDispatcher' => 'setDispatcher',
- ];
+ protected ?LoggerInterface $logger = null;
+
+ /**
+ * The event dispatcher instance.
+ */
+ protected ?DispatcherInterface $dispatcher = null;
/**
* Constructor.
- *
- * @return void
*/
- public function __construct()
+ public function __construct($dispatcher = new Dispatcher)
{
- $this->dispatcher = new Dispatcher();
- }
-
- /**
- * Forward missing method calls onto the instance.
- *
- * @param string $method
- * @param mixed $args
- * @return mixed
- */
- public function __call($method, $args)
- {
- $method = $this->proxy[$method] ?? $method;
-
- if (! method_exists($this, $method)) {
- throw new BadMethodCallException(sprintf(
- 'Call to undefined method %s::%s()',
- static::class,
- $method
- ));
- }
-
- return $this->{$method}(...$args);
+ $this->dispatcher = $dispatcher;
}
/**
* Add a new connection.
- *
- * @param Connection $connection
- * @param string|null $name
- * @return $this
*/
- public function add(Connection $connection, $name = null)
+ public function addConnection(Connection $connection, ?string $name = null): void
{
$this->connections[$name ?? $this->default] = $connection;
if ($this->dispatcher) {
$connection->setDispatcher($this->dispatcher);
}
-
- return $this;
}
/**
- * Remove a connection.
- *
- * @param $name
- * @return $this
+ * Remove a connection by its name.
*/
- public function remove($name)
+ public function removeConnection(string $name): void
{
unset($this->connections[$name]);
-
- return $this;
}
/**
- * Get all of the connections.
+ * Get all the registered connections.
*
* @return Connection[]
*/
- public function all()
+ public function getConnections(): array
{
return $this->connections;
}
/**
- * Get a connection by name or return the default.
- *
- * @param string|null $name
- * @return Connection
+ * Get a connection by its name or return the default.
*
* @throws ContainerException If the given connection does not exist.
*/
- public function get($name = null)
+ public function getConnection(?string $name = null): Connection
{
- if ($this->exists($name = $name ?? $this->default)) {
+ if ($this->hasConnection($name = $name ?? $this->default)) {
return $this->connections[$name];
}
@@ -159,82 +93,61 @@ class ConnectionManager
}
/**
- * Return the default connection.
- *
- * @return Connection
+ * Get the default connection.
*/
- public function getDefault()
+ public function getDefaultConnection(): Connection
{
- return $this->get($this->default);
+ return $this->getConnection($this->default);
+ }
+
+ /**
+ * Set the default connection by its name.
+ */
+ public function setDefaultConnection(string $name): void
+ {
+ $this->default = $name;
}
/**
* Get the default connection name.
- *
- * @return string
*/
- public function getDefaultConnectionName()
+ public function getDefaultConnectionName(): string
{
return $this->default;
}
/**
- * Checks if the connection exists.
- *
- * @param string $name
- * @return bool
+ * Determine if a connection exists.
*/
- public function exists($name)
+ public function hasConnection(string $name): bool
{
return array_key_exists($name, $this->connections);
}
- /**
- * Set the default connection name.
- *
- * @param string $name
- * @return $this
- */
- public function setDefault($name = null)
- {
- $this->default = $name;
-
- return $this;
- }
-
/**
* Flush the manager of all instances and connections.
- *
- * @return $this
*/
- public function flush()
+ public function flush(): void
{
$this->logger = null;
$this->connections = [];
- $this->dispatcher = new Dispatcher();
-
- return $this;
+ $this->dispatcher->forgetAll();
}
/**
* Get the logger instance.
- *
- * @return LoggerInterface|null
*/
- public function getLogger()
+ public function getLogger(): ?LoggerInterface
{
return $this->logger;
}
/**
* Set the event logger to use.
- *
- * @param LoggerInterface $logger
- * @return void
*/
- public function setLogger(LoggerInterface $logger)
+ public function setLogger(LoggerInterface $logger): void
{
$this->logger = $logger;
@@ -243,10 +156,8 @@ class ConnectionManager
/**
* Initialize the event logger.
- *
- * @return void
*/
- public function initEventLogger()
+ protected function initEventLogger(): void
{
$logger = $this->newEventLogger();
@@ -261,51 +172,40 @@ class ConnectionManager
/**
* Make a new event logger instance.
- *
- * @return Logger
*/
- protected function newEventLogger()
+ protected function newEventLogger(): Logger
{
return new Logger($this->logger);
}
/**
* Unset the logger instance.
- *
- * @return void
*/
- public function unsetLogger()
+ public function unsetLogger(): void
{
$this->logger = null;
}
/**
* Get the event dispatcher.
- *
- * @return DispatcherInterface|null
*/
- public function dispatcher()
+ public function getDispatcher(): ?DispatcherInterface
{
return $this->dispatcher;
}
/**
* Set the event dispatcher.
- *
- * @param DispatcherInterface $dispatcher
- * @return void
*/
- public function setDispatcher(DispatcherInterface $dispatcher)
+ public function setDispatcher(DispatcherInterface $dispatcher): void
{
$this->dispatcher = $dispatcher;
}
/**
* Unset the event dispatcher.
- *
- * @return void
*/
- public function unsetEventDispatcher()
+ public function unsetDispatcher(): void
{
$this->dispatcher = null;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Container.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Container.php
index 0c125593d..5a3bd7f4c 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Container.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Container.php
@@ -2,122 +2,79 @@
namespace LdapRecord;
-/**
- * @method static $this reset()
- * @method static Connection[] all()
- * @method static Connection[] allConnections()
- * @method static Connection getDefaultConnection()
- * @method static Connection get(string|null $name = null)
- * @method static Connection getConnection(string|null $name = null)
- * @method static bool exists(string $name)
- * @method static $this remove(string|null $name = null)
- * @method static $this removeConnection(string|null $name = null)
- * @method static $this setDefault(string|null $name = null)
- * @method static $this setDefaultConnection(string|null $name = null)
- * @method static $this add(Connection $connection, string|null $name = null)
- * @method static $this addConnection(Connection $connection, string|null $name = null)
- */
+/** @mixin ConnectionManager */
class Container
{
/**
* The current container instance.
- *
- * @var Container
*/
- protected static $instance;
+ protected static Container $instance;
/**
* The connection manager instance.
- *
- * @var ConnectionManager
*/
- protected $manager;
-
- /**
- * The methods to passthru, for compatibility.
- *
- * @var array
- */
- protected $passthru = [
- 'reset', 'flush',
- 'add', 'addConnection',
- 'remove', 'removeConnection',
- 'setDefault', 'setDefaultConnection',
- ];
-
- /**
- * Forward missing static calls onto the current instance.
- *
- * @param string $method
- * @param mixed $args
- * @return mixed
- */
- public static function __callStatic($method, $args)
- {
- return static::getInstance()->{$method}(...$args);
- }
+ protected ConnectionManager $manager;
/**
* Get or set the current instance of the container.
- *
- * @return Container
*/
- public static function getInstance()
+ public static function getInstance(): static
{
return static::$instance ?? static::getNewInstance();
}
/**
* Set the container instance.
- *
- * @param Container|null $container
- * @return Container|null
*/
- public static function setInstance(self $container = null)
+ public static function setInstance(?self $container = null): ?static
{
return static::$instance = $container;
}
/**
* Set and get a new instance of the container.
- *
- * @return Container
*/
- public static function getNewInstance()
+ public static function getNewInstance(): static
{
- return static::setInstance(new static());
+ return static::setInstance(new static);
+ }
+
+ /**
+ * Forward missing static calls onto the current instance.
+ */
+ public static function __callStatic(string $method, array $parameters): mixed
+ {
+ return static::getInstance()->{$method}(...$parameters);
}
/**
* Constructor.
- *
- * @return void
*/
- public function __construct()
+ public function __construct(ConnectionManager $manager = new ConnectionManager)
{
- $this->manager = new ConnectionManager();
+ $this->manager = $manager;
}
/**
* Forward missing method calls onto the connection manager.
- *
- * @param string $method
- * @param mixed $args
- * @return mixed
*/
- public function __call($method, $args)
+ public function __call(string $method, array $parameters): mixed
{
- $value = $this->manager->{$method}(...$args);
+ return $this->manager->{$method}(...$parameters);
+ }
- return in_array($method, $this->passthru) ? $this : $value;
+ /**
+ * Set the current container instance available globally.
+ */
+ public function setAsGlobal(): void
+ {
+ static::setInstance($this);
}
/**
* Get the connection manager.
- *
- * @return ConnectionManager
*/
- public function manager()
+ public function getConnectionManager(): ConnectionManager
{
return $this->manager;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetailedError.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetailedError.php
index fff528c98..e9d9609dc 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetailedError.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetailedError.php
@@ -4,67 +4,35 @@ namespace LdapRecord;
class DetailedError
{
- /**
- * The error code from ldap_errno.
- *
- * @var int|null
- */
- protected $errorCode;
-
- /**
- * The error message from ldap_error.
- *
- * @var string|null
- */
- protected $errorMessage;
-
- /**
- * The diagnostic message when retrieved after an ldap_error.
- *
- * @var string|null
- */
- protected $diagnosticMessage;
-
/**
* Constructor.
- *
- * @param int $errorCode
- * @param string $errorMessage
- * @param string $diagnosticMessage
*/
- public function __construct($errorCode, $errorMessage, $diagnosticMessage)
- {
- $this->errorCode = $errorCode;
- $this->errorMessage = $errorMessage;
- $this->diagnosticMessage = $diagnosticMessage;
- }
+ public function __construct(
+ protected int $errorCode,
+ protected string $errorMessage,
+ protected ?string $diagnosticMessage
+ ) {}
/**
- * Returns the LDAP error code.
- *
- * @return int
+ * Get the LDAP error code.
*/
- public function getErrorCode()
+ public function getErrorCode(): int
{
return $this->errorCode;
}
/**
- * Returns the LDAP error message.
- *
- * @return string
+ * Get the LDAP error message.
*/
- public function getErrorMessage()
+ public function getErrorMessage(): string
{
return $this->errorMessage;
}
/**
- * Returns the LDAP diagnostic message.
- *
- * @return string
+ * Get the LDAP diagnostic message.
*/
- public function getDiagnosticMessage()
+ public function getDiagnosticMessage(): ?string
{
return $this->diagnosticMessage;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetectsErrors.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetectsErrors.php
index 61fc4a02e..bb6f675f0 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetectsErrors.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/DetectsErrors.php
@@ -6,59 +6,43 @@ trait DetectsErrors
{
/**
* Determine if the error was caused by a lost connection.
- *
- * @param string $error
- * @return bool
*/
- protected function causedByLostConnection($error)
+ protected function causedByLostConnection(string $error): bool
{
return $this->errorContainsMessage($error, ["Can't contact LDAP server", 'Operations error']);
}
/**
* Determine if the error was caused by lack of pagination support.
- *
- * @param string $error
- * @return bool
*/
- protected function causedByPaginationSupport($error)
+ protected function causedByPaginationSupport(string $error): bool
{
return $this->errorContainsMessage($error, 'No server controls in result');
}
/**
* Determine if the error was caused by a size limit warning.
- *
- * @param $error
- * @return bool
*/
- protected function causedBySizeLimit($error)
+ protected function causedBySizeLimit(string $error): bool
{
return $this->errorContainsMessage($error, ['Partial search results returned', 'Size limit exceeded']);
}
/**
* Determine if the error was caused by a "No such object" warning.
- *
- * @param string $error
- * @return bool
*/
- protected function causedByNoSuchObject($error)
+ protected function causedByNoSuchObject(string $error): bool
{
return $this->errorContainsMessage($error, ['No such object']);
}
/**
- * Determine if the error contains the any of the messages.
- *
- * @param string $error
- * @param string|array $messages
- * @return bool
+ * Determine if the error contains any of the messages.
*/
- protected function errorContainsMessage($error, $messages = [])
+ protected function errorContainsMessage(string $error, string|array $messages = []): bool
{
foreach ((array) $messages as $message) {
- if (str_contains((string) $error, $message)) {
+ if (str_contains($error, $message)) {
return true;
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/EscapesValues.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/EscapesValues.php
index ea53a2f93..088b50013 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/EscapesValues.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/EscapesValues.php
@@ -8,13 +8,8 @@ trait EscapesValues
{
/**
* Prepare a value to be escaped.
- *
- * @param string $value
- * @param string $ignore
- * @param int $flags
- * @return EscapedValue
*/
- public function escape($value, $ignore = '', $flags = 0)
+ public function escape(mixed $value = null, string $ignore = '', int $flags = 0): EscapedValue
{
return new EscapedValue($value, $ignore, $flags);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/ConnectionEvent.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/ConnectionEvent.php
index d2d77e2fc..99a6e6f1c 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/ConnectionEvent.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/ConnectionEvent.php
@@ -8,15 +8,11 @@ abstract class ConnectionEvent
{
/**
* The LDAP connection.
- *
- * @var Connection
*/
- protected $connection;
+ protected Connection $connection;
/**
* Constructor.
- *
- * @param Connection $connection
*/
public function __construct(Connection $connection)
{
@@ -25,10 +21,8 @@ abstract class ConnectionEvent
/**
* Get the connection pertaining to the event.
- *
- * @return Connection
*/
- public function getConnection()
+ public function getConnection(): Connection
{
return $this->connection;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Dispatcher.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Dispatcher.php
index 4fedbc2ef..304e15ccd 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Dispatcher.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Dispatcher.php
@@ -2,7 +2,9 @@
namespace LdapRecord\Events;
+use Closure;
use LdapRecord\Support\Arr;
+use LdapRecord\Support\Str;
/**
* Class Dispatcher.
@@ -21,29 +23,23 @@ class Dispatcher implements DispatcherInterface
{
/**
* The registered event listeners.
- *
- * @var array
*/
- protected $listeners = [];
+ protected array $listeners = [];
/**
* The wildcard listeners.
- *
- * @var array
*/
- protected $wildcards = [];
+ protected array $wildcards = [];
/**
* The cached wildcard listeners.
- *
- * @var array
*/
- protected $wildcardsCache = [];
+ protected array $wildcardsCache = [];
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function listen($events, $listener)
+ public function listen(string|array $events, mixed $listener): void
{
foreach ((array) $events as $event) {
if (str_contains((string) $event, '*')) {
@@ -56,12 +52,8 @@ class Dispatcher implements DispatcherInterface
/**
* Setup a wildcard listener callback.
- *
- * @param string $event
- * @param mixed $listener
- * @return void
*/
- protected function setupWildcardListen($event, $listener)
+ protected function setupWildcardListen(string $event, mixed $listener): void
{
$this->wildcards[$event][] = $this->makeListener($listener, true);
@@ -69,33 +61,33 @@ class Dispatcher implements DispatcherInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function hasListeners($eventName)
+ public function hasListeners(string $event): bool
{
- return isset($this->listeners[$eventName]) || isset($this->wildcards[$eventName]);
+ return isset($this->listeners[$event]) || isset($this->wildcards[$event]);
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function until($event, $payload = [])
+ public function until(string|object $event, mixed $payload = []): mixed
{
return $this->dispatch($event, $payload, true);
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function fire($event, $payload = [], $halt = false)
+ public function fire(string|object $event, mixed $payload = [], bool $halt = false): void
{
- return $this->dispatch($event, $payload, $halt);
+ $this->dispatch($event, $payload, $halt);
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function dispatch($event, $payload = [], $halt = false)
+ public function dispatch(string|object $event, mixed $payload = [], $halt = false): mixed
{
// When the given "event" is actually an object we will assume it is an event
// object and use the class as the event name and this event itself as the
@@ -132,12 +124,8 @@ class Dispatcher implements DispatcherInterface
/**
* Parse the given event and payload and prepare them for dispatching.
- *
- * @param mixed $event
- * @param mixed $payload
- * @return array
*/
- protected function parseEventAndPayload($event, $payload)
+ protected function parseEventAndPayload(string|object $event, mixed $payload): array
{
if (is_object($event)) {
[$payload, $event] = [[$event], get_class($event)];
@@ -147,89 +135,42 @@ class Dispatcher implements DispatcherInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getListeners($eventName)
+ public function getListeners(string $event): array
{
- $listeners = $this->listeners[$eventName] ?? [];
+ $listeners = $this->listeners[$event] ?? [];
$listeners = array_merge(
$listeners,
- $this->wildcardsCache[$eventName] ?? $this->getWildcardListeners($eventName)
+ $this->wildcardsCache[$event] ?? $this->getWildcardListeners($event)
);
- return class_exists($eventName, false)
- ? $this->addInterfaceListeners($eventName, $listeners)
+ return class_exists($event, false)
+ ? $this->addInterfaceListeners($event, $listeners)
: $listeners;
}
/**
* Get the wildcard listeners for the event.
- *
- * @param string $eventName
- * @return array
*/
- protected function getWildcardListeners($eventName)
+ protected function getWildcardListeners(string $event): array
{
$wildcards = [];
foreach ($this->wildcards as $key => $listeners) {
- if ($this->wildcardContainsEvent($key, $eventName)) {
+ if (Str::is($key, $event)) {
$wildcards = array_merge($wildcards, $listeners);
}
}
- return $this->wildcardsCache[$eventName] = $wildcards;
- }
-
- /**
- * Determine if the wildcard matches or contains the given event.
- *
- * This function is a direct excerpt from Laravel's Str::is().
- *
- * @param string $wildcard
- * @param string $eventName
- * @return bool
- */
- protected function wildcardContainsEvent($wildcard, $eventName)
- {
- $patterns = Arr::wrap($wildcard);
-
- if (empty($patterns)) {
- return false;
- }
-
- foreach ($patterns as $pattern) {
- // If the given event is an exact match we can of course return true right
- // from the beginning. Otherwise, we will translate asterisks and do an
- // actual pattern match against the two strings to see if they match.
- if ($pattern == $eventName) {
- return true;
- }
-
- $pattern = preg_quote($pattern, '#');
-
- // Asterisks are translated into zero-or-more regular expression wildcards
- // to make it convenient to check if the strings starts with the given
- // pattern such as "library/*", making any string check convenient.
- $pattern = str_replace('\*', '.*', $pattern);
-
- if (preg_match('#^'.$pattern.'\z#u', $eventName) === 1) {
- return true;
- }
- }
-
- return false;
+ return $this->wildcardsCache[$event] = $wildcards;
}
/**
* Add the listeners for the event's interfaces to the given array.
- *
- * @param string $eventName
- * @param array $listeners
- * @return array
*/
- protected function addInterfaceListeners($eventName, array $listeners = [])
+ protected function addInterfaceListeners(string $eventName, array $listeners = []): array
{
foreach (class_implements($eventName) as $interface) {
if (isset($this->listeners[$interface])) {
@@ -244,12 +185,8 @@ class Dispatcher implements DispatcherInterface
/**
* Register an event listener with the dispatcher.
- *
- * @param \Closure|string $listener
- * @param bool $wildcard
- * @return \Closure
*/
- public function makeListener($listener, $wildcard = false)
+ public function makeListener(Closure|string $listener, bool $wildcard = false): Closure
{
if (is_string($listener)) {
return $this->createClassListener($listener, $wildcard);
@@ -266,12 +203,8 @@ class Dispatcher implements DispatcherInterface
/**
* Create a class based listener.
- *
- * @param string $listener
- * @param bool $wildcard
- * @return \Closure
*/
- protected function createClassListener($listener, $wildcard = false)
+ protected function createClassListener(string $listener, bool $wildcard = false): Closure
{
return function ($event, $payload) use ($listener, $wildcard) {
if ($wildcard) {
@@ -287,39 +220,53 @@ class Dispatcher implements DispatcherInterface
/**
* Create the class based event callable.
- *
- * @param string $listener
- * @return callable
*/
- protected function createClassCallable($listener)
+ protected function createClassCallable(string $listener): callable
{
[$class, $method] = $this->parseListenerCallback($listener);
- return [new $class(), $method];
+ return [new $class, $method];
}
/**
* Parse the class listener into class and method.
- *
- * @param string $listener
- * @return array
*/
- protected function parseListenerCallback($listener)
+ protected function parseListenerCallback(string $listener): array
{
- return str_contains((string) $listener, '@')
+ return str_contains($listener, '@')
? explode('@', $listener, 2)
: [$listener, 'handle'];
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function forget($event)
+ public function forget(string $event): void
{
- if (str_contains((string) $event, '*')) {
+ if (str_contains($event, '*')) {
unset($this->wildcards[$event]);
} else {
unset($this->listeners[$event]);
}
+
+ foreach ($this->wildcardsCache as $key => $listeners) {
+ if (Str::is($event, $key)) {
+ unset($this->wildcardsCache[$key]);
+ }
+ }
+ }
+
+ /**
+ * Remove all the listeners from the dispatcher.
+ */
+ public function forgetAll(): void
+ {
+ $listeners = array_merge(
+ $this->listeners, $this->wildcards
+ );
+
+ foreach (array_keys($listeners) as $listener) {
+ $this->forget($listener);
+ }
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/DispatcherInterface.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/DispatcherInterface.php
index 590328f09..71de892c0 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/DispatcherInterface.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/DispatcherInterface.php
@@ -6,63 +6,41 @@ interface DispatcherInterface
{
/**
* Register an event listener with the dispatcher.
- *
- * @param string|array $events
- * @param mixed $listener
- * @return void
*/
- public function listen($events, $listener);
+ public function listen(string|array $events, mixed $listener): void;
/**
* Determine if a given event has listeners.
- *
- * @param string $eventName
- * @return bool
*/
- public function hasListeners($eventName);
+ public function hasListeners(string $event): bool;
/**
* Fire an event until the first non-null response is returned.
- *
- * @param string|object $event
- * @param mixed $payload
- * @return array|null
*/
- public function until($event, $payload = []);
+ public function until(string|object $event, mixed $payload = []): mixed;
/**
* Fire an event and call the listeners.
- *
- * @param string|object $event
- * @param mixed $payload
- * @param bool $halt
- * @return mixed
*/
- public function fire($event, $payload = [], $halt = false);
+ public function fire(string|object $event, mixed $payload = [], bool $halt = false): void;
/**
* Fire an event and call the listeners.
- *
- * @param string|object $event
- * @param mixed $payload
- * @param bool $halt
- * @return array|null
*/
- public function dispatch($event, $payload = [], $halt = false);
+ public function dispatch(string|object $event, mixed $payload = [], $halt = false): mixed;
/**
- * Get all of the listeners for a given event name.
- *
- * @param string $eventName
- * @return array
+ * Get all the listeners for a given event name.
*/
- public function getListeners($eventName);
+ public function getListeners(string $event): array;
/**
* Remove a set of listeners from the dispatcher.
- *
- * @param string $event
- * @return void
*/
- public function forget($event);
+ public function forget(string $event): void;
+
+ /**
+ * Remove all the listeners from the dispatcher.
+ */
+ public function forgetAll(): void;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Logger.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Logger.php
index b8a849169..5ac66f278 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Logger.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/Logger.php
@@ -13,28 +13,21 @@ class Logger
{
/**
* The logger instance.
- *
- * @var LoggerInterface|null
*/
- protected $logger;
+ protected ?LoggerInterface $logger;
/**
* Constructor.
- *
- * @param LoggerInterface|null $logger
*/
- public function __construct(LoggerInterface $logger = null)
+ public function __construct(?LoggerInterface $logger = null)
{
$this->logger = $logger;
}
/**
* Logs the given event.
- *
- * @param mixed $event
- * @return void
*/
- public function log($event)
+ public function log($event): void
{
switch (true) {
case $event instanceof AuthEvent:
@@ -51,11 +44,8 @@ class Logger
/**
* Logs an authentication event.
- *
- * @param AuthEvent $event
- * @return void
*/
- public function auth(AuthEvent $event)
+ public function auth(AuthEvent $event): void
{
if (isset($this->logger)) {
$connection = $event->getConnection();
@@ -78,11 +68,8 @@ class Logger
/**
* Logs a model event.
- *
- * @param ModelEvent $event
- * @return void
*/
- public function model(ModelEvent $event)
+ public function model(ModelEvent $event): void
{
if (isset($this->logger)) {
$model = $event->getModel();
@@ -102,11 +89,8 @@ class Logger
/**
* Logs a query event.
- *
- * @param QueryEvent $event
- * @return void
*/
- public function query(QueryEvent $event)
+ public function query(QueryEvent $event): void
{
if (isset($this->logger)) {
$query = $event->getQuery();
@@ -127,12 +111,9 @@ class Logger
}
/**
- * Returns the operational name of the given event.
- *
- * @param mixed $event
- * @return string
+ * Get the operational name of the given event.
*/
- protected function getOperationName($event)
+ protected function getOperationName($event): string
{
return (new ReflectionClass($event))->getShortName();
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/NullDispatcher.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/NullDispatcher.php
index 7683d1f80..31f95cb77 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/NullDispatcher.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Events/NullDispatcher.php
@@ -6,15 +6,11 @@ class NullDispatcher implements DispatcherInterface
{
/**
* The underlying dispatcher instance.
- *
- * @var DispatcherInterface
*/
- protected $dispatcher;
+ protected DispatcherInterface $dispatcher;
/**
* Constructor.
- *
- * @param DispatcherInterface $dispatcher
*/
public function __construct(DispatcherInterface $dispatcher)
{
@@ -23,84 +19,62 @@ class NullDispatcher implements DispatcherInterface
/**
* Register an event listener with the dispatcher.
- *
- * @param string|array $events
- * @param mixed $listener
- * @return void
*/
- public function listen($events, $listener)
+ public function listen(string|array $events, mixed $listener): void
{
$this->dispatcher->listen($events, $listener);
}
/**
* Determine if a given event has listeners.
- *
- * @param string $eventName
- * @return bool
*/
- public function hasListeners($eventName)
+ public function hasListeners(string $event): bool
{
- return $this->dispatcher->hasListeners($eventName);
+ return $this->dispatcher->hasListeners($event);
}
/**
* Fire an event until the first non-null response is returned.
- *
- * @param string|object $event
- * @param mixed $payload
- * @return null
*/
- public function until($event, $payload = [])
+ public function until(string|object $event, mixed $payload = []): ?array
{
return null;
}
/**
* Fire an event and call the listeners.
- *
- * @param string|object $event
- * @param mixed $payload
- * @param bool $halt
- * @return null
*/
- public function fire($event, $payload = [], $halt = false)
- {
- return null;
- }
+ public function fire(string|object $event, mixed $payload = [], bool $halt = false): void {}
/**
* Fire an event and call the listeners.
- *
- * @param string|object $event
- * @param mixed $payload
- * @param bool $halt
- * @return null
*/
- public function dispatch($event, $payload = [], $halt = false)
+ public function dispatch(string|object $event, mixed $payload = [], $halt = false): mixed
{
return null;
}
/**
- * Get all of the listeners for a given event name.
- *
- * @param string $eventName
- * @return array
+ * Get all the listeners for a given event name.
*/
- public function getListeners($eventName)
+ public function getListeners(string $event): array
{
- return $this->dispatcher->getListeners($eventName);
+ return $this->dispatcher->getListeners($event);
}
/**
* Remove a set of listeners from the dispatcher.
- *
- * @param string $event
- * @return void
*/
- public function forget($event)
+ public function forget(string $event): void
{
$this->dispatcher->forget($event);
}
+
+ /**
+ * Remove all the listeners from the dispatcher.
+ */
+ public function forgetAll(): void
+ {
+ $this->dispatcher->forgetAll();
+ }
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Exceptions/ConstraintViolationException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Exceptions/ConstraintViolationException.php
index 641843a9b..b5d30a739 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Exceptions/ConstraintViolationException.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Exceptions/ConstraintViolationException.php
@@ -11,25 +11,17 @@ class ConstraintViolationException extends LdapRecordException
/**
* Determine if the exception was generated due to the password policy.
- *
- * @return bool
*/
- public function causedByPasswordPolicy()
+ public function causedByPasswordPolicy(): bool
{
- return isset($this->detailedError)
- ? $this->errorContainsMessage($this->detailedError->getDiagnosticMessage(), '0000052D')
- : false;
+ return isset($this->detailedError) && $this->errorContainsMessage($this->detailedError->getDiagnosticMessage(), '0000052D');
}
/**
* Determine if the exception was generated due to an incorrect password.
- *
- * @return bool
*/
- public function causedByIncorrectPassword()
+ public function causedByIncorrectPassword(): bool
{
- return isset($this->detailedError)
- ? $this->errorContainsMessage($this->detailedError->getDiagnosticMessage(), '00000056')
- : false;
+ return isset($this->detailedError) && $this->errorContainsMessage($this->detailedError->getDiagnosticMessage(), '00000056');
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/HandlesConnection.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/HandlesConnection.php
index 4a2e27598..e47904d8b 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/HandlesConnection.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/HandlesConnection.php
@@ -5,88 +5,100 @@ namespace LdapRecord;
use Closure;
use ErrorException;
use Exception;
+use LDAP\Connection;
+/** @mixin Ldap */
trait HandlesConnection
{
/**
* The LDAP host that is currently connected.
- *
- * @var string|null
*/
- protected $host;
+ protected ?string $host = null;
+
+ /**
+ * The LDAP protocol to use (ldap:// or ldaps://).
+ */
+ protected ?string $protocol = null;
/**
* The LDAP connection resource.
*
- * @var resource|null
+ * @var Connection
*/
- protected $connection;
+ protected mixed $connection = null;
/**
- * The bound status of the connection.
- *
- * @var bool
+ * Whether the connection is bound.
*/
- protected $bound = false;
+ protected bool $bound = false;
+
+ /**
+ * Whether the connection is secured over TLS or SSL.
+ */
+ protected bool $secure = false;
/**
* Whether the connection must be bound over SSL.
- *
- * @var bool
*/
- protected $useSSL = false;
+ protected bool $useSSL = false;
/**
* Whether the connection must be bound over TLS.
- *
- * @var bool
*/
- protected $useTLS = false;
+ protected bool $useTLS = false;
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function isUsingSSL()
+ public function isUsingSSL(): bool
{
return $this->useSSL;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function isUsingTLS()
+ public function isUsingTLS(): bool
{
return $this->useTLS;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function isBound()
+ public function isBound(): bool
{
return $this->bound;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function isConnected()
+ public function isSecure(): bool
+ {
+ return $this->secure;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isConnected(): bool
{
return ! is_null($this->connection);
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function canChangePasswords()
+ public function canChangePasswords(): bool
{
return $this->isUsingSSL() || $this->isUsingTLS();
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function ssl($enabled = true)
+ public function ssl(bool $enabled = true): static
{
$this->useSSL = $enabled;
@@ -94,9 +106,9 @@ trait HandlesConnection
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function tls($enabled = true)
+ public function tls(bool $enabled = true): static
{
$this->useTLS = $enabled;
@@ -104,9 +116,9 @@ trait HandlesConnection
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function setOptions(array $options = [])
+ public function setOptions(array $options = []): void
{
foreach ($options as $option => $value) {
$this->setOption($option, $value);
@@ -114,46 +126,57 @@ trait HandlesConnection
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getHost()
+ public function getHost(): ?string
{
return $this->host;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getConnection()
+ public function getConnection(): ?Connection
{
return $this->connection;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getProtocol()
+ public function getProtocol(): string
{
- return $this->isUsingSSL() ? LdapInterface::PROTOCOL_SSL : LdapInterface::PROTOCOL;
+ return $this->protocol ?: (
+ $this->isUsingSSL()
+ ? LdapInterface::PROTOCOL_SSL
+ : LdapInterface::PROTOCOL
+ );
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getExtendedError()
+ public function getExtendedError(): ?string
{
return $this->getDiagnosticMessage();
}
+ /**
+ * Handle the bind response.
+ */
+ protected function handleBindResponse(LdapResultResponse $response): void
+ {
+ $this->bound = $response->successful();
+
+ $this->secure = $this->secure ?: $this->bound && $this->isUsingSSL();
+ }
+
/**
* Convert warnings to exceptions for the given operation.
*
- * @param Closure $operation
- * @return mixed
- *
* @throws LdapRecordException
*/
- protected function executeFailableOperation(Closure $operation)
+ protected function executeFailableOperation(Closure $operation): mixed
{
// If some older versions of PHP, errors are reported instead of throwing
// exceptions, which could be a significant detriment to our application.
@@ -172,8 +195,8 @@ trait HandlesConnection
}
// If the failed query operation was a based on a query being executed
- // -- such as a search, read, or listing, then we can safely return
- // the failed response here and prevent throwning an exception.
+ // -- such as a search, read, or list, then we can safely return
+ // the failed response here and prevent throwing an exception.
if ($this->shouldBypassFailure($method = debug_backtrace()[1]['function'])) {
return $result;
}
@@ -188,46 +211,24 @@ trait HandlesConnection
/**
* Determine if the failed operation should be bypassed.
- *
- * @param string $method
- * @return bool
*/
- protected function shouldBypassFailure($method)
+ protected function shouldBypassFailure(string $method): bool
{
- return in_array($method, ['search', 'read', 'listing']);
+ return in_array($method, ['search', 'read', 'list']);
}
/**
* Determine if the error should be bypassed.
- *
- * @param string $error
- * @return bool
*/
- protected function shouldBypassError($error)
+ protected function shouldBypassError(string $error): bool
{
return $this->causedByPaginationSupport($error) || $this->causedBySizeLimit($error) || $this->causedByNoSuchObject($error);
}
- /**
- * Determine if the current PHP version supports server controls.
- *
- * @deprecated since v2.5.0
- *
- * @return bool
- */
- public function supportsServerControlsInMethods()
- {
- return version_compare(PHP_VERSION, '7.3.0') >= 0;
- }
-
/**
* Generates an LDAP connection string for each host given.
- *
- * @param string|array $hosts
- * @param string $port
- * @return string
*/
- protected function makeConnectionUris($hosts, $port)
+ protected function makeConnectionUris(array|string $hosts, string|int $port): string
{
// If an attempt to connect via SSL protocol is being performed,
// and we are still using the default port, we will swap it
@@ -244,15 +245,9 @@ trait HandlesConnection
/**
* Assemble the host URI strings.
- *
- * @param array|string $hosts
- * @param string $port
- * @return array
*/
- protected function assembleHostUris($hosts, $port)
+ protected function assembleHostUris(array|string $hosts, string|int $port): array
{
- return array_map(function ($host) use ($port) {
- return "{$this->getProtocol()}{$host}:{$port}";
- }, (array) $hosts);
+ return array_map(fn ($host) => "{$this->getProtocol()}{$host}:{$port}", (array) $hosts);
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Ldap.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Ldap.php
index 76c372040..7f2be60b6 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Ldap.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Ldap.php
@@ -6,15 +6,16 @@ use LDAP\Connection as RawLdapConnection;
class Ldap implements LdapInterface
{
- use HandlesConnection, DetectsErrors;
+ use DetectsErrors;
+ use HandlesConnection;
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getEntries($searchResults)
+ public function getEntries(mixed $result): array
{
- return $this->executeFailableOperation(function () use ($searchResults) {
- return ldap_get_entries($this->connection, $searchResults);
+ return $this->executeFailableOperation(function () use ($result) {
+ return ldap_get_entries($this->connection, $result);
});
}
@@ -23,13 +24,12 @@ class Ldap implements LdapInterface
*
* @see http://php.net/manual/en/function.ldap-first-entry.php
*
- * @param resource $searchResults
- * @return resource
+ * @param \Ldap\Result $result
*/
- public function getFirstEntry($searchResults)
+ public function getFirstEntry(mixed $result): mixed
{
- return $this->executeFailableOperation(function () use ($searchResults) {
- return ldap_first_entry($this->connection, $searchResults);
+ return $this->executeFailableOperation(function () use ($result) {
+ return ldap_first_entry($this->connection, $result);
});
}
@@ -38,10 +38,9 @@ class Ldap implements LdapInterface
*
* @see http://php.net/manual/en/function.ldap-next-entry.php
*
- * @param resource $entry
- * @return resource
+ * @param \Ldap\ResultEntry $entry
*/
- public function getNextEntry($entry)
+ public function getNextEntry(mixed $entry): mixed
{
return $this->executeFailableOperation(function () use ($entry) {
return ldap_next_entry($this->connection, $entry);
@@ -53,10 +52,9 @@ class Ldap implements LdapInterface
*
* @see http://php.net/manual/en/function.ldap-get-attributes.php
*
- * @param resource $entry
- * @return array|false
+ * @param \Ldap\ResultEntry $entry
*/
- public function getAttributes($entry)
+ public function getAttributes(mixed $entry): array|false
{
return $this->executeFailableOperation(function () use ($entry) {
return ldap_get_attributes($this->connection, $entry);
@@ -64,41 +62,29 @@ class Ldap implements LdapInterface
}
/**
- * Returns the number of entries from a search result.
- *
- * @see http://php.net/manual/en/function.ldap-count-entries.php
- *
- * @param resource $searchResults
- * @return int
+ * {@inheritDoc}
*/
- public function countEntries($searchResults)
+ public function countEntries(mixed $result): int
{
- return $this->executeFailableOperation(function () use ($searchResults) {
- return ldap_count_entries($this->connection, $searchResults);
+ return $this->executeFailableOperation(function () use ($result) {
+ return ldap_count_entries($this->connection, $result);
});
}
/**
- * Compare value of attribute found in entry specified with DN.
- *
- * @see http://php.net/manual/en/function.ldap-compare.php
- *
- * @param string $dn
- * @param string $attribute
- * @param string $value
- * @return mixed
+ * {@inheritDoc}
*/
- public function compare($dn, $attribute, $value)
+ public function compare(string $dn, string $attribute, string $value, ?array $controls = null): bool|int
{
- return $this->executeFailableOperation(function () use ($dn, $attribute, $value) {
- return ldap_compare($this->connection, $dn, $attribute, $value);
+ return $this->executeFailableOperation(function () use ($dn, $attribute, $value, $controls) {
+ return ldap_compare($this->connection, $dn, $attribute, $value, $controls);
});
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getLastError()
+ public function getLastError(): ?string
{
if (! $this->connection) {
return null;
@@ -108,9 +94,9 @@ class Ldap implements LdapInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getDetailedError()
+ public function getDetailedError(): ?DetailedError
{
if (! $number = $this->errNo()) {
return null;
@@ -122,15 +108,9 @@ class Ldap implements LdapInterface
}
/**
- * Get all binary values from the specified result entry.
- *
- * @see http://php.net/manual/en/function.ldap-get-values-len.php
- *
- * @param $entry
- * @param $attribute
- * @return array
+ * {@inheritDoc}
*/
- public function getValuesLen($entry, $attribute)
+ public function getValuesLen(mixed $entry, string $attribute): array|false
{
return $this->executeFailableOperation(function () use ($entry, $attribute) {
return ldap_get_values_len($this->connection, $entry, $attribute);
@@ -138,17 +118,17 @@ class Ldap implements LdapInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function setOption($option, $value)
+ public function setOption(int $option, mixed $value): bool
{
return ldap_set_option($this->connection, $option, $value);
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getOption($option, &$value = null)
+ public function getOption(int $option, mixed &$value = null): mixed
{
ldap_get_option($this->connection, $option, $value);
@@ -159,59 +139,63 @@ class Ldap implements LdapInterface
* Set a callback function to do re-binds on referral chasing.
*
* @see http://php.net/manual/en/function.ldap-set-rebind-proc.php
- *
- * @param callable $callback
- * @return bool
*/
- public function setRebindCallback(callable $callback)
+ public function setRebindCallback(callable $callback): bool
{
return ldap_set_rebind_proc($this->connection, $callback);
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function startTLS()
+ public function startTLS(): bool
{
- return $this->executeFailableOperation(function () {
+ return $this->secure = $this->executeFailableOperation(function () {
return ldap_start_tls($this->connection);
});
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function connect($hosts = [], $port = 389)
+ public function connect(string|array $hosts = [], int $port = 389, ?string $protocol = null): bool
{
$this->bound = false;
-
+ $this->protocol = $protocol;
$this->host = $this->makeConnectionUris($hosts, $port);
- return $this->connection = $this->executeFailableOperation(function () {
+ $this->connection = $this->executeFailableOperation(function () {
return ldap_connect($this->host);
});
+
+ return $this->connection instanceof RawLdapConnection;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function close()
+ public function close(): bool
{
- $result = (is_resource($this->connection) || $this->connection instanceof RawLdapConnection)
- ? @ldap_close($this->connection)
- : false;
+ $result = false;
+
+ if ($this->connection instanceof RawLdapConnection) {
+ $result = @ldap_close($this->connection);
+ }
- $this->connection = null;
$this->bound = false;
+ $this->secure = false;
+
$this->host = null;
+ $this->protocol = null;
+ $this->connection = null;
return $result;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function search($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = [])
+ public function search(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed
{
return $this->executeFailableOperation(function () use (
$dn,
@@ -221,18 +205,16 @@ class Ldap implements LdapInterface
$size,
$time,
$deref,
- $serverControls
+ $controls
) {
- return empty($serverControls)
- ? ldap_search($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref)
- : ldap_search($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $serverControls);
+ return ldap_search($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $controls);
});
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function listing($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = [])
+ public function list(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed
{
return $this->executeFailableOperation(function () use (
$dn,
@@ -242,18 +224,16 @@ class Ldap implements LdapInterface
$size,
$time,
$deref,
- $serverControls
+ $controls
) {
- return empty($serverControls)
- ? ldap_list($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref)
- : ldap_list($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $serverControls);
+ return ldap_list($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $controls);
});
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function read($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = [])
+ public function read(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed
{
return $this->executeFailableOperation(function () use (
$dn,
@@ -263,47 +243,78 @@ class Ldap implements LdapInterface
$size,
$time,
$deref,
- $serverControls
+ $controls
) {
- return empty($serverControls)
- ? ldap_read($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref)
- : ldap_read($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $serverControls);
+ return ldap_read($this->connection, $dn, $filter, $fields, $onlyAttributes, $size, $time, $deref, $controls);
});
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function parseResult($result, &$errorCode, &$dn, &$errorMessage, &$referrals, &$serverControls = [])
+ public function parseResult(mixed $result, int &$errorCode = 0, ?string &$dn = null, ?string &$errorMessage = null, ?array &$referrals = null, ?array &$controls = null): LdapResultResponse|false
{
- return $this->executeFailableOperation(function () use (
- $result,
- &$errorCode,
- &$dn,
- &$errorMessage,
- &$referrals,
- &$serverControls
- ) {
- return empty($serverControls)
- ? ldap_parse_result($this->connection, $result, $errorCode, $dn, $errorMessage, $referrals)
- : ldap_parse_result($this->connection, $result, $errorCode, $dn, $errorMessage, $referrals, $serverControls);
- });
+ if (ldap_parse_result($this->connection, $result, $errorCode, $dn, $errorMessage, $referrals, $controls)) {
+ return new LdapResultResponse(
+ $errorCode,
+ $dn,
+ $errorMessage,
+ $referrals,
+ $controls
+ );
+ }
+
+ return false;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function bind($username, $password)
+ public function bind(?string $dn = null, ?string $password = null, ?array $controls = null): LdapResultResponse
{
- return $this->bound = $this->executeFailableOperation(function () use ($username, $password) {
- return ldap_bind($this->connection, $username, $password ? html_entity_decode($password) : null);
+ /** @var \LDAP\Result $result */
+ $result = $this->executeFailableOperation(function () use ($dn, $password, $controls) {
+ return ldap_bind_ext($this->connection, $dn, $password ? html_entity_decode($password) : null, $controls);
+ });
+
+ $response = $this->parseResult($result);
+
+ $this->handleBindResponse($response);
+
+ return $response;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function saslBind(?string $dn = null, ?string $password = null, array $options = []): bool
+ {
+ return $this->executeFailableOperation(function () use ($dn, $password, $options) {
+ $options = array_merge([
+ 'mech' => null,
+ 'realm' => null,
+ 'authc_id' => null,
+ 'authz_id' => null,
+ 'props' => null,
+ ], $options);
+
+ return $this->bound = ldap_sasl_bind(
+ $this->connection,
+ $dn,
+ $password ? html_entity_decode($password) : null,
+ $options['mech'],
+ $options['realm'],
+ $options['authc_id'],
+ $options['authz_id'],
+ $options['props'],
+ );
});
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function add($dn, array $entry)
+ public function add(string $dn, array $entry): bool
{
return $this->executeFailableOperation(function () use ($dn, $entry) {
return ldap_add($this->connection, $dn, $entry);
@@ -311,9 +322,9 @@ class Ldap implements LdapInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function delete($dn)
+ public function delete(string $dn): bool
{
return $this->executeFailableOperation(function () use ($dn) {
return ldap_delete($this->connection, $dn);
@@ -321,9 +332,9 @@ class Ldap implements LdapInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false)
+ public function rename(string $dn, string $newRdn, string $newParent, bool $deleteOldRdn = false): bool
{
return $this->executeFailableOperation(function () use (
$dn,
@@ -336,9 +347,9 @@ class Ldap implements LdapInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function modify($dn, array $entry)
+ public function modify(string $dn, array $entry): bool
{
return $this->executeFailableOperation(function () use ($dn, $entry) {
return ldap_modify($this->connection, $dn, $entry);
@@ -346,9 +357,9 @@ class Ldap implements LdapInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function modifyBatch($dn, array $values)
+ public function modifyBatch(string $dn, array $values): bool
{
return $this->executeFailableOperation(function () use ($dn, $values) {
return ldap_modify_batch($this->connection, $dn, $values);
@@ -356,9 +367,9 @@ class Ldap implements LdapInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function modAdd($dn, array $entry)
+ public function modAdd(string $dn, array $entry): bool
{
return $this->executeFailableOperation(function () use ($dn, $entry) {
return ldap_mod_add($this->connection, $dn, $entry);
@@ -366,9 +377,9 @@ class Ldap implements LdapInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function modReplace($dn, array $entry)
+ public function modReplace(string $dn, array $entry): bool
{
return $this->executeFailableOperation(function () use ($dn, $entry) {
return ldap_mod_replace($this->connection, $dn, $entry);
@@ -376,9 +387,9 @@ class Ldap implements LdapInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function modDelete($dn, array $entry)
+ public function modDelete(string $dn, array $entry): bool
{
return $this->executeFailableOperation(function () use ($dn, $entry) {
return ldap_mod_del($this->connection, $dn, $entry);
@@ -386,88 +397,63 @@ class Ldap implements LdapInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function controlPagedResult($pageSize = 1000, $isCritical = false, $cookie = '')
- {
- return $this->executeFailableOperation(function () use ($pageSize, $isCritical, $cookie) {
- return ldap_control_paged_result($this->connection, $pageSize, $isCritical, $cookie);
- });
- }
-
- /**
- * @inheritdoc
- */
- public function controlPagedResultResponse($result, &$cookie, &$estimated = null)
- {
- return $this->executeFailableOperation(function () use ($result, &$cookie, &$estimated) {
- return ldap_control_paged_result_response($this->connection, $result, $cookie, $estimated);
- });
- }
-
- /**
- * @inheritdoc
- */
- public function freeResult($result)
+ public function freeResult(mixed $result): bool
{
return ldap_free_result($result);
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function errNo()
+ public function errNo(): ?int
{
return $this->connection ? ldap_errno($this->connection) : null;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function err2Str($number)
+ public function err2Str(int $number): string
{
return ldap_err2str($number);
}
/**
- * Returns the extended error hex code of the last command.
- *
- * @return string|null
+ * Get the extended error hex code of the last command.
*/
- public function getExtendedErrorHex()
+ public function getExtendedErrorHex(): ?string
{
if (preg_match("/(?<=data\s).*?(?=,)/", $this->getExtendedError(), $code)) {
return $code[0];
}
+
+ return null;
}
/**
- * Returns the extended error code of the last command.
- *
- * @return bool|string
+ * Get the extended error code of the last command.
*/
- public function getExtendedErrorCode()
+ public function getExtendedErrorCode(): string|false
{
return $this->extractDiagnosticCode($this->getExtendedError());
}
/**
* Extract the diagnostic code from the message.
- *
- * @param string $message
- * @return string|bool
*/
- public function extractDiagnosticCode($message)
+ public function extractDiagnosticCode(string $message): string|false
{
preg_match('/^([\da-fA-F]+):/', $message, $matches);
- return isset($matches[1]) ? $matches[1] : false;
+ return $matches[1] ?? false;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getDiagnosticMessage()
+ public function getDiagnosticMessage(): ?string
{
$this->getOption(LDAP_OPT_ERROR_STRING, $message);
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapInterface.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapInterface.php
index fcff57f48..735f858ca 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapInterface.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapInterface.php
@@ -2,15 +2,15 @@
namespace LdapRecord;
+use LDAP\Connection;
+
+/**
+ * @see https://ldap.com/ldap-oid-reference-guide
+ * @see http://msdn.microsoft.com/en-us/library/cc223359.aspx
+ * @see https://help.univention.com/t/openldap-debug-level/19301
+ */
interface LdapInterface
{
- /**
- * The SSL LDAP protocol string.
- *
- * @var string
- */
- public const PROTOCOL_SSL = 'ldaps://';
-
/**
* The standard LDAP protocol string.
*
@@ -19,136 +19,370 @@ interface LdapInterface
public const PROTOCOL = 'ldap://';
/**
- * The LDAP SSL port number.
+ * The SSL LDAP protocol string.
*
* @var string
*/
- public const PORT_SSL = 636;
+ public const PROTOCOL_SSL = 'ldaps://';
/**
* The standard LDAP port number.
*
- * @var string
+ * @var int
*/
public const PORT = 389;
/**
- * Various useful server control OID's.
+ * The LDAP SSL port number.
*
- * @see https://ldap.com/ldap-oid-reference-guide/
- * @see http://msdn.microsoft.com/en-us/library/cc223359.aspx
+ * @var int
+ */
+ public const PORT_SSL = 636;
+
+ /**
+ * Print entry and exit from routines.
+ *
+ * @var int
+ */
+ public const DEBUG_TRACE = 1;
+
+ /**
+ * Print packet activity.
+ *
+ * @var int
+ */
+ public const DEBUG_PACKETS = 2;
+
+ /**
+ * Print data arguments from requests.
+ *
+ * @var int
+ */
+ public const DEBUG_ARGS = 4;
+
+ /**
+ * Print connection activity.
+ *
+ * @var int
+ */
+ public const DEBUG_CONNS = 8;
+
+ /**
+ * Print encoding and decoding of data.
+ *
+ * @var int
+ */
+ public const DEBUG_BER = 16;
+
+ /**
+ * Print search filters.
+ *
+ * @var int
+ */
+ public const DEBUG_FILTER = 32;
+
+ /**
+ * Print configuration file processing.
+ *
+ * @var int
+ */
+ public const DEBUG_CONFIG = 64;
+
+ /**
+ * Print Access Control List activities.
+ *
+ * @var int
+ */
+ public const DEBUG_ACL = 128;
+
+ /**
+ * Print operational statistics.
+ *
+ * @var int
+ */
+ public const DEBUG_STATS = 256;
+
+ /**
+ * Print more detailed statistics.
+ *
+ * @var int
+ */
+ public const DEBUG_STATS2 = 512;
+
+ /**
+ * Print communication with shell backends.
+ *
+ * @var int
+ */
+ public const DEBUG_SHELL = 1024;
+
+ /**
+ * Print entry parsing.
+ *
+ * @var int
+ */
+ public const DEBUG_PARSE = 2048;
+
+ /**
+ * Print LDAPSync replication.
+ *
+ * @var int
+ */
+ public const DEBUG_SYNC = 16384;
+
+ /**
+ * Print referral activities.
+ *
+ * @var int
+ */
+ public const DEBUG_REFERRAL = 32768;
+
+ /**
+ * Print error conditions.
+ *
+ * @var int
+ */
+ public const DEBUG_ERROR = 32768;
+
+ /**
+ * Print all levels of debug.
+ *
+ * @var int
+ */
+ public const DEBUG_ANY = 65535;
+
+ /**
+ * OID for StartTLS extended operation. Signals the server to initiate a TLS connection.
+ *
+ * @var string
*/
public const OID_SERVER_START_TLS = '1.3.6.1.4.1.1466.20037';
+
+ /**
+ * OID for Paged Results Control. Used to retrieve search results in pages.
+ *
+ * @var string
+ */
public const OID_SERVER_PAGED_RESULTS = '1.2.840.113556.1.4.319';
+
+ /**
+ * OID for Show Deleted Control. Includes deleted entries in the search results.
+ *
+ * @var string
+ */
public const OID_SERVER_SHOW_DELETED = '1.2.840.113556.1.4.417';
+
+ /**
+ * OID for Server Side Sort Control. Requests the server to sort the search results.
+ *
+ * @var string
+ */
public const OID_SERVER_SORT = '1.2.840.113556.1.4.473';
+
+ /**
+ * OID for Cross-Domain Move Target Control. Used in cross-domain move operations.
+ *
+ * @var string
+ */
public const OID_SERVER_CROSSDOM_MOVE_TARGET = '1.2.840.113556.1.4.521';
+
+ /**
+ * OID for LDAP Notification Control. Used to register for change notifications.
+ *
+ * @var string
+ */
public const OID_SERVER_NOTIFICATION = '1.2.840.113556.1.4.528';
+
+ /**
+ * OID for Extended DN Control. Requests extended DN information in search results.
+ *
+ * @var string
+ */
public const OID_SERVER_EXTENDED_DN = '1.2.840.113556.1.4.529';
+
+ /**
+ * OID for Lazy Commit Control. Delays the actual commit of changes until requested.
+ *
+ * @var string
+ */
public const OID_SERVER_LAZY_COMMIT = '1.2.840.113556.1.4.619';
+
+ /**
+ * OID for Security Descriptor Flags Control. Used to manipulate security descriptor flags.
+ *
+ * @var string
+ */
public const OID_SERVER_SD_FLAGS = '1.2.840.113556.1.4.801';
+
+ /**
+ * OID for Tree Delete Control. Enables the deletion of an entire subtree.
+ *
+ * @var string
+ */
public const OID_SERVER_TREE_DELETE = '1.2.840.113556.1.4.805';
+
+ /**
+ * OID for DirSync Control. Used for directory synchronization operations.
+ *
+ * @var string
+ */
public const OID_SERVER_DIRSYNC = '1.2.840.113556.1.4.841';
+
+ /**
+ * OID for Verify Name Control. Allows verification of an entry without retrieving attributes.
+ *
+ * @var string
+ */
public const OID_SERVER_VERIFY_NAME = '1.2.840.113556.1.4.1338';
+
+ /**
+ * OID for Domain Scope Control. Limits a search to the current domain.
+ *
+ * @var string
+ */
public const OID_SERVER_DOMAIN_SCOPE = '1.2.840.113556.1.4.1339';
+
+ /**
+ * OID for Search Options Control. Used to set various search options.
+ *
+ * @var string
+ */
public const OID_SERVER_SEARCH_OPTIONS = '1.2.840.113556.1.4.1340';
+
+ /**
+ * OID for Permissive Modify Control. Allows modifications even if some attributes are missing.
+ *
+ * @var string
+ */
public const OID_SERVER_PERMISSIVE_MODIFY = '1.2.840.113556.1.4.1413';
+
+ /**
+ * OID for Authentication Service Queries (ASQ) Control. Used to perform ASQ operations.
+ *
+ * @var string
+ */
public const OID_SERVER_ASQ = '1.2.840.113556.1.4.1504';
+
+ /**
+ * OID for Fast Bind Control. Optimizes the bind process for faster authentication.
+ *
+ * @var string
+ */
public const OID_SERVER_FAST_BIND = '1.2.840.113556.1.4.1781';
+
+ /**
+ * OID for Virtual List View (VLV) Request Control. Used to request a specific range of entries.
+ *
+ * @var string
+ */
public const OID_SERVER_CONTROL_VLVREQUEST = '2.16.840.1.113730.3.4.9';
/**
- * Query OID's.
- *
- * @see https://ldapwiki.com/wiki/LDAP_MATCHING_RULE_IN_CHAIN
+ * OID for the 'matchingRuleInChain' matching rule. Used for substring searches in multi-valued attributes.
*/
public const OID_MATCHING_RULE_IN_CHAIN = '1.2.840.113556.1.4.1941';
/**
* Set the current connection to use SSL.
- *
- * @param bool $enabled
- * @return $this
*/
- public function ssl();
+ public function ssl(): static;
/**
* Determine if the current connection instance is using SSL.
- *
- * @return bool
*/
- public function isUsingSSL();
+ public function isUsingSSL(): bool;
/**
* Set the current connection to use TLS.
- *
- * @param bool $enabled
- * @return $this
*/
- public function tls();
+ public function tls(): static;
/**
* Determine if the current connection instance is using TLS.
- *
- * @return bool
*/
- public function isUsingTLS();
+ public function isUsingTLS(): bool;
/**
* Determine if the connection is bound.
- *
- * @return bool
*/
- public function isBound();
+ public function isBound(): bool;
+
+ /**
+ * Determine if the connection is secure over TLS or SSL.
+ */
+ public function isSecure(): bool;
/**
* Determine if the connection has been created.
- *
- * @return bool
*/
- public function isConnected();
+ public function isConnected(): bool;
/**
* Determine the connection is able to modify passwords.
- *
- * @return bool
*/
- public function canChangePasswords();
+ public function canChangePasswords(): bool;
/**
- * Returns the full LDAP host URL.
+ * Get the full LDAP host URL.
*
* Ex: ldap://192.168.1.1:386
- *
- * @return string|null
*/
- public function getHost();
+ public function getHost(): ?string;
/**
- * Get the underlying connection resource.
- *
- * @return resource|null
+ * Get the underlying raw LDAP connection.
*/
- public function getConnection();
+ public function getConnection(): ?Connection;
/**
* Retrieve the entries from a search result.
*
* @see http://php.net/manual/en/function.ldap-get-entries.php
*
- * @param resource $searchResults
- * @return array
+ * @param \LDAP\Result $result
*/
- public function getEntries($searchResults);
+ public function getEntries(mixed $result): array;
+
+ /**
+ * Get the entry identifier for first entry in the result.
+ *
+ * @see https://www.php.net/manual/en/function.ldap-first-entry.php
+ *
+ * @param \LDAP\Result $result
+ */
+ public function getFirstEntry(mixed $result): mixed;
+
+ /**
+ * Retrieve the next result entry.
+ *
+ * @see https://www.php.net/manual/en/function.ldap-next-entry.php
+ *
+ * @param \LDAP\Result $entry
+ */
+ public function getNextEntry(mixed $entry): mixed;
+
+ /**
+ * Reads attributes and values from an entry in the search result.
+ *
+ * @see https://www.php.net/manual/en/function.ldap-get-attributes.php
+ *
+ * @param \LDAP\Result $entry
+ */
+ public function getAttributes(mixed $entry): array|false;
+
+ /**
+ * Reads all the values of the attribute in the entry in the result.
+ *
+ * @param \LDAP\Result $entry
+ */
+ public function getValuesLen(mixed $entry, string $attribute): array|false;
/**
* Retrieve the last error on the current connection.
*
* @see http://php.net/manual/en/function.ldap-error.php
- *
- * @return string|null
*/
- public function getLastError();
+ public function getLastError(): ?string;
/**
* Return detailed information about an error.
@@ -156,62 +390,64 @@ interface LdapInterface
* Returns null when there was a successful last request.
*
* Returns DetailedError when there was an error.
- *
- * @return DetailedError|null
*/
- public function getDetailedError();
+ public function getDetailedError(): ?DetailedError;
+
+ /**
+ * Count the number of entries in a search.
+ *
+ * @see https://www.php.net/manual/en/function.ldap-count-entries.php
+ *
+ * @param \LDAP\Result $result
+ */
+ public function countEntries(mixed $result): int;
+
+ /**
+ * Compare value of attribute found in entry specified with DN.
+ */
+ public function compare(string $dn, string $attribute, string $value, ?array $controls = null): bool|int;
/**
* Set an option on the current connection.
*
* @see http://php.net/manual/en/function.ldap-set-option.php
- *
- * @param int $option
- * @param mixed $value
- * @return bool
*/
- public function setOption($option, $value);
+ public function setOption(int $option, mixed $value): bool;
/**
- * Set options on the current connection.
- *
- * @param array $options
- * @return void
+ * Set multiple options on the current connection.
*/
- public function setOptions(array $options = []);
+ public function setOptions(array $options = []): void;
+
+ /**
+ * Set a callback function to do re-binds on referral chasing.
+ *
+ * @see https://www.php.net/manual/en/function.ldap-set-rebind-proc.php
+ */
+ public function setRebindCallback(callable $callback): bool;
/**
* Get the value for the LDAP option.
*
* @see https://www.php.net/manual/en/function.ldap-get-option.php
- *
- * @param int $option
- * @param mixed $value
- * @return mixed
*/
- public function getOption($option, &$value = null);
+ public function getOption(int $option, mixed &$value = null): mixed;
/**
* Starts a connection using TLS.
*
* @see http://php.net/manual/en/function.ldap-start-tls.php
*
- * @return bool
- *
* @throws LdapRecordException
*/
- public function startTLS();
+ public function startTLS(): bool;
/**
* Connects to the specified hostname using the specified port.
*
* @see http://php.net/manual/en/function.ldap-start-tls.php
- *
- * @param string|array $hosts
- * @param int $port
- * @return resource|false
*/
- public function connect($hosts = [], $port = 389);
+ public function connect(string|array $hosts = [], int $port = 389, ?string $protocol = null): bool;
/**
* Closes the current connection.
@@ -219,275 +455,176 @@ interface LdapInterface
* Returns false if no connection is present.
*
* @see http://php.net/manual/en/function.ldap-close.php
- *
- * @return bool
*/
- public function close();
+ public function close(): bool;
/**
* Performs a search on the current connection.
*
* @see http://php.net/manual/en/function.ldap-search.php
*
- * @param string $dn
- * @param string $filter
- * @param array $fields
- * @param bool $onlyAttributes
- * @param int $size
- * @param int $time
- * @param int $deref
- * @param array $serverControls
- * @return resource
+ * @return \LDAP\Result
*/
- public function search($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []);
+ public function search(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
/**
* Performs a single level search on the current connection.
*
* @see http://php.net/manual/en/function.ldap-list.php
*
- * @param string $dn
- * @param string $filter
- * @param array $fields
- * @param bool $onlyAttributes
- * @param int $size
- * @param int $time
- * @param int $deref
- * @param array $serverControls
- * @return resource
+ * @return \LDAP\Result
*/
- public function listing($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []);
+ public function list(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
/**
* Reads an entry on the current connection.
*
* @see http://php.net/manual/en/function.ldap-read.php
*
- * @param string $dn
- * @param string $filter
- * @param array $fields
- * @param bool $onlyAttributes
- * @param int $size
- * @param int $time
- * @param int $deref
- * @param array $serverControls
- * @return resource
+ * @return \LDAP\Result
*/
- public function read($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = []);
+ public function read(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed;
/**
* Extract information from an LDAP result.
*
* @see https://www.php.net/manual/en/function.ldap-parse-result.php
*
- * @param resource $result
- * @param int $errorCode
- * @param ?string $dn
- * @param ?string $errorMessage
- * @param ?array $referrals
- * @param ?array $serverControls
- * @return bool
+ * @param \LDAP\Result $result
*/
- public function parseResult($result, &$errorCode, &$dn, &$errorMessage, &$referrals, &$serverControls = []);
+ public function parseResult(mixed $result, int &$errorCode = 0, ?string &$dn = null, ?string &$errorMessage = null, ?array &$referrals = null, ?array &$controls = null): LdapResultResponse|false;
/**
- * Binds to the current connection using the specified username and password.
- * If sasl is true, the current connection is bound using SASL.
+ * Bind to the LDAP directory.
*
* @see http://php.net/manual/en/function.ldap-bind.php
*
- * @param string $username
- * @param string $password
- * @return bool
- *
* @throws LdapRecordException
*/
- public function bind($username, $password);
+ public function bind(?string $dn = null, ?string $password = null, ?array $controls = null): LdapResultResponse;
+
+ /**
+ * Bind to the LDAP directory using SASL.
+ *
+ * SASL options:
+ * - mech: Mechanism (Defaults: null)
+ * - realm: Realm (Defaults: null)
+ * - authc_id: Verification Identity (Defaults: null)
+ * - authz_id: Authorization Identity (Defaults: null)
+ * - props: Options for Authorization Identity (Defaults: null)
+ *
+ * @see https://php.net/manual/en/function.ldap-sasl-bind.php
+ * @see https://www.iana.org/assignments/sasl-mechanisms/sasl-mechanisms.xhtml
+ */
+ public function saslBind(?string $dn = null, ?string $password = null, array $options = []): bool;
/**
* Adds an entry to the current connection.
*
* @see http://php.net/manual/en/function.ldap-add.php
*
- * @param string $dn
- * @param array $entry
- * @return bool
- *
* @throws LdapRecordException
*/
- public function add($dn, array $entry);
+ public function add(string $dn, array $entry): bool;
/**
* Deletes an entry on the current connection.
*
* @see http://php.net/manual/en/function.ldap-delete.php
*
- * @param string $dn
- * @return bool
- *
* @throws LdapRecordException
*/
- public function delete($dn);
+ public function delete(string $dn): bool;
/**
* Modify the name of an entry on the current connection.
*
* @see http://php.net/manual/en/function.ldap-rename.php
*
- * @param string $dn
- * @param string $newRdn
- * @param string $newParent
- * @param bool $deleteOldRdn
- * @return bool
- *
* @throws LdapRecordException
*/
- public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false);
+ public function rename(string $dn, string $newRdn, string $newParent, bool $deleteOldRdn = false): bool;
/**
* Modifies an existing entry on the current connection.
*
* @see http://php.net/manual/en/function.ldap-modify.php
*
- * @param string $dn
- * @param array $entry
- * @return bool
- *
* @throws LdapRecordException
*/
- public function modify($dn, array $entry);
+ public function modify(string $dn, array $entry): bool;
/**
* Batch modifies an existing entry on the current connection.
*
* @see http://php.net/manual/en/function.ldap-modify-batch.php
*
- * @param string $dn
- * @param array $values
- * @return bool
- *
* @throws LdapRecordException
*/
- public function modifyBatch($dn, array $values);
+ public function modifyBatch(string $dn, array $values): bool;
/**
* Add attribute values to current attributes.
*
* @see http://php.net/manual/en/function.ldap-mod-add.php
*
- * @param string $dn
- * @param array $entry
- * @return bool
- *
* @throws LdapRecordException
*/
- public function modAdd($dn, array $entry);
+ public function modAdd(string $dn, array $entry): bool;
/**
* Replaces attribute values with new ones.
*
* @see http://php.net/manual/en/function.ldap-mod-replace.php
*
- * @param string $dn
- * @param array $entry
- * @return bool
- *
* @throws LdapRecordException
*/
- public function modReplace($dn, array $entry);
+ public function modReplace(string $dn, array $entry): bool;
/**
* Delete attribute values from current attributes.
*
* @see http://php.net/manual/en/function.ldap-mod-del.php
*
- * @param string $dn
- * @param array $entry
- * @return bool
- *
* @throws LdapRecordException
*/
- public function modDelete($dn, array $entry);
-
- /**
- * Send LDAP pagination control.
- *
- * @see http://php.net/manual/en/function.ldap-control-paged-result.php
- *
- * @param int $pageSize
- * @param bool $isCritical
- * @param string $cookie
- * @return bool
- */
- public function controlPagedResult($pageSize = 1000, $isCritical = false, $cookie = '');
-
- /**
- * Retrieve the LDAP pagination cookie.
- *
- * @see http://php.net/manual/en/function.ldap-control-paged-result-response.php
- *
- * @param resource $result
- * @param string $cookie
- * @return bool
- */
- public function controlPagedResultResponse($result, &$cookie);
+ public function modDelete(string $dn, array $entry): bool;
/**
* Frees up the memory allocated internally to store the result.
*
* @see https://www.php.net/manual/en/function.ldap-free-result.php
*
- * @param resource $result
- * @return bool
+ * @param \LDAP\Result $result
*/
- public function freeResult($result);
+ public function freeResult(mixed $result): bool;
/**
- * Returns the error number of the last command executed.
+ * Get the error number of the last command executed.
*
* @see http://php.net/manual/en/function.ldap-errno.php
- *
- * @return int|null
*/
- public function errNo();
+ public function errNo(): ?int;
/**
- * Returns the error string of the specified error number.
+ * Get the error string of the specified error number.
*
* @see http://php.net/manual/en/function.ldap-err2str.php
- *
- * @param int $number
- * @return string
*/
- public function err2Str($number);
+ public function err2Str(int $number): string;
/**
- * Returns the LDAP protocol to utilize for the current connection.
- *
- * @return string
+ * Get the LDAP protocol to utilize for the current connection.
*/
- public function getProtocol();
+ public function getProtocol(): string;
/**
- * Returns the extended error code of the last command.
- *
- * @return string
+ * Get the extended error code of the last command.
*/
- public function getExtendedError();
+ public function getExtendedError(): ?string;
/**
- * Return the diagnostic Message.
- *
- * @return string
+ * Get the diagnostic message.
*/
- public function getDiagnosticMessage();
-
- /**
- * Determine if the current PHP version supports server controls.
- *
- * @deprecated since v2.5.0
- *
- * @return bool
- */
- public function supportsServerControlsInMethods();
+ public function getDiagnosticMessage(): ?string;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapRecordException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapRecordException.php
index 0669b4c65..f574b9bc4 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapRecordException.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapRecordException.php
@@ -8,30 +8,21 @@ class LdapRecordException extends Exception
{
/**
* The detailed LDAP error (if available).
- *
- * @var DetailedError|null
*/
- protected $detailedError;
+ protected ?DetailedError $detailedError = null;
/**
* Create a new Bind Exception with a detailed connection error.
- *
- * @param Exception $e
- * @param DetailedError|null $error
- * @return $this
*/
- public static function withDetailedError(Exception $e, DetailedError $error = null)
+ public static function withDetailedError(Exception $e, ?DetailedError $error = null): static
{
return (new static($e->getMessage(), $e->getCode(), $e))->setDetailedError($error);
}
/**
* Set the detailed error.
- *
- * @param DetailedError|null $error
- * @return $this
*/
- public function setDetailedError(DetailedError $error = null)
+ public function setDetailedError(?DetailedError $error = null): static
{
$this->detailedError = $error;
@@ -39,11 +30,9 @@ class LdapRecordException extends Exception
}
/**
- * Returns the detailed error.
- *
- * @return DetailedError|null
+ * Get the detailed error.
*/
- public function getDetailedError()
+ public function getDetailedError(): ?DetailedError
{
return $this->detailedError;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapResultResponse.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapResultResponse.php
new file mode 100644
index 000000000..c0c1e8306
--- /dev/null
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/LdapResultResponse.php
@@ -0,0 +1,33 @@
+errorCode === 0;
+ }
+
+ /**
+ * Determine if the LDAP response indicates a failed status.
+ */
+ public function failed(): bool
+ {
+ return ! $this->successful();
+ }
+}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Computer.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Computer.php
index 72db0a0d8..3900c61a9 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Computer.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Computer.php
@@ -2,18 +2,21 @@
namespace LdapRecord\Models\ActiveDirectory;
+use LdapRecord\Models\ActiveDirectory\Concerns\HasAccountControl;
use LdapRecord\Models\ActiveDirectory\Concerns\HasPrimaryGroup;
+use LdapRecord\Models\ActiveDirectory\Relations\HasOnePrimaryGroup;
+use LdapRecord\Models\Relations\HasMany;
+use LdapRecord\Models\Relations\HasOne;
class Computer extends Entry
{
+ use HasAccountControl;
use HasPrimaryGroup;
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'person',
'organizationalperson',
@@ -23,32 +26,24 @@ class Computer extends Entry
/**
* The groups relationship.
- *
- * Retrieves groups that the current computer is apart of.
- *
- * @return \LdapRecord\Models\Relations\HasMany
*/
- public function groups()
+ public function groups(): HasMany
{
return $this->hasMany(Group::class, 'member')->with($this->primaryGroup());
}
/**
* The primary group relationship.
- *
- * @return Relations\HasOnePrimaryGroup
*/
- public function primaryGroup()
+ public function primaryGroup(): HasOnePrimaryGroup
{
return $this->hasOnePrimaryGroup(Group::class, 'primarygroupid');
}
/**
* The managed by relationship.
- *
- * @return \LdapRecord\Models\Relations\HasOne
*/
- public function managedBy()
+ public function managedBy(): HasOne
{
return $this->hasOne([Contact::class, Group::class, User::class], 'managedby');
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasAccountControl.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasAccountControl.php
new file mode 100644
index 000000000..425cc548f
--- /dev/null
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasAccountControl.php
@@ -0,0 +1,46 @@
+isDisabled();
+ }
+
+ /**
+ * Determine if the user's account is disabled.
+ */
+ public function isDisabled(): bool
+ {
+ return $this->accountControl()->hasFlag(AccountControl::ACCOUNTDISABLE);
+ }
+
+ /**
+ * Get the user's account control.
+ */
+ public function accountControl(): AccountControl
+ {
+ return new AccountControl(
+ $this->getFirstAttribute('userAccountControl')
+ );
+ }
+
+ /**
+ * Set the user's account control attribute.
+ */
+ public function setUserAccountControlAttribute(mixed $value): void
+ {
+ if ($value instanceof AccountControl) {
+ $value = $value->getValue();
+ }
+
+ $this->attributes['useraccountcontrol'] = [(int) $value];
+ }
+}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasPrimaryGroup.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasPrimaryGroup.php
index b7138d30c..c8e69915a 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasPrimaryGroup.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Concerns/HasPrimaryGroup.php
@@ -8,13 +8,8 @@ trait HasPrimaryGroup
{
/**
* Returns a new has one primary group relationship.
- *
- * @param mixed $related
- * @param string $relationKey
- * @param string $foreignKey
- * @return HasOnePrimaryGroup
*/
- public function hasOnePrimaryGroup($related, $relationKey, $foreignKey = 'primarygroupid')
+ public function hasOnePrimaryGroup(string $related, string $relationKey, string $foreignKey = 'primarygroupid'): HasOnePrimaryGroup
{
return new HasOnePrimaryGroup($this->newQuery(), $this, $related, $relationKey, $foreignKey);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Contact.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Contact.php
index 52c451fe4..9087f058e 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Contact.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Contact.php
@@ -2,14 +2,14 @@
namespace LdapRecord\Models\ActiveDirectory;
+use LdapRecord\Models\Relations\HasMany;
+
class Contact extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'person',
'organizationalperson',
@@ -18,12 +18,8 @@ class Contact extends Entry
/**
* The groups relationship.
- *
- * Retrieves groups that the current contact is apart of.
- *
- * @return \LdapRecord\Models\Relations\HasMany
*/
- public function groups()
+ public function groups(): HasMany
{
return $this->hasMany(Group::class, 'member');
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Container.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Container.php
index 1636cf393..e17fb1f70 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Container.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Container.php
@@ -6,10 +6,8 @@ class Container extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'container',
];
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Entry.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Entry.php
index e1a0233cc..e9924f433 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Entry.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Entry.php
@@ -16,10 +16,8 @@ class Entry extends BaseEntry implements ActiveDirectory
{
/**
* The default attributes that should be mutated to dates.
- *
- * @var array
*/
- protected $defaultDates = [
+ protected array $defaultDates = [
'whenchanged' => 'windows',
'whencreated' => 'windows',
'dscorepropagationdata' => 'windows',
@@ -27,83 +25,73 @@ class Entry extends BaseEntry implements ActiveDirectory
/**
* The attribute key that contains the Object SID.
- *
- * @var string
*/
- protected $sidKey = 'objectsid';
+ protected string $sidKey = 'objectsid';
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getObjectSidKey()
+ public function getObjectSidKey(): string
{
return $this->sidKey;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getObjectSid()
+ public function getObjectSid(): ?string
{
return $this->getFirstAttribute($this->sidKey);
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getConvertedSid($sid = null)
+ public function getConvertedSid($sid = null): ?string
{
try {
- return (string) $this->newObjectSid(
- $sid ?? $this->getObjectSid()
+ return $this->newObjectSid(
+ (string) ($sid ?? $this->getObjectSid())
);
- } catch (InvalidArgumentException $e) {
- return;
+ } catch (InvalidArgumentException) {
+ return null;
}
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getBinarySid($sid = null)
+ public function getBinarySid($sid = null): ?string
{
try {
return $this->newObjectSid(
$sid ?? $this->getObjectSid()
)->getBinary();
- } catch (InvalidArgumentException $e) {
- return;
+ } catch (InvalidArgumentException) {
+ return null;
}
}
/**
* Make a new object Sid instance.
- *
- * @param string $value
- * @return Sid
*/
- protected function newObjectSid($value)
+ protected function newObjectSid(string $value): Sid
{
return new Sid($value);
}
/**
* Create a new query builder.
- *
- * @param Connection $connection
- * @return ActiveDirectoryBuilder
*/
- public function newQueryBuilder(Connection $connection)
+ public function newQueryBuilder(Connection $connection): ActiveDirectoryBuilder
{
return new ActiveDirectoryBuilder($connection);
}
/**
* Determine if the object is deleted.
- *
- * @return bool
*/
- public function isDeleted()
+ public function isDeleted(): bool
{
return strtoupper((string) $this->getFirstAttribute('isDeleted')) === 'TRUE';
}
@@ -111,12 +99,9 @@ class Entry extends BaseEntry implements ActiveDirectory
/**
* Restore a deleted object.
*
- * @param string|null $newParentDn
- * @return bool
- *
* @throws \LdapRecord\LdapRecordException
*/
- public function restore($newParentDn = null)
+ public function restore(?string $newParentDn = null): bool
{
if (! $this->isDeleted()) {
return false;
@@ -138,30 +123,27 @@ class Entry extends BaseEntry implements ActiveDirectory
$this->setRawAttribute('distinguishedname', $newDn);
$this->save(['isDeleted' => null]);
+
+ return true;
}
/**
* Get the objects restore location.
- *
- * @return string
*/
- protected function getDefaultRestoreLocation()
+ protected function getDefaultRestoreLocation(): ?string
{
return $this->getFirstAttribute('lastKnownParent') ?? $this->getParentDn($this->getParentDn($this->getDn()));
}
/**
* Convert the attributes for JSON serialization.
- *
- * @param array $attributes
- * @return array
*/
- protected function convertAttributesForJson(array $attributes = [])
+ protected function convertAttributesForJson(array $attributes = []): array
{
$attributes = parent::convertAttributesForJson($attributes);
// If the model has a SID set, we need to convert it to its
- // string format, due to it being in binary. Otherwise
+ // string format, due to it being in binary. Otherwise,
// we will receive a JSON serialization exception.
if (isset($attributes[$this->sidKey])) {
$attributes[$this->sidKey] = [$this->getConvertedSid(
@@ -174,23 +156,11 @@ class Entry extends BaseEntry implements ActiveDirectory
/**
* Convert the attributes from JSON serialization.
- *
- * @param array $attributes
- * @return array
*/
- protected function convertAttributesFromJson(array $attributes = [])
+ protected function convertAttributesFromJson(array $attributes = []): array
{
$attributes = parent::convertAttributesFromJson($attributes);
- // Here we are converting the model's GUID and SID attributes
- // back to their original values from serialization, so that
- // their original value may be used and compared against.
- if (isset($attributes[$this->guidKey])) {
- $attributes[$this->guidKey] = [$this->getBinaryGuid(
- Arr::first($attributes[$this->guidKey])
- )];
- }
-
if (isset($attributes[$this->sidKey])) {
$attributes[$this->sidKey] = [$this->getBinarySid(
Arr::first($attributes[$this->sidKey])
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeDatabase.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeDatabase.php
index 77abbbcf5..e32f82009 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeDatabase.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeDatabase.php
@@ -5,17 +5,17 @@ namespace LdapRecord\Models\ActiveDirectory;
class ExchangeDatabase extends Entry
{
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public static $objectClasses = ['msExchMDB'];
+ public static array $objectClasses = ['msExchMDB'];
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public static function boot()
+ public static function boot(): void
{
parent::boot();
- static::addGlobalScope(new Scopes\InConfigurationContext());
+ static::addGlobalScope(new Scopes\InConfigurationContext);
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeServer.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeServer.php
index d304876ab..5e13d405d 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeServer.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ExchangeServer.php
@@ -5,18 +5,18 @@ namespace LdapRecord\Models\ActiveDirectory;
class ExchangeServer extends Entry
{
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public static $objectClasses = ['msExchExchangeServer'];
+ public static array $objectClasses = ['msExchExchangeServer'];
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public static function boot()
+ public static function boot(): void
{
parent::boot();
- static::addGlobalScope(new Scopes\HasServerRoleAttribute());
- static::addGlobalScope(new Scopes\InConfigurationContext());
+ static::addGlobalScope(new Scopes\HasServerRoleAttribute);
+ static::addGlobalScope(new Scopes\InConfigurationContext);
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ForeignSecurityPrincipal.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ForeignSecurityPrincipal.php
index 25287ae4a..34e6c3358 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ForeignSecurityPrincipal.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/ForeignSecurityPrincipal.php
@@ -2,23 +2,23 @@
namespace LdapRecord\Models\ActiveDirectory;
+use LdapRecord\Models\Relations\HasMany;
+
class ForeignSecurityPrincipal extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = ['foreignsecurityprincipal'];
+ public static array $objectClasses = [
+ 'foreignsecurityprincipal',
+ ];
/**
* The groups relationship.
*
- * Retrieves groups that the current security principal is apart of.
- *
- * @return \LdapRecord\Models\Relations\HasMany
+ * Retrieves groups that the current security principal is a part of.
*/
- public function groups()
+ public function groups(): HasMany
{
return $this->hasMany(Group::class, 'member');
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Group.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Group.php
index 784588771..165bd90f8 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Group.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Group.php
@@ -2,14 +2,14 @@
namespace LdapRecord\Models\ActiveDirectory;
+use LdapRecord\Models\Relations\HasMany;
+
class Group extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'group',
];
@@ -17,23 +17,17 @@ class Group extends Entry
/**
* The groups relationship.
*
- * Retrieves groups that the current group is apart of.
- *
- * @return \LdapRecord\Models\Relations\HasMany
+ * Retrieves groups that the current group is a part of.
*/
- public function groups()
+ public function groups(): HasMany
{
return $this->hasMany(static::class, 'member');
}
/**
* The members relationship.
- *
- * Retrieves members that are apart of the group.
- *
- * @return \LdapRecord\Models\Relations\HasMany
*/
- public function members()
+ public function members(): HasMany
{
return $this->hasMany([
static::class, User::class, Contact::class, Computer::class,
@@ -44,12 +38,8 @@ class Group extends Entry
/**
* The primary group members relationship.
- *
- * Retrieves members that are apart the primary group.
- *
- * @return \LdapRecord\Models\Relations\HasMany
*/
- public function primaryGroupMembers()
+ public function primaryGroupMembers(): HasMany
{
return $this->hasMany([
static::class, User::class, Contact::class, Computer::class,
@@ -58,13 +48,11 @@ class Group extends Entry
/**
* Get the RID of the group.
- *
- * @return array
*/
- public function getRidAttribute()
+ public function getRidAttribute(): array
{
- $objectSidComponents = explode('-', (string) $this->getConvertedSid());
-
- return [end($objectSidComponents)];
+ return array_filter([
+ last(explode('-', (string) $this->getConvertedSid())),
+ ]);
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/OrganizationalUnit.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/OrganizationalUnit.php
index 80aae9f47..0801d1080 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/OrganizationalUnit.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/OrganizationalUnit.php
@@ -6,20 +6,16 @@ class OrganizationalUnit extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'organizationalunit',
];
/**
* Get the creatable RDN attribute name.
- *
- * @return string
*/
- public function getCreatableRdnAttribute()
+ public function getCreatableRdnAttribute(): string
{
return 'ou';
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Printer.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Printer.php
index df7421610..71534981d 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Printer.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Printer.php
@@ -6,8 +6,6 @@ class Printer extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = ['printqueue'];
+ public static array $objectClasses = ['printqueue'];
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Relations/HasOnePrimaryGroup.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Relations/HasOnePrimaryGroup.php
index 40350c97a..971f79066 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Relations/HasOnePrimaryGroup.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Relations/HasOnePrimaryGroup.php
@@ -9,11 +9,8 @@ class HasOnePrimaryGroup extends HasOne
{
/**
* Get the foreign model by the given value.
- *
- * @param string $value
- * @return Model|null
*/
- protected function getForeignModelByValue($value)
+ protected function getForeignModelByValue(string $value): ?Model
{
return $this->query->findBySid(
$this->getParentModelObjectSid()
@@ -24,11 +21,8 @@ class HasOnePrimaryGroup extends HasOne
* Get the foreign value from the given model.
*
* Retrieves the last RID from the models Object SID.
- *
- * @param Model $model
- * @return string
*/
- protected function getForeignValueFromModel(Model $model)
+ protected function getForeignValueFromModel(Model $model): ?string
{
$objectSidComponents = explode('-', $model->getConvertedSid());
@@ -37,10 +31,8 @@ class HasOnePrimaryGroup extends HasOne
/**
* Get the parent relationship models converted object sid.
- *
- * @return string
*/
- protected function getParentModelObjectSid()
+ protected function getParentModelObjectSid(): string
{
return preg_replace(
'/\d+$/',
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/HasServerRoleAttribute.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/HasServerRoleAttribute.php
index 76df79ca3..24a2387d3 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/HasServerRoleAttribute.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/HasServerRoleAttribute.php
@@ -10,12 +10,8 @@ class HasServerRoleAttribute implements Scope
{
/**
* Includes condition of having a serverRole attribute.
- *
- * @param Builder $query
- * @param Model $model
- * @return void
*/
- public function apply(Builder $query, Model $model)
+ public function apply(Builder $query, Model $model): void
{
$query->whereHas('serverRole');
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/InConfigurationContext.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/InConfigurationContext.php
index dc8a4d21b..b7942cf4d 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/InConfigurationContext.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/InConfigurationContext.php
@@ -12,13 +12,9 @@ class InConfigurationContext implements Scope
/**
* Refines the base dn to be inside the configuration context.
*
- * @param Builder $query
- * @param Model $model
- * @return void
- *
* @throws \LdapRecord\Models\ModelNotFoundException
*/
- public function apply(Builder $query, Model $model)
+ public function apply(Builder $query, Model $model): void
{
$query->in($this->getConfigurationNamingContext($model));
}
@@ -26,9 +22,6 @@ class InConfigurationContext implements Scope
/**
* Get the LDAP server configuration naming context distinguished name.
*
- * @param Model $model
- * @return mixed
- *
* @throws \LdapRecord\Models\ModelNotFoundException
*/
protected function getConfigurationNamingContext(Model $model)
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/RejectComputerObjectClass.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/RejectComputerObjectClass.php
index 9d00cf8fa..30545b802 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/RejectComputerObjectClass.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/Scopes/RejectComputerObjectClass.php
@@ -10,12 +10,8 @@ class RejectComputerObjectClass implements Scope
{
/**
* Prevent computer objects from being included in results.
- *
- * @param Builder $query
- * @param Model $model
- * @return void
*/
- public function apply(Builder $query, Model $model)
+ public function apply(Builder $query, Model $model): void
{
$query->where('objectclass', '!=', 'computer');
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/User.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/User.php
index c2ea0325d..3faec3882 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/User.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ActiveDirectory/User.php
@@ -4,39 +4,36 @@ namespace LdapRecord\Models\ActiveDirectory;
use Carbon\Carbon;
use Illuminate\Contracts\Auth\Authenticatable;
+use LdapRecord\Models\ActiveDirectory\Concerns\HasAccountControl;
use LdapRecord\Models\ActiveDirectory\Concerns\HasPrimaryGroup;
use LdapRecord\Models\ActiveDirectory\Scopes\RejectComputerObjectClass;
-use LdapRecord\Models\Attributes\AccountControl;
use LdapRecord\Models\Concerns\CanAuthenticate;
use LdapRecord\Models\Concerns\HasPassword;
+use LdapRecord\Models\Relations\HasMany;
+use LdapRecord\Models\Relations\HasOne;
use LdapRecord\Query\Model\Builder;
class User extends Entry implements Authenticatable
{
+ use CanAuthenticate;
+ use HasAccountControl;
use HasPassword;
use HasPrimaryGroup;
- use CanAuthenticate;
/**
* The password's attribute name.
- *
- * @var string
*/
- protected $passwordAttribute = 'unicodepwd';
+ protected string $passwordAttribute = 'unicodepwd';
/**
* The password's hash method.
- *
- * @var string
*/
- protected $passwordHashMethod = 'encode';
+ protected string $passwordHashMethod = 'encode';
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'person',
'organizationalperson',
@@ -45,10 +42,8 @@ class User extends Entry implements Authenticatable
/**
* The attributes that should be mutated to dates.
- *
- * @var array
*/
- protected $dates = [
+ protected array $dates = [
'lastlogon' => 'windows-int',
'lastlogoff' => 'windows-int',
'pwdlastset' => 'windows-int',
@@ -59,9 +54,9 @@ class User extends Entry implements Authenticatable
];
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- protected static function boot()
+ protected static function boot(): void
{
parent::boot();
@@ -69,49 +64,23 @@ class User extends Entry implements Authenticatable
// class. This is needed due to computer objects containing all
// of the ActiveDirectory 'user' object classes. Without
// this scope, they would be included in results.
- static::addGlobalScope(new RejectComputerObjectClass());
+ static::addGlobalScope(new RejectComputerObjectClass);
}
/**
- * Determine if the user's account is enabled.
- *
- * @return bool
+ * Get the unique identifier for the user.
*/
- public function isEnabled()
+ public function getAuthIdentifier(): ?string
{
- return ! $this->isDisabled();
- }
-
- /**
- * Determine if the user's account is disabled.
- *
- * @return bool
- */
- public function isDisabled()
- {
- return $this->accountControl()->has(AccountControl::ACCOUNTDISABLE);
- }
-
- /**
- * Get the user's account control.
- *
- * @return AccountControl
- */
- public function accountControl()
- {
- return new AccountControl(
- $this->getFirstAttribute('userAccountControl')
- );
+ return $this->getConvertedGuid();
}
/**
* The groups relationship.
*
- * Retrieves groups that the user is apart of.
- *
- * @return \LdapRecord\Models\Relations\HasMany
+ * Retrieves groups that the user is a part of.
*/
- public function groups()
+ public function groups(): HasMany
{
return $this->hasMany(Group::class, 'member')->with($this->primaryGroup());
}
@@ -120,10 +89,8 @@ class User extends Entry implements Authenticatable
* The manager relationship.
*
* Retrieves the manager of the user.
- *
- * @return \LdapRecord\Models\Relations\HasOne
*/
- public function manager()
+ public function manager(): HasOne
{
return $this->hasOne(static::class, 'manager');
}
@@ -131,33 +98,25 @@ class User extends Entry implements Authenticatable
/**
* The primary group relationship of the current user.
*
- * Retrieves the primary group the user is apart of.
- *
- * @return \LdapRecord\Models\Relations\HasOne
+ * Retrieves the primary group the user is a part of.
*/
- public function primaryGroup()
+ public function primaryGroup(): HasOne
{
return $this->hasOnePrimaryGroup(Group::class, 'primarygroupid');
}
/**
* Scopes the query to exchange mailbox users.
- *
- * @param Builder $query
- * @return Builder
*/
- public function scopeWhereHasMailbox(Builder $query)
+ public function scopeWhereHasMailbox(Builder $query): Builder
{
return $query->whereHas('msExchMailboxGuid');
}
/**
* Scopes the query to users having a lockout value set.
- *
- * @param Builder $query
- * @return Builder
*/
- public function scopeWhereHasLockout(Builder $query)
+ public function scopeWhereHasLockout(Builder $query): Builder
{
return $query->where('lockoutTime', '>=', 1);
}
@@ -167,12 +126,8 @@ class User extends Entry implements Authenticatable
*
* @see https://ldapwiki.com/wiki/Active%20Directory%20Account%20Lockout
* @see https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/account-lockout-duration
- *
- * @param string|int $localTimezone
- * @param int|null $durationInMinutes
- * @return bool
*/
- public function isLockedOut($localTimezone, $durationInMinutes = null)
+ public function isLockedOut(string|int $localTimezone, ?int $durationInMinutes = null): bool
{
$time = $this->getFirstAttribute('lockouttime');
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/AccountControl.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/AccountControl.php
index 45fae214d..9024b934e 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/AccountControl.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/AccountControl.php
@@ -3,8 +3,9 @@
namespace LdapRecord\Models\Attributes;
use ReflectionClass;
+use Stringable;
-class AccountControl
+class AccountControl implements Stringable
{
public const SCRIPT = 1;
@@ -51,151 +52,122 @@ class AccountControl
public const PARTIAL_SECRETS_ACCOUNT = 67108864;
/**
- * The account control flag values.
+ * The account control flags.
*
* @var array
*/
- protected $values = [];
+ protected array $flags = [];
/**
* Constructor.
- *
- * @param ?int $flag
*/
- public function __construct($flag = null)
+ public function __construct(?int $flag = null)
{
if (! is_null($flag)) {
- $this->apply($flag);
+ $this->applyFlags($flag);
}
}
/**
- * Get the value when casted to string.
- *
- * @return string
+ * Get the value when cast to string.
*/
- public function __toString()
+ public function __toString(): string
{
return (string) $this->getValue();
}
/**
- * Get the value when casted to int.
- *
- * @return int
+ * Get the value when cast to int.
*/
- public function __toInt()
+ public function __toInt(): int
{
return $this->getValue();
}
/**
- * Add the flag to the account control values.
- *
- * @param int $flag
- * @return $this
+ * Set a flag on the account control.
*/
- public function add($flag)
+ public function setFlag(int $flag): static
{
// Use the value as a key so if the same value
// is used, it will always be overwritten
- $this->values[$flag] = $flag;
+ $this->flags[$flag] = $flag;
return $this;
}
/**
- * Remove the flag from the account control.
- *
- * @param int $flag
- * @return $this
+ * Unset a flag from the account control.
*/
- public function remove($flag)
+ public function unsetFlag(int $flag): static
{
- unset($this->values[$flag]);
+ unset($this->flags[$flag]);
return $this;
}
/**
- * Extract and apply the flag.
- *
- * @param int $flag
- * @return void
+ * Extract and apply several flags.
*/
- public function apply($flag)
+ public function applyFlags(int $flags): void
{
- $this->setValues($this->extractFlags($flag));
+ $this->setFlags($this->extractFlags($flags));
}
/**
- * Determine if the account control contains the given UAC flag(s).
- *
- * @param int $flag
- * @return bool
+ * Determine if the account control contains the given flag(s).
*/
- public function has($flag)
+ public function hasFlag(int $flag): bool
{
// Here we will extract the given flag into an array
// of possible flags. This will allow us to see if
// our AccountControl object contains any of them.
$flagsUsed = array_intersect(
$this->extractFlags($flag),
- $this->values
+ $this->flags
);
return in_array($flag, $flagsUsed);
}
/**
- * Determine if the account control does not contain the given UAC flag(s).
- *
- * @param int $flag
- * @return bool
+ * Determine if the account control does not contain the given flag(s).
*/
- public function doesntHave($flag)
+ public function doesntHaveFlag(int $flag): bool
{
- return ! $this->has($flag);
+ return ! $this->hasFlag($flag);
}
/**
* Generate an LDAP filter based on the current value.
- *
- * @return string
*/
- public function filter()
+ public function filter(): string
{
- return sprintf('(UserAccountControl:1.2.840.113556.1.4.803:=%s)', $this->getValue());
+ return sprintf('(UserAccountControl:1.2.840.113556.1.4.803:=%s)', $this);
}
/**
* The logon script will be run.
- *
- * @return $this
*/
- public function runLoginScript()
+ public function setRunLoginScript(): static
{
- return $this->add(static::SCRIPT);
+ return $this->setFlag(static::SCRIPT);
}
/**
* The user account is locked.
- *
- * @return $this
*/
- public function accountIsLocked()
+ public function setAccountIsLocked(): static
{
- return $this->add(static::LOCKOUT);
+ return $this->setFlag(static::LOCKOUT);
}
/**
* The user account is disabled.
- *
- * @return $this
*/
- public function accountIsDisabled()
+ public function setAccountIsDisabled(): static
{
- return $this->add(static::ACCOUNTDISABLE);
+ return $this->setFlag(static::ACCOUNTDISABLE);
}
/**
@@ -203,117 +175,95 @@ class AccountControl
*
* This account provides user access to this domain, but not to any domain that
* trusts this domain. This is sometimes referred to as a local user account.
- *
- * @return $this
*/
- public function accountIsTemporary()
+ public function setAccountIsTemporary(): static
{
- return $this->add(static::TEMP_DUPLICATE_ACCOUNT);
+ return $this->setFlag(static::TEMP_DUPLICATE_ACCOUNT);
}
/**
* This is a default account type that represents a typical user.
- *
- * @return $this
*/
- public function accountIsNormal()
+ public function setAccountIsNormal(): static
{
- return $this->add(static::NORMAL_ACCOUNT);
+ return $this->setFlag(static::NORMAL_ACCOUNT);
}
/**
* This is a permit to trust an account for a system domain that trusts other domains.
- *
- * @return $this
*/
- public function accountIsForInterdomain()
+ public function setAccountIsForInterdomain(): static
{
- return $this->add(static::INTERDOMAIN_TRUST_ACCOUNT);
+ return $this->setFlag(static::INTERDOMAIN_TRUST_ACCOUNT);
}
/**
* This is a computer account for a computer that is running Microsoft
* Windows NT 4.0 Workstation, Microsoft Windows NT 4.0 Server, Microsoft
* Windows 2000 Professional, or Windows 2000 Server and is a member of this domain.
- *
- * @return $this
*/
- public function accountIsForWorkstation()
+ public function setAccountIsForWorkstation(): static
{
- return $this->add(static::WORKSTATION_TRUST_ACCOUNT);
+ return $this->setFlag(static::WORKSTATION_TRUST_ACCOUNT);
}
/**
* This is a computer account for a domain controller that is a member of this domain.
- *
- * @return $this
*/
- public function accountIsForServer()
+ public function setAccountIsForServer(): static
{
- return $this->add(static::SERVER_TRUST_ACCOUNT);
+ return $this->setFlag(static::SERVER_TRUST_ACCOUNT);
}
/**
* This is an MNS logon account.
- *
- * @return $this
*/
- public function accountIsMnsLogon()
+ public function setAccountIsMnsLogon(): static
{
- return $this->add(static::MNS_LOGON_ACCOUNT);
+ return $this->setFlag(static::MNS_LOGON_ACCOUNT);
}
/**
* (Windows 2000/Windows Server 2003) This account does
* not require Kerberos pre-authentication for logging on.
- *
- * @return $this
*/
- public function accountDoesNotRequirePreAuth()
+ public function setAccountDoesNotRequirePreAuth(): static
{
- return $this->add(static::DONT_REQ_PREAUTH);
+ return $this->setFlag(static::DONT_REQ_PREAUTH);
}
/**
* When this flag is set, it forces the user to log on by using a smart card.
- *
- * @return $this
*/
- public function accountRequiresSmartCard()
+ public function setAccountRequiresSmartCard(): static
{
- return $this->add(static::SMARTCARD_REQUIRED);
+ return $this->setFlag(static::SMARTCARD_REQUIRED);
}
/**
* (Windows Server 2008/Windows Server 2008 R2) The account is a read-only domain controller (RODC).
*
* This is a security-sensitive setting. Removing this setting from an RODC compromises security on that server.
- *
- * @return $this
*/
- public function accountIsReadOnly()
+ public function setAccountIsReadOnly(): static
{
- return $this->add(static::PARTIAL_SECRETS_ACCOUNT);
+ return $this->setFlag(static::PARTIAL_SECRETS_ACCOUNT);
}
/**
* The home folder is required.
- *
- * @return $this
*/
- public function homeFolderIsRequired()
+ public function setHomeFolderIsRequired(): static
{
- return $this->add(static::HOMEDIR_REQUIRED);
+ return $this->setFlag(static::HOMEDIR_REQUIRED);
}
/**
* No password is required.
- *
- * @return $this
*/
- public function passwordIsNotRequired()
+ public function setPasswordIsNotRequired(): static
{
- return $this->add(static::PASSWD_NOTREQD);
+ return $this->setFlag(static::PASSWD_NOTREQD);
}
/**
@@ -322,42 +272,34 @@ class AccountControl
* For information about how to programmatically set this permission, visit the following link:
*
* @see http://msdn2.microsoft.com/en-us/library/aa746398.aspx
- *
- * @return $this
*/
- public function passwordCannotBeChanged()
+ public function setPasswordCannotBeChanged(): static
{
- return $this->add(static::PASSWD_CANT_CHANGE);
+ return $this->setFlag(static::PASSWD_CANT_CHANGE);
}
/**
* Represents the password, which should never expire on the account.
- *
- * @return $this
*/
- public function passwordDoesNotExpire()
+ public function setPasswordDoesNotExpire(): static
{
- return $this->add(static::DONT_EXPIRE_PASSWORD);
+ return $this->setFlag(static::DONT_EXPIRE_PASSWORD);
}
/**
* (Windows 2000/Windows Server 2003) The user's password has expired.
- *
- * @return $this
*/
- public function passwordIsExpired()
+ public function setPasswordIsExpired(): static
{
- return $this->add(static::PASSWORD_EXPIRED);
+ return $this->setFlag(static::PASSWORD_EXPIRED);
}
/**
* The user can send an encrypted password.
- *
- * @return $this
*/
- public function allowEncryptedTextPassword()
+ public function setAllowEncryptedTextPassword(): static
{
- return $this->add(static::ENCRYPTED_TEXT_PWD_ALLOWED);
+ return $this->setFlag(static::ENCRYPTED_TEXT_PWD_ALLOWED);
}
/**
@@ -368,12 +310,10 @@ class AccountControl
*
* To enable a service for Kerberos delegation, you must set this
* flag on the userAccountControl property of the service account.
- *
- * @return $this
*/
- public function trustForDelegation()
+ public function setTrustForDelegation(): static
{
- return $this->add(static::TRUSTED_FOR_DELEGATION);
+ return $this->setFlag(static::TRUSTED_FOR_DELEGATION);
}
/**
@@ -383,44 +323,36 @@ class AccountControl
* should be tightly controlled. This setting lets a service that runs under the
* account assume a client's identity and authenticate as that user to other remote
* servers on the network.
- *
- * @return $this
*/
- public function trustToAuthForDelegation()
+ public function setTrustToAuthForDelegation(): static
{
- return $this->add(static::TRUSTED_TO_AUTH_FOR_DELEGATION);
+ return $this->setFlag(static::TRUSTED_TO_AUTH_FOR_DELEGATION);
}
/**
* When this flag is set, the security context of the user is not delegated to a
* service even if the service account is set as trusted for Kerberos delegation.
- *
- * @return $this
*/
- public function doNotTrustForDelegation()
+ public function setDoNotTrustForDelegation(): static
{
- return $this->add(static::NOT_DELEGATED);
+ return $this->setFlag(static::NOT_DELEGATED);
}
/**
* (Windows 2000/Windows Server 2003) Restrict this principal to
* use only Data Encryption Standard (DES) encryption types for keys.
- *
- * @return $this
*/
- public function useDesKeyOnly()
+ public function setUseDesKeyOnly(): static
{
- return $this->add(static::USE_DES_KEY_ONLY);
+ return $this->setFlag(static::USE_DES_KEY_ONLY);
}
/**
* Get the account control value.
- *
- * @return int
*/
- public function getValue()
+ public function getValue(): int
{
- return array_sum($this->values);
+ return array_sum($this->flags);
}
/**
@@ -428,64 +360,56 @@ class AccountControl
*
* @return array
*/
- public function getValues()
+ public function getFlags(): array
{
- return $this->values;
+ return $this->flags;
}
/**
* Set the account control values.
*
* @param array $flags
- * @return void
*/
- public function setValues(array $flags)
+ public function setFlags(array $flags): void
{
- $this->values = $flags;
+ $this->flags = $flags;
}
/**
* Get all flags that are currently applied to the value.
- *
- * @return array
*/
- public function getAppliedFlags()
+ public function getAppliedFlags(): array
{
$flags = $this->getAllFlags();
- $exists = [];
+ $applied = [];
foreach ($flags as $name => $flag) {
- if ($this->has($flag)) {
- $exists[$name] = $flag;
+ if ($this->hasFlag($flag)) {
+ $applied[$name] = $flag;
}
}
- return $exists;
+ return $applied;
}
/**
* Get all possible account control flags.
- *
- * @return array
*/
- public function getAllFlags()
+ public function getAllFlags(): array
{
return (new ReflectionClass(__CLASS__))->getConstants();
}
/**
* Extracts the given flag into an array of flags used.
- *
- * @param int $flag
- * @return array
*/
- public function extractFlags($flag)
+ protected function extractFlags(int $flag): array
{
$flags = [];
for ($i = 0; $i <= 26; $i++) {
- if ((int) $flag & (1 << $i)) {
+ if ($flag & (1 << $i)) {
$flags[1 << $i] = 1 << $i;
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedName.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedName.php
index fc981299a..09391091b 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedName.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedName.php
@@ -4,89 +4,69 @@ namespace LdapRecord\Models\Attributes;
use LdapRecord\EscapesValues;
use LdapRecord\Support\Arr;
+use Stringable;
-class DistinguishedName
+class DistinguishedName implements Stringable
{
use EscapesValues;
/**
- * The underlying raw value.
- *
- * @var string
+ * The underlying raw distinguished name value.
*/
- protected $value;
+ protected string $value;
/**
* Constructor.
- *
- * @param string|null $value
*/
- public function __construct($value = null)
+ public function __construct(?string $value = null)
{
$this->value = trim((string) $value);
}
/**
* Get the distinguished name value.
- *
- * @return string
*/
- public function __toString()
+ public function __toString(): string
{
- return (string) $this->value;
+ return $this->value;
}
/**
* Alias of the "build" method.
- *
- * @param string|null $value
- * @return DistinguishedNameBuilder
*/
- public static function of($value = null)
+ public static function of(?string $value = null): DistinguishedNameBuilder
{
return static::build($value);
}
/**
* Get a new DN builder object from the given DN.
- *
- * @param string|null $value
- * @return DistinguishedNameBuilder
*/
- public static function build($value = null)
+ public static function build(?string $value = null): DistinguishedNameBuilder
{
return new DistinguishedNameBuilder($value);
}
/**
* Make a new distinguished name instance.
- *
- * @param string|null $value
- * @return static
*/
- public static function make($value = null)
+ public static function make(?string $value = null): static
{
return new static($value);
}
/**
* Determine if the given value is a valid distinguished name.
- *
- * @param string $value
- * @return bool
*/
- public static function isValid($value)
+ public static function isValid(?string $value = null): bool
{
return ! static::make($value)->isEmpty();
}
/**
* Explode a distinguished name into relative distinguished names.
- *
- * @param string $dn
- * @return array
*/
- public static function explode($dn)
+ public static function explode(string $dn): array
{
$components = ldap_explode_dn($dn, (int) $withoutAttributes = false);
@@ -103,58 +83,34 @@ class DistinguishedName
return $components;
}
- /**
- * Un-escapes a hexadecimal string into its original string representation.
- *
- * @param string $value
- * @return string
- */
- public static function unescape($value)
- {
- return preg_replace_callback('/\\\([0-9A-Fa-f]{2})/', function ($matches) {
- return chr(hexdec($matches[1]));
- }, $value);
- }
-
/**
* Explode the RDN into an attribute and value.
- *
- * @param string $rdn
- * @return array
*/
- public static function explodeRdn($rdn)
+ public static function explodeRdn(string $rdn): array
{
return explode('=', $rdn, $limit = 2);
}
/**
* Implode the component attribute and value into an RDN.
- *
- * @param string $rdn
- * @return string
*/
- public static function makeRdn(array $component)
+ public static function makeRdn(array $component): string
{
return implode('=', $component);
}
/**
* Get the underlying value.
- *
- * @return string|null
*/
- public function get()
+ public function get(): ?string
{
return $this->value;
}
/**
* Set the underlying value.
- *
- * @param string|null $value
- * @return $this
*/
- public function set($value)
+ public function set(?string $value = null): static
{
$this->value = $value;
@@ -163,15 +119,13 @@ class DistinguishedName
/**
* Get the distinguished name values without attributes.
- *
- * @return array
*/
- public function values()
+ public function values(): array
{
$values = [];
foreach ($this->multi() as [, $value]) {
- $values[] = static::unescape($value);
+ $values[] = EscapedValue::unescape($value);
}
return $values;
@@ -179,10 +133,8 @@ class DistinguishedName
/**
* Get the distinguished name attributes without values.
- *
- * @return array
*/
- public function attributes()
+ public function attributes(): array
{
$attributes = [];
@@ -195,10 +147,8 @@ class DistinguishedName
/**
* Get the distinguished name components with attributes.
- *
- * @return array
*/
- public function components()
+ public function components(): array
{
$components = [];
@@ -207,7 +157,7 @@ class DistinguishedName
// escaped. This cannot be opted out of. Here we will unescape
// the attribute value, then re-escape it to its original
// representation from the server using the "dn" flag.
- $value = $this->escape(static::unescape($value))->dn();
+ $value = $this->escape(EscapedValue::unescape($value))->forDn();
$components[] = static::makeRdn([$attribute, $value]);
}
@@ -217,10 +167,8 @@ class DistinguishedName
/**
* Convert the distinguished name into an associative array.
- *
- * @return array
*/
- public function assoc()
+ public function assoc(): array
{
$map = [];
@@ -237,52 +185,40 @@ class DistinguishedName
/**
* Split the RDNs into a multi-dimensional array.
- *
- * @return array
*/
- public function multi()
+ public function multi(): array
{
- return array_map(function ($rdn) {
- return static::explodeRdn($rdn);
- }, $this->rdns());
+ return array_map(fn ($rdn) => static::explodeRdn($rdn), $this->rdns());
}
/**
* Split the distinguished name into an array of unescaped RDN's.
- *
- * @return array
*/
- public function rdns()
+ public function rdns(): array
{
return static::explode($this->value);
}
/**
* Get the first RDNs value.
- *
- * @return string|null
*/
- public function name()
+ public function name(): ?string
{
return Arr::first($this->values());
}
/**
* Get the first RDNs attribute.
- *
- * @return string|null
*/
- public function head()
+ public function head(): ?string
{
return Arr::first($this->attributes());
}
/**
* Get the relative distinguished name.
- *
- * @return string|null
*/
- public function relative()
+ public function relative(): ?string
{
return Arr::first($this->components());
}
@@ -291,20 +227,16 @@ class DistinguishedName
* Alias of relative().
*
* Get the first RDN from the distinguished name.
- *
- * @return string|null
*/
- public function first()
+ public function first(): ?string
{
return $this->relative();
}
/**
* Get the parent distinguished name.
- *
- * @return string|null
*/
- public function parent()
+ public function parent(): ?string
{
$components = $this->components();
@@ -315,112 +247,91 @@ class DistinguishedName
/**
* Determine if the distinguished name is empty.
- *
- * @return bool
*/
- public function isEmpty()
+ public function isEmpty(): bool
{
return empty(
- array_filter($this->values())
+ array_filter(
+ array_map('trim', $this->values())
+ )
);
}
/**
- * Determine if the current distinguished name is a parent of the given child.
- *
- * @param DistinguishedName $child
- * @return bool
+ * Determine if the distinguished name is not empty.
*/
- public function isParentOf(self $child)
+ public function isNotEmpty(): bool
+ {
+ return ! $this->isEmpty();
+ }
+
+ /**
+ * Determine if the current distinguished name is a parent of the given child.
+ */
+ public function isParentOf(self $child): bool
{
return $child->isChildOf($this);
}
/**
* Determine if the current distinguished name is a child of the given parent.
- *
- * @param DistinguishedName $parent
- * @return bool
*/
- public function isChildOf(self $parent)
+ public function isChildOf(self $parent): bool
{
- if (
- empty($components = $this->components()) ||
- empty($parentComponents = $parent->components())
- ) {
+ if (! $this->isComparable($this->parent(), $parent->get())) {
return false;
}
- array_shift($components);
-
- return $this->compare($components, $parentComponents);
+ return $this->normalize($this->parent()) === $this->normalize($parent->get());
}
/**
* Determine if the current distinguished name is an ancestor of the descendant.
- *
- * @param DistinguishedName $descendant
- * @return bool
*/
- public function isAncestorOf(self $descendant)
+ public function isAncestorOf(self $descendant): bool
{
return $descendant->isDescendantOf($this);
}
/**
* Determine if the current distinguished name is a descendant of the ancestor.
- *
- * @param DistinguishedName $ancestor
- * @return bool
*/
- public function isDescendantOf(self $ancestor)
+ public function isDescendantOf(self $ancestor): bool
{
- if (
- empty($components = $this->components()) ||
- empty($ancestorComponents = $ancestor->components())
- ) {
+ if (! $this->isComparable($this->parent(), $ancestor->get())) {
return false;
}
- if (! $length = count($components) - count($ancestorComponents)) {
+ return str_ends_with(
+ $this->normalize($this->parent()),
+ $this->normalize($ancestor->get())
+ );
+ }
+
+ /**
+ * Determine if the current distinguished name is a sibling of the given distinguished name.
+ */
+ public function isSiblingOf(self $sibling): bool
+ {
+ if (! $this->isComparable($this->parent(), $sibling->parent())) {
return false;
}
- array_splice($components, $offset = 0, $length);
-
- return $this->compare($components, $ancestorComponents);
+ return $this->normalize($this->parent()) === $this->normalize($sibling->parent());
}
/**
- * Compare whether the two distinguished name values are equal.
- *
- * @param array $values
- * @param array $other
- * @return bool
+ * Determine if the distinguished names are comparable.
*/
- protected function compare(array $values, array $other)
+ protected function isComparable(?string $first, ?string $second): bool
{
- return $this->recase($values) == $this->recase($other);
- }
-
- /**
- * Recase the array values.
- *
- * @param array $values
- * @return array
- */
- protected function recase(array $values)
- {
- return array_map([$this, 'normalize'], $values);
+ return static::make($first)->isNotEmpty() && static::make($second)->isNotEmpty();
}
/**
* Normalize the string value.
- *
- * @param string $value
- * @return string
*/
- protected function normalize($value)
+ protected function normalize(string $value): string
{
return strtolower($value);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedNameBuilder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedNameBuilder.php
index a0d84d828..7345cb92d 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedNameBuilder.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/DistinguishedNameBuilder.php
@@ -4,67 +4,53 @@ namespace LdapRecord\Models\Attributes;
use LdapRecord\EscapesValues;
use LdapRecord\Support\Arr;
+use Stringable;
-class DistinguishedNameBuilder
+class DistinguishedNameBuilder implements Stringable
{
use EscapesValues;
/**
* The components of the DN.
- *
- * @var array
*/
- protected $components = [];
+ protected array $components = [];
/**
* Whether to output the DN in reverse.
- *
- * @var bool
*/
- protected $reverse = false;
+ protected bool $reverse = false;
/**
* Constructor.
- *
- * @param string|null $value
*/
public function __construct($dn = null)
{
- $this->components = array_map(function ($rdn) {
- return DistinguishedName::explodeRdn($rdn);
- }, DistinguishedName::make($dn)->components());
+ $this->components = array_map(
+ fn ($rdn) => DistinguishedName::explodeRdn($rdn),
+ DistinguishedName::make($dn)->components()
+ );
}
/**
* Forward missing method calls onto the Distinguished Name object.
- *
- * @param string $method
- * @param array $args
- * @return mixed
*/
- public function __call($method, $args)
+ public function __call(string $method, array $args): mixed
{
return $this->get()->{$method}(...$args);
}
/**
* Get the distinguished name value.
- *
- * @return string
*/
- public function __toString()
+ public function __toString(): string
{
return (string) $this->get();
}
/**
* Prepend an RDN onto the DN.
- *
- * @param string|array $attribute
- * @param string|null $value
- * @return $this
*/
- public function prepend($attribute, $value = null)
+ public function prepend(array|string $attribute, ?string $value = null): static
{
array_unshift(
$this->components,
@@ -76,12 +62,8 @@ class DistinguishedNameBuilder
/**
* Append an RDN onto the DN.
- *
- * @param string|array $attribute
- * @param string|null $value
- * @return $this
*/
- public function append($attribute, $value = null)
+ public function append(array|string $attribute, ?string $value = null): static
{
array_push(
$this->components,
@@ -93,12 +75,8 @@ class DistinguishedNameBuilder
/**
* Componentize the attribute and value.
- *
- * @param string|array $attribute
- * @param string|null $value
- * @return array
*/
- protected function componentize($attribute, $value = null)
+ protected function componentize(array|string $attribute, ?string $value = null): array
{
// Here we will make the assumption that an array of
// RDN's have been given if the value is null, and
@@ -120,65 +98,50 @@ class DistinguishedNameBuilder
/**
* Make a componentized array by exploding the value if it's a string.
- *
- * @param string $value
- * @return array
*/
- protected function makeComponentizedArray($value)
+ protected function makeComponentizedArray(array|string $value): array
{
return is_array($value) ? $value : DistinguishedName::explodeRdn($value);
}
/**
* Make an appendable component array from the attribute and value.
- *
- * @param string|array $attribute
- * @param string|null $value
- * @return array
*/
- protected function makeAppendableComponent($attribute, $value = null)
+ protected function makeAppendableComponent(string|array $attribute, ?string $value = null): array
{
- return [trim($attribute), $this->escape(trim($value))->dn()];
+ return [trim($attribute), $this->escape(trim($value))->forDn()];
}
/**
* Pop an RDN off of the end of the DN.
- *
- * @param int $amount
- * @param array $removed
- * @return $this
*/
- public function pop($amount = 1, &$removed = [])
+ public function pop(int $amount = 1, ?array &$removed = null): static
{
- $removed = array_map(function ($component) {
- return DistinguishedName::makeRdn($component);
- }, array_splice($this->components, -$amount, $amount));
+ $removed = array_map(
+ fn ($component) => DistinguishedName::makeRdn($component),
+ array_splice($this->components, -$amount, $amount)
+ );
return $this;
}
/**
* Shift an RDN off of the beginning of the DN.
- *
- * @param int $amount
- * @param array $removed
- * @return $this
*/
- public function shift($amount = 1, &$removed = [])
+ public function shift(int $amount = 1, ?array &$removed = null): static
{
- $removed = array_map(function ($component) {
- return DistinguishedName::makeRdn($component);
- }, array_splice($this->components, 0, $amount));
+ $removed = array_map(
+ fn ($component) => DistinguishedName::makeRdn($component),
+ array_splice($this->components, 0, $amount)
+ );
return $this;
}
/**
* Whether to output the DN in reverse.
- *
- * @return $this
*/
- public function reverse()
+ public function reverse(): static
{
$this->reverse = true;
@@ -187,11 +150,8 @@ class DistinguishedNameBuilder
/**
* Get the components of the DN.
- *
- * @param null|string $type
- * @return array
*/
- public function components($type = null)
+ public function components(?string $type = null): array
{
return is_null($type)
? $this->components
@@ -200,42 +160,36 @@ class DistinguishedNameBuilder
/**
* Get the components of a particular type.
- *
- * @param string $type
- * @return array
*/
- protected function componentsOfType($type)
+ protected function componentsOfType(string $type): array
{
- $components = array_filter($this->components, function ($component) use ($type) {
- return ([$name] = $component) && strtolower($name) === strtolower($type);
- });
+ $components = array_filter($this->components, fn ($component) => (
+ ([$name] = $component) && strtolower($name) === strtolower($type)
+ ));
return array_values($components);
}
/**
* Get the fully qualified DN.
- *
- * @return DistinguishedName
*/
- public function get()
+ public function get(): DistinguishedName
{
return new DistinguishedName($this->build());
}
/**
* Build the distinguished name from the components.
- *
- * @return string
*/
- protected function build()
+ protected function build(): string
{
$components = $this->reverse
? array_reverse($this->components)
: $this->components;
- return implode(',', array_map(function ($component) {
- return DistinguishedName::makeRdn($component);
- }, $components));
+ return implode(',', array_map(
+ fn ($component) => DistinguishedName::makeRdn($component),
+ $components
+ ));
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/EscapedValue.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/EscapedValue.php
index 3c9d4db0a..c28d95c20 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/EscapedValue.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/EscapedValue.php
@@ -2,80 +2,75 @@
namespace LdapRecord\Models\Attributes;
-class EscapedValue
+use Stringable;
+
+class EscapedValue implements Stringable
{
/**
* The value to be escaped.
- *
- * @var string
*/
- protected $value;
+ protected mixed $value;
/**
* The characters to ignore when escaping.
- *
- * @var string
*/
- protected $ignore;
+ protected string $ignore;
/**
* The escape flags.
- *
- * @var int
*/
- protected $flags;
+ protected int $flags;
/**
* Constructor.
- *
- * @param string $value
- * @param string $ignore
- * @param int $flags
*/
- public function __construct($value, $ignore = '', $flags = 0)
+ public function __construct(mixed $value, string $ignore = '', int $flags = 0)
{
- $this->value = (string) $value;
+ $this->value = $value;
$this->ignore = $ignore;
$this->flags = $flags;
}
/**
- * Get the escaped value.
- *
- * @return string
+ * Un-escapes a hexadecimal string into its original string representation.
*/
- public function __toString()
+ public static function unescape(string $value): string
{
- return (string) $this->get();
+ return preg_replace_callback(
+ '/\\\([0-9A-Fa-f]{2})/',
+ fn ($matches) => chr(hexdec($matches[1])),
+ $value
+ );
}
/**
* Get the escaped value.
- *
- * @return mixed
*/
- public function get()
+ public function __toString(): string
{
- return ldap_escape($this->value, $this->ignore, $this->flags);
+ return $this->get();
+ }
+
+ /**
+ * Get the escaped value.
+ */
+ public function get(): string
+ {
+ return ldap_escape((string) $this->value, $this->ignore, $this->flags);
}
/**
* Get the raw (unescaped) value.
- *
- * @return mixed
*/
- public function raw()
+ public function getRaw(): mixed
{
return $this->value;
}
/**
* Set the characters to exclude from being escaped.
- *
- * @param string $characters
- * @return $this
*/
- public function ignore($characters)
+ public function ignore(string $characters): static
{
$this->ignore = $characters;
@@ -84,10 +79,8 @@ class EscapedValue
/**
* Prepare the value to be escaped for use in a distinguished name.
- *
- * @return $this
*/
- public function dn()
+ public function forDn(): static
{
$this->flags = LDAP_ESCAPE_DN;
@@ -96,10 +89,8 @@ class EscapedValue
/**
* Prepare the value to be escaped for use in a filter.
- *
- * @return $this
*/
- public function filter()
+ public function forFilter(): static
{
$this->flags = LDAP_ESCAPE_FILTER;
@@ -108,10 +99,8 @@ class EscapedValue
/**
* Prepare the value to be escaped for use in a distinguished name and filter.
- *
- * @return $this
*/
- public function both()
+ public function forDnAndFilter(): static
{
$this->flags = LDAP_ESCAPE_FILTER + LDAP_ESCAPE_DN;
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Guid.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Guid.php
index e04b5cd3f..dfde16429 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Guid.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Guid.php
@@ -3,33 +3,14 @@
namespace LdapRecord\Models\Attributes;
use InvalidArgumentException;
-use LdapRecord\Utilities;
+use Stringable;
-class Guid
+class Guid implements Stringable
{
/**
* The string GUID value.
- *
- * @var string
*/
- protected $value;
-
- /**
- * The guid structure in order by section to parse using substr().
- *
- * @author Chad Sikorra
- *
- * @see https://github.com/ldaptools/ldaptools
- *
- * @var array
- */
- protected $guidSections = [
- [[-26, 2], [-28, 2], [-30, 2], [-32, 2]],
- [[-22, 2], [-24, 2]],
- [[-18, 2], [-20, 2]],
- [[-16, 4]],
- [[-12, 12]],
- ];
+ protected ?string $value = null;
/**
* The hexadecimal octet order based on string position.
@@ -37,10 +18,8 @@ class Guid
* @author Chad Sikorra
*
* @see https://github.com/ldaptools/ldaptools
- *
- * @var array
*/
- protected $octetSections = [
+ protected array $octetSections = [
[6, 4, 2, 0],
[10, 8],
[14, 12],
@@ -48,24 +27,19 @@ class Guid
];
/**
- * Determines if the specified GUID is valid.
- *
- * @param string $guid
- * @return bool
+ * Determine if the specified GUID is valid.
*/
- public static function isValid($guid)
+ public static function isValid(string $guid): bool
{
- return Utilities::isValidGuid($guid);
+ return (bool) preg_match('/^([0-9a-fA-F]){8}(-([0-9a-fA-F]){4}){3}-([0-9a-fA-F]){12}$/', $guid);
}
/**
* Constructor.
*
- * @param mixed $value
- *
* @throws InvalidArgumentException
*/
- public function __construct($value)
+ public function __construct(string $value)
{
if (static::isValid($value)) {
$this->value = $value;
@@ -77,66 +51,83 @@ class Guid
}
/**
- * Returns the string value of the GUID.
- *
- * @return string
+ * Get the string value of the GUID.
*/
- public function __toString()
+ public function __toString(): string
{
return $this->getValue();
}
/**
- * Returns the string value of the SID.
- *
- * @return string
+ * Get the string value of the GUID.
*/
- public function getValue()
+ public function getValue(): string
{
return $this->value;
}
/**
* Get the binary representation of the GUID string.
- *
- * @return string
*/
- public function getBinary()
+ public function getBinary(): string
{
return hex2bin($this->getHex());
}
/**
- * Get the hexadecimal representation of the GUID string.
- *
- * @return string
+ * Get the encoded hexadecimal representation of the GUID string.
*/
- public function getHex()
+ public function getEncodedHex(): string
{
- $data = '';
+ return '\\'.implode('\\', str_split($this->getHex(), 2));
+ }
+
+ /**
+ * Get the hexadecimal representation of the GUID string.
+ */
+ public function getHex(): string
+ {
+ return implode($this->getOctetSections());
+ }
+
+ /**
+ * Get the octect sections of the GUID.
+ */
+ protected function getOctetSections(): array
+ {
+ $sections = [];
$guid = str_replace('-', '', $this->value);
foreach ($this->octetSections as $section) {
- $data .= $this->parseSection($guid, $section, $octet = true);
+ $sections[] = $this->parseSection($guid, $section, true);
}
- return $data;
+ return $sections;
}
/**
- * Returns the string variant of a binary GUID.
- *
- * @param string $binary
- * @return string|null
+ * Get the string variant of a binary GUID.
*/
- protected function binaryGuidToString($binary)
+ protected function binaryGuidToString(string $binary): ?string
{
- return Utilities::binaryGuidToString($binary);
+ if (trim($binary) === '') {
+ return null;
+ }
+
+ $hex = unpack('H*hex', $binary)['hex'];
+
+ $hex1 = substr($hex, -26, 2).substr($hex, -28, 2).substr($hex, -30, 2).substr($hex, -32, 2);
+ $hex2 = substr($hex, -22, 2).substr($hex, -24, 2);
+ $hex3 = substr($hex, -18, 2).substr($hex, -20, 2);
+ $hex4 = substr($hex, -16, 4);
+ $hex5 = substr($hex, -12, 12);
+
+ return sprintf('%s-%s-%s-%s-%s', $hex1, $hex2, $hex3, $hex4, $hex5);
}
/**
- * Return the specified section of the hexadecimal string.
+ * Get the specified section of the hexadecimal string.
*
* @author Chad Sikorra
*
@@ -147,7 +138,7 @@ class Guid
* @param bool $octet Whether this is for octet string form.
* @return string The concatenated sections in upper-case.
*/
- protected function parseSection($hex, array $sections, $octet = false)
+ protected function parseSection(string $hex, array $sections, bool $octet = false): string
{
$parsedString = '';
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/MbString.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/MbString.php
index 72d4c6f48..c6eb4985e 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/MbString.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/MbString.php
@@ -6,11 +6,8 @@ class MbString
{
/**
* Get the integer value of a specific character.
- *
- * @param $string
- * @return int
*/
- public static function ord($string)
+ public static function ord(string $string): int
{
if (static::isLoaded()) {
$result = unpack('N', mb_convert_encoding($string, 'UCS-4BE', 'UTF-8'));
@@ -25,11 +22,8 @@ class MbString
/**
* Get the character for a specific integer value.
- *
- * @param $int
- * @return string
*/
- public static function chr($int)
+ public static function chr(int $int): string
{
if (static::isLoaded()) {
return mb_convert_encoding(pack('n', $int), 'UTF-8', 'UTF-16BE');
@@ -40,36 +34,28 @@ class MbString
/**
* Split a string into its individual characters and return it as an array.
- *
- * @param string $value
- * @return string[]
*/
- public static function split($value)
+ public static function split(string $value): array
{
return preg_split('/(? ['$1$', 12],
+ static::CRYPT_SALT_TYPE_SHA256 => ['$5$', 16],
+ static::CRYPT_SALT_TYPE_SHA512 => ['$6$', 16],
+ default => throw new InvalidArgumentException("Invalid crypt type [$type]."),
+ };
}
/**
* Attempt to retrieve the hash method used for the password.
- *
- * @param string $password
- * @return string|void
*/
- public static function getHashMethod($password)
+ public static function getHashMethod(string $password): ?string
{
if (! preg_match('/^\{(\w+)\}/', $password, $matches)) {
- return;
+ return null;
}
return $matches[1];
@@ -272,14 +198,11 @@ class Password
/**
* Attempt to retrieve the hash method and algorithm used for the password.
- *
- * @param string $password
- * @return array|void
*/
- public static function getHashMethodAndAlgo($password)
+ public static function getHashMethodAndAlgo(string $password): ?array
{
if (! preg_match('/^\{(\w+)\}\$([0-9a-z]{1})\$/', $password, $matches)) {
- return;
+ return null;
}
return [$matches[1], $matches[2]];
@@ -288,11 +211,9 @@ class Password
/**
* Attempt to retrieve a salt from the encrypted password.
*
- * @return string
- *
* @throws LdapRecordException
*/
- public static function getSalt($encryptedPassword)
+ public static function getSalt(string $encryptedPassword): string
{
// crypt() methods.
if (preg_match('/^\{(\w+)\}(\$.*\$).*$/', $encryptedPassword, $matches)) {
@@ -310,12 +231,9 @@ class Password
/**
* Determine if the hash method requires a salt to be given.
*
- * @param string $method
- * @return bool
- *
* @throws \ReflectionException
*/
- public static function hashMethodRequiresSalt($method): bool
+ public static function hashMethodRequiresSalt(string $method): bool
{
$parameters = (new ReflectionMethod(static::class, $method))->getParameters();
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Sid.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Sid.php
index 7760453ce..08c36267c 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Sid.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Sid.php
@@ -3,36 +3,29 @@
namespace LdapRecord\Models\Attributes;
use InvalidArgumentException;
-use LdapRecord\Utilities;
+use Stringable;
-class Sid
+class Sid implements Stringable
{
/**
* The string SID value.
- *
- * @var string
*/
- protected $value;
+ protected string $value;
/**
- * Determines if the specified SID is valid.
- *
- * @param string $sid
- * @return bool
+ * Determine if the specified SID is valid.
*/
- public static function isValid($sid)
+ public static function isValid(string $sid): bool
{
- return Utilities::isValidSid($sid);
+ return (bool) preg_match("/^S-\d(-\d{1,10}){1,16}$/i", $sid);
}
/**
* Constructor.
*
- * @param mixed $value
- *
* @throws InvalidArgumentException
*/
- public function __construct($value)
+ public function __construct(string $value)
{
if (static::isValid($value)) {
$this->value = $value;
@@ -44,31 +37,25 @@ class Sid
}
/**
- * Returns the string value of the SID.
- *
- * @return string
+ * Get the string value of the SID.
*/
- public function __toString()
+ public function __toString(): string
{
return $this->getValue();
}
/**
- * Returns the string value of the SID.
- *
- * @return string
+ * Get the string value of the SID.
*/
- public function getValue()
+ public function getValue(): string
{
return $this->value;
}
/**
- * Returns the binary variant of the SID.
- *
- * @return string
+ * Get the binary variant of the SID.
*/
- public function getBinary()
+ public function getBinary(): string
{
$sid = explode('-', ltrim($this->value, 'S-'));
@@ -87,13 +74,50 @@ class Sid
}
/**
- * Returns the string variant of a binary SID.
- *
- * @param string $binary
- * @return string|null
+ * Get the string variant of a binary SID.
*/
- protected function binarySidToString($binary)
+ protected function binarySidToString(string $binary): ?string
{
- return Utilities::binarySidToString($binary);
+ if (trim($binary) === '') {
+ return null;
+ }
+
+ // Revision - 8bit unsigned int (C1)
+ // Count - 8bit unsigned int (C1)
+ // 2 null bytes
+ // ID - 32bit unsigned long, big-endian order
+ $sid = @unpack('C1rev/C1count/x2/N1id', $binary);
+
+ if (! isset($sid['id']) || ! isset($sid['rev'])) {
+ return null;
+ }
+
+ $revisionLevel = $sid['rev'];
+
+ $identifierAuthority = $sid['id'];
+
+ $subs = $sid['count'] ?? 0;
+
+ $sidHex = $subs ? bin2hex($binary) : '';
+
+ $subAuthorities = [];
+
+ // The sub-authorities depend on the count, so only get as
+ // many as the count, regardless of data beyond it.
+ for ($i = 0; $i < $subs; $i++) {
+ $data = implode(array_reverse(
+ str_split(
+ substr($sidHex, 16 + ($i * 8), 8),
+ 2
+ )
+ ));
+
+ $subAuthorities[] = hexdec($data);
+ }
+
+ // Tack on the 'S-' and glue it all together...
+ return 'S-'.$revisionLevel.'-'.$identifierAuthority.implode(
+ preg_filter('/^/', '-', $subAuthorities)
+ );
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSProperty.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSProperty.php
index 499579f82..dd2d0ebda 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSProperty.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSProperty.php
@@ -29,10 +29,8 @@ class TSProperty
* cannot find any information on them in Microsoft documentation. However, their values appear to stay in sync with
* their non 'W' counterparts. But not doing so when manipulating the data manually does not seem to affect anything.
* This probably needs more investigation.
- *
- * @var array
*/
- protected $propTypes = [
+ protected array $propTypes = [
'string' => [
'CtxWFHomeDir',
'CtxWFHomeDirW',
@@ -63,31 +61,23 @@ class TSProperty
/**
* The property name.
- *
- * @var string
*/
- protected $name;
+ protected ?string $name = null;
/**
* The property value.
- *
- * @var string|int
*/
- protected $value;
+ protected string|int|null $value = null;
/**
* The property value type.
- *
- * @var int
*/
- protected $valueType = 1;
+ protected int $valueType = 1;
/**
* Pass binary TSProperty data to construct its object representation.
- *
- * @param string|null $value
*/
- public function __construct($value = null)
+ public function __construct(string|int|null $value = null)
{
if ($value) {
$this->decode(bin2hex($value));
@@ -96,11 +86,8 @@ class TSProperty
/**
* Set the name for the TSProperty.
- *
- * @param string $name
- * @return TSProperty
*/
- public function setName($name)
+ public function setName(string $name): static
{
$this->name = $name;
@@ -109,21 +96,16 @@ class TSProperty
/**
* Get the name for the TSProperty.
- *
- * @return string
*/
- public function getName()
+ public function getName(): ?string
{
return $this->name;
}
/**
* Set the value for the TSProperty.
- *
- * @param string|int $value
- * @return TSProperty
*/
- public function setValue($value)
+ public function setValue(string|int $value): static
{
$this->value = $value;
@@ -132,10 +114,8 @@ class TSProperty
/**
* Get the value for the TSProperty.
- *
- * @return string|int
*/
- public function getValue()
+ public function getValue(): string|int|null
{
return $this->value;
}
@@ -143,10 +123,8 @@ class TSProperty
/**
* Convert the TSProperty name/value back to its binary
* representation for the userParameters blob.
- *
- * @return string
*/
- public function toBinary()
+ public function toBinary(): string
{
$name = bin2hex($this->name);
@@ -166,10 +144,8 @@ class TSProperty
/**
* Given a TSProperty blob, decode the name/value/type/etc.
- *
- * @param string $tsProperty
*/
- protected function decode($tsProperty)
+ protected function decode(string $tsProperty): void
{
$nameLength = hexdec(substr($tsProperty, 0, 2));
@@ -183,12 +159,8 @@ class TSProperty
/**
* Based on the property name/value in question, get its encoded form.
- *
- * @param string $propName
- * @param string|int $propValue
- * @return string
*/
- protected function getEncodedValueForProp($propName, $propValue)
+ protected function getEncodedValueForProp(string $propName, string|int $propValue): string
{
if (in_array($propName, $this->propTypes['string'])) {
// Simple strings are null terminated. Unsure if this is
@@ -206,12 +178,8 @@ class TSProperty
/**
* Based on the property name in question, get its actual value from the binary blob value.
- *
- * @param string $propName
- * @param string $propValue
- * @return string|int
*/
- protected function getDecodedValueForProp($propName, $propValue)
+ protected function getDecodedValueForProp(string $propName, string $propValue): string|int
{
if (in_array($propName, $this->propTypes['string'])) {
// Strip away null terminators. I think this should
@@ -234,11 +202,9 @@ class TSProperty
* Decode the property by inspecting the nibbles of each blob, checking
* the control, and adding up the results into a final value.
*
- * @param string $hex
- * @param bool $string Whether or not this is simple string data.
- * @return string
+ * @param bool $string Whether this is simple string data.
*/
- protected function decodePropValue($hex, $string = false)
+ protected function decodePropValue(string $hex, bool $string = false): string
{
$decodePropValue = '';
@@ -266,12 +232,8 @@ class TSProperty
/**
* Get the encoded property value as a binary blob.
- *
- * @param string $value
- * @param bool $string
- * @return string
*/
- protected function encodePropValue($value, $string = false)
+ protected function encodePropValue(string $value, bool $string = false): string
{
// An int must be properly padded. (then split and reversed).
// For a string, we just split the chars. This seems
@@ -307,12 +269,8 @@ class TSProperty
* PHP's pack() function has no 'b' or 'B' template. This is
* a workaround that turns a literal bit-string into a
* packed byte-string with 8 bits per byte.
- *
- * @param string $bits
- * @param bool $len
- * @return string
*/
- protected function packBitString($bits, $len)
+ protected function packBitString(string $bits, int $len): string
{
$bits = substr($bits, 0, $len);
// Pad input with zeros to next multiple of 4 above $len
@@ -329,12 +287,8 @@ class TSProperty
/**
* Based on the control, adjust the nibble accordingly.
- *
- * @param string $nibble
- * @param string $control
- * @return string
*/
- protected function nibbleControl($nibble, $control)
+ protected function nibbleControl(string $nibble, string $control): string
{
// This control stays constant for the low/high nibbles,
// so it doesn't matter which we compare to
@@ -355,10 +309,8 @@ class TSProperty
* must be subtracted by 9 before the final value is constructed.
*
* @param string $nibbleType Either X or Y
- * @param string $nibble
- * @return string
*/
- protected function getNibbleWithControl($nibbleType, $nibble)
+ protected function getNibbleWithControl(string $nibbleType, string $nibble): string
{
$dec = bindec($nibble);
@@ -375,11 +327,9 @@ class TSProperty
/**
* Need to make sure hex values are always an even length, so pad as needed.
*
- * @param int $int
* @param int $padLength The hex string must be padded to this length (with zeros).
- * @return string
*/
- protected function dec2hex($int, $padLength = 2)
+ protected function dec2hex(int $int, int $padLength = 2): string
{
return str_pad(dechex($int), $padLength, 0, STR_PAD_LEFT);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSPropertyArray.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSPropertyArray.php
index 8320dd8ed..a81018143 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSPropertyArray.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/TSPropertyArray.php
@@ -36,33 +36,31 @@ class TSPropertyArray
];
/**
- * @var string The default data that occurs before the TSPropertyArray (CtxCfgPresent with a bunch of spaces...?)
+ * The default data that occurs before the TSPropertyArray (CtxCfgPresent with a bunch of spaces...?).
*/
- protected $defaultPreBinary = '43747843666750726573656e742020202020202020202020202020202020202020202020202020202020202020202020';
+ protected string $defaultPreBinary = '43747843666750726573656e742020202020202020202020202020202020202020202020202020202020202020202020';
/**
+ * The TSProperty array.
+ *
* @var TSProperty[]
*/
- protected $tsProperty = [];
+ protected array $tsProperty = [];
/**
- * @var string
+ * The TSProperty signature.
*/
- protected $signature = self::VALID_SIGNATURE;
+ protected string $signature = self::VALID_SIGNATURE;
/**
* Binary data that occurs before the TSPropertyArray data in userParameters.
- *
- * @var string
*/
- protected $preBinary = '';
+ protected string $preBinary = '';
/**
* Binary data that occurs after the TSPropertyArray data in userParameters.
- *
- * @var string
*/
- protected $postBinary = '';
+ protected string $postBinary = '';
/**
* Construct in one of the following ways:.
@@ -70,10 +68,8 @@ class TSPropertyArray
* - Pass an array of TSProperty key => value pairs (See DEFAULTS constant).
* - Pass the userParameters binary value. The object representation of that will be decoded and constructed.
* - Pass nothing and a default set of TSProperty key => value pairs will be used (See DEFAULTS constant).
- *
- * @param mixed $tsPropertyArray
*/
- public function __construct($tsPropertyArray = null)
+ public function __construct(mixed $tsPropertyArray = null)
{
$this->preBinary = hex2bin($this->defaultPreBinary);
@@ -81,7 +77,7 @@ class TSPropertyArray
$tsPropertyArray = $tsPropertyArray ?: self::DEFAULTS;
foreach ($tsPropertyArray as $key => $value) {
- $tsProperty = new TSProperty();
+ $tsProperty = new TSProperty;
$this->tsProperty[$key] = $tsProperty->setName($key)->setValue($value);
}
@@ -92,22 +88,16 @@ class TSPropertyArray
/**
* Check if a specific TSProperty exists by its property name.
- *
- * @param string $propName
- * @return bool
*/
- public function has($propName)
+ public function has(string $propName): bool
{
return array_key_exists(strtolower($propName), array_change_key_case($this->tsProperty));
}
/**
* Get a TSProperty object by its property name (ie. CtxWFProfilePath).
- *
- * @param string $propName
- * @return TSProperty
*/
- public function get($propName)
+ public function get(string $propName): TSProperty
{
$this->validateProp($propName);
@@ -116,11 +106,8 @@ class TSPropertyArray
/**
* Add a TSProperty object. If it already exists, it will be overwritten.
- *
- * @param TSProperty $tsProperty
- * @return $this
*/
- public function add(TSProperty $tsProperty)
+ public function add(TSProperty $tsProperty): static
{
$this->tsProperty[$tsProperty->getName()] = $tsProperty;
@@ -128,12 +115,9 @@ class TSPropertyArray
}
/**
- * Remove a TSProperty by its property name (ie. CtxMinEncryptionLevel).
- *
- * @param string $propName
- * @return $this
+ * Remove a TSProperty by its property name (i.e. CtxMinEncryptionLevel).
*/
- public function remove($propName)
+ public function remove(string $propName): static
{
foreach (array_keys($this->tsProperty) as $property) {
if (strtolower($propName) == strtolower($property)) {
@@ -146,12 +130,8 @@ class TSPropertyArray
/**
* Set the value for a specific TSProperty by its name.
- *
- * @param string $propName
- * @param mixed $propValue
- * @return $this
*/
- public function set($propName, $propValue)
+ public function set(string $propName, string|int $propValue): static
{
$this->validateProp($propName);
@@ -162,10 +142,8 @@ class TSPropertyArray
/**
* Get the full binary representation of the userParameters containing the TSPropertyArray data.
- *
- * @return string
*/
- public function toBinary()
+ public function toBinary(): string
{
$binary = $this->preBinary;
@@ -182,10 +160,8 @@ class TSPropertyArray
/**
* Get a simple associative array containing of all TSProperty names and values.
- *
- * @return array
*/
- public function toArray()
+ public function toArray(): array
{
$userParameters = [];
@@ -201,17 +177,15 @@ class TSPropertyArray
*
* @return TSProperty[]
*/
- public function getTSProperties()
+ public function getTSProperties(): array
{
return $this->tsProperty;
}
/**
* Validates that the given property name exists.
- *
- * @param string $propName
*/
- protected function validateProp($propName)
+ protected function validateProp(string $propName): void
{
if (! $this->has($propName)) {
throw new InvalidArgumentException(sprintf('TSProperty for "%s" does not exist.', $propName));
@@ -219,21 +193,17 @@ class TSPropertyArray
}
/**
- * @param string $propName
- * @return TSProperty
+ * Get the TS property object for the given property.
*/
- protected function getTsPropObj($propName)
+ protected function getTsPropObj(string $propName): TSProperty
{
return array_change_key_case($this->tsProperty)[strtolower($propName)];
}
/**
- * Get an associative array with all of the userParameters property names and values.
- *
- * @param string $userParameters
- * @return void
+ * Get an associative array with all the userParameters property names and values.
*/
- protected function decodeUserParameters($userParameters)
+ protected function decodeUserParameters(string $userParameters): void
{
$userParameters = bin2hex($userParameters);
@@ -263,11 +233,9 @@ class TSPropertyArray
* individual TSProperty structures. Return the full length
* of the TSPropertyArray data.
*
- * @param string $tsPropertyArray
- * @param int $tsPropCount
* @return int The length of the data in the TSPropertyArray
*/
- protected function addTSPropData($tsPropertyArray, $tsPropCount)
+ protected function addTSPropData(string $tsPropertyArray, int $tsPropCount): int
{
$length = 0;
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Timestamp.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Timestamp.php
index 0f07bc5a0..4046eb715 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Timestamp.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Attributes/Timestamp.php
@@ -7,38 +7,37 @@ use Carbon\CarbonInterface;
use DateTime;
use DateTimeZone;
use LdapRecord\LdapRecordException;
-use LdapRecord\Utilities;
class Timestamp
{
+ public const TYPE_LDAP = 'ldap';
+
+ public const TYPE_WINDOWS = 'windows';
+
+ public const TYPE_WINDOWS_INT = 'windows-int';
+
public const WINDOWS_INT_MAX = 9223372036854775807;
/**
* The current timestamp type.
- *
- * @var string
*/
- protected $type;
+ protected string $type;
/**
* The available timestamp types.
- *
- * @var array
*/
- protected $types = [
- 'ldap',
- 'windows',
- 'windows-int',
+ protected array $types = [
+ Timestamp::TYPE_LDAP,
+ Timestamp::TYPE_WINDOWS,
+ Timestamp::TYPE_WINDOWS_INT,
];
/**
* Constructor.
*
- * @param string $type
- *
* @throws LdapRecordException
*/
- public function __construct($type)
+ public function __construct(string $type)
{
$this->setType($type);
}
@@ -46,11 +45,9 @@ class Timestamp
/**
* Set the type of timestamp to convert from / to.
*
- * @param string $type
- *
* @throws LdapRecordException
*/
- public function setType($type)
+ public function setType(string $type): void
{
if (! in_array($type, $this->types)) {
throw new LdapRecordException("Unrecognized LDAP date type [$type]");
@@ -62,18 +59,15 @@ class Timestamp
/**
* Converts the value to an LDAP date string.
*
- * @param mixed $value
- * @return float|string
- *
* @throws LdapRecordException
*/
- public function fromDateTime($value)
+ public function fromDateTime(mixed $value): int|string
{
$value = is_array($value) ? reset($value) : $value;
- // If the value is being converted to a windows integer format but it
+ // If the value is being converted to a windows integer format, but it
// is already in that format, we will simply return the value back.
- if ($this->type == 'windows-int' && $this->valueIsWindowsIntegerType($value)) {
+ if ($this->type === Timestamp::TYPE_WINDOWS_INT && $this->valueIsWindowsIntegerType($value)) {
return $value;
}
// If the value is numeric, we will assume it's a UNIX timestamp.
@@ -89,30 +83,18 @@ class Timestamp
$value = Carbon::instance($value);
}
- switch ($this->type) {
- case 'ldap':
- $value = $this->convertDateTimeToLdapTime($value);
- break;
- case 'windows':
- $value = $this->convertDateTimeToWindows($value);
- break;
- case 'windows-int':
- $value = $this->convertDateTimeToWindowsInteger($value);
- break;
- default:
- throw new LdapRecordException("Unrecognized date type [{$this->type}]");
- }
-
- return $value;
+ return match ($this->type) {
+ Timestamp::TYPE_LDAP => $this->convertDateTimeToLdapTime($value),
+ Timestamp::TYPE_WINDOWS => $this->convertDateTimeToWindows($value),
+ Timestamp::TYPE_WINDOWS_INT => $this->convertDateTimeToWindowsInteger($value),
+ default => throw new LdapRecordException("Unrecognized date type [{$this->type}]"),
+ };
}
/**
* Determine if the value given is in Windows Integer (NTFS Filetime) format.
- *
- * @param int|string $value
- * @return bool
*/
- protected function valueIsWindowsIntegerType($value)
+ protected function valueIsWindowsIntegerType(mixed $value): bool
{
return is_numeric($value) && in_array(strlen((string) $value), [18, 19]);
}
@@ -120,12 +102,9 @@ class Timestamp
/**
* Converts the LDAP timestamp value to a Carbon instance.
*
- * @param mixed $value
- * @return Carbon|int|false
- *
* @throws LdapRecordException
*/
- public function toDateTime($value)
+ public function toDateTime(mixed $value): Carbon|int|false
{
$value = is_array($value) ? reset($value) : $value;
@@ -133,87 +112,70 @@ class Timestamp
return Carbon::instance($value);
}
- switch ($this->type) {
- case 'ldap':
- $value = $this->convertLdapTimeToDateTime($value);
- break;
- case 'windows':
- $value = $this->convertWindowsTimeToDateTime($value);
- break;
- case 'windows-int':
- $value = $this->convertWindowsIntegerTimeToDateTime($value);
- break;
- default:
- throw new LdapRecordException("Unrecognized date type [{$this->type}]");
- }
+ $value = match ($this->type) {
+ Timestamp::TYPE_LDAP => $this->convertLdapTimeToDateTime($value),
+ Timestamp::TYPE_WINDOWS => $this->convertWindowsTimeToDateTime($value),
+ Timestamp::TYPE_WINDOWS_INT => $this->convertWindowsIntegerTimeToDateTime($value),
+ default => throw new LdapRecordException("Unrecognized date type [{$this->type}]"),
+ };
return $value instanceof DateTime ? Carbon::instance($value) : $value;
}
/**
* Converts standard LDAP timestamps to a date time object.
- *
- * @param string $value
- * @return DateTime|false
*/
- protected function convertLdapTimeToDateTime($value)
+ protected function convertLdapTimeToDateTime(string $value): DateTime|false
{
- return DateTime::createFromFormat(
- str_contains((string) $value, 'Z') ? 'YmdHis\Z' : 'YmdHisT',
- $value
- );
+ return DateTime::createFromFormat(match (true) {
+ str_ends_with($value, '.000Z') => 'YmdHis.000\Z',
+ str_ends_with($value, '.0Z') => 'YmdHis.0\Z',
+ str_ends_with($value, 'Z') => 'YmdHis\Z',
+ default => 'YmdHisT',
+ }, $value);
}
/**
* Converts date objects to a standard LDAP timestamp.
- *
- * @param DateTime $date
- * @return string
*/
- protected function convertDateTimeToLdapTime(DateTime $date)
+ protected function convertDateTimeToLdapTime(DateTime $date): string
{
return $date->format(
- $date->getOffset() == 0 ? 'YmdHis\Z' : 'YmdHisO'
+ $date->getOffset() == 0
+ ? 'YmdHis\Z'
+ : 'YmdHisO'
);
}
/**
* Converts standard windows timestamps to a date time object.
- *
- * @param string $value
- * @return DateTime|false
*/
- protected function convertWindowsTimeToDateTime($value)
+ protected function convertWindowsTimeToDateTime(string $value): DateTime|false
{
- return DateTime::createFromFormat(
- str_contains((string) $value, '0Z') ? 'YmdHis.0\Z' : 'YmdHis.0T',
- $value,
- new DateTimeZone('UTC')
- );
+ return DateTime::createFromFormat(match (true) {
+ str_ends_with($value, '.0Z') => 'YmdHis.0\Z',
+ default => 'YmdHis.0T'
+ }, $value, new DateTimeZone('UTC'));
}
/**
* Converts date objects to a windows timestamp.
- *
- * @param DateTime $date
- * @return string
*/
- protected function convertDateTimeToWindows(DateTime $date)
+ protected function convertDateTimeToWindows(DateTime $date): string
{
return $date->format(
- $date->getOffset() == 0 ? 'YmdHis.0\Z' : 'YmdHis.0O'
+ $date->getOffset() == 0
+ ? 'YmdHis.0\Z'
+ : 'YmdHis.0O'
);
}
/**
* Converts standard windows integer dates to a date time object.
*
- * @param int $value
- * @return DateTime|int|false
- *
* @throws \Exception
*/
- protected function convertWindowsIntegerTimeToDateTime($value)
+ protected function convertWindowsIntegerTimeToDateTime(string|int|null $value = null): DateTime|int|false
{
if (is_null($value) || $value === '') {
return false;
@@ -227,19 +189,16 @@ class Timestamp
return (int) $value;
}
- return (new DateTime())->setTimestamp(
- Utilities::convertWindowsTimeToUnixTime($value)
+ return (new DateTime)->setTimestamp(
+ (int) ($value / 10000000) - 11644473600
);
}
/**
* Converts date objects to a windows integer timestamp.
- *
- * @param DateTime $date
- * @return float
*/
- protected function convertDateTimeToWindowsInteger(DateTime $date)
+ protected function convertDateTimeToWindowsInteger(DateTime $date): int
{
- return Utilities::convertUnixTimeToWindowsTime($date->getTimestamp());
+ return ($date->getTimestamp() + 11644473600) * 10000000;
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/BatchModification.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/BatchModification.php
index 954c58fcf..3b153095d 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/BatchModification.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/BatchModification.php
@@ -9,48 +9,38 @@ class BatchModification
use DetectsResetIntegers;
/**
- * The array keys to be used in batch modifications.
+ * The array key identifiers.
*/
public const KEY_ATTRIB = 'attrib';
+
public const KEY_MODTYPE = 'modtype';
+
public const KEY_VALUES = 'values';
/**
* The attribute of the modification.
- *
- * @var string|null
*/
- protected $attribute;
+ protected ?string $attribute = null;
/**
* The original value of the attribute before modification.
- *
- * @var array
*/
- protected $original = [];
+ protected array $original = [];
/**
* The values of the modification.
- *
- * @var array
*/
- protected $values = [];
+ protected array $values = [];
/**
* The modtype integer of the batch modification.
- *
- * @var int|null
*/
- protected $type;
+ protected ?int $type = null;
/**
* Constructor.
- *
- * @param string|null $attribute
- * @param string|int|null $type
- * @param array $values
*/
- public function __construct($attribute = null, $type = null, array $values = [])
+ public function __construct(?string $attribute = null, ?int $type = null, array $values = [])
{
$this->setAttribute($attribute)
->setType($type)
@@ -58,12 +48,17 @@ class BatchModification
}
/**
- * Set the original value of the attribute before modification.
- *
- * @param array|string $original
- * @return $this
+ * Make a new batch modification instance.
*/
- public function setOriginal($original = [])
+ public static function make(?string $attribute = null, ?int $type = null, array $values = []): self
+ {
+ return new static($attribute, $type, $values);
+ }
+
+ /**
+ * Set the original value of the attribute before modification.
+ */
+ public function setOriginal(array|string $original = []): static
{
$this->original = $this->normalizeAttributeValues($original);
@@ -71,22 +66,17 @@ class BatchModification
}
/**
- * Returns the original value of the attribute before modification.
- *
- * @return array
+ * Get the original value of the attribute before modification.
*/
- public function getOriginal()
+ public function getOriginal(): array
{
return $this->original;
}
/**
* Set the attribute of the modification.
- *
- * @param string $attribute
- * @return $this
*/
- public function setAttribute($attribute)
+ public function setAttribute(?string $attribute = null): static
{
$this->attribute = $attribute;
@@ -94,64 +84,51 @@ class BatchModification
}
/**
- * Returns the attribute of the modification.
- *
- * @return string
+ * Get the attribute of the modification.
*/
- public function getAttribute()
+ public function getAttribute(): string
{
return $this->attribute;
}
/**
* Set the values of the modification.
- *
- * @param array $values
- * @return $this
*/
- public function setValues(array $values = [])
+ public function setValues(array $values = []): static
{
// Null and empty values must also not be added to a batch
// modification. Passing null or empty values will result
// in an exception when trying to save the modification.
$this->values = array_filter($this->normalizeAttributeValues($values), function ($value) {
- return is_numeric($value) && $this->valueIsResetInteger((int) $value) ?: ! empty($value);
+ return is_numeric($value) && $this->valueIsResetInteger((int) $value) || ! empty($value);
});
return $this;
}
/**
- * Normalize all of the attribute values.
- *
- * @param array|string $values
- * @return array
+ * Normalize all the attribute values.
*/
- protected function normalizeAttributeValues($values = [])
+ protected function normalizeAttributeValues(array|string $values = []): array
{
- // We must convert all of the values to strings. Only strings can
+ // We must convert all the values to strings. Only strings can
// be used in batch modifications, otherwise we will we will
// receive an LDAP exception while attempting to save.
return array_map('strval', (array) $values);
}
/**
- * Returns the values of the modification.
- *
- * @return array
+ * Get the values of the modification.
*/
- public function getValues()
+ public function getValues(): array
{
return $this->values;
}
/**
* Set the type of the modification.
- *
- * @param int|null $type
- * @return $this
*/
- public function setType($type = null)
+ public function setType(?int $type = null): static
{
if (is_null($type)) {
return $this;
@@ -167,21 +144,17 @@ class BatchModification
}
/**
- * Returns the type of the modification.
- *
- * @return int
+ * Get the type of the modification.
*/
- public function getType()
+ public function getType(): ?int
{
return $this->type;
}
/**
- * Determines if the batch modification is valid in its current state.
- *
- * @return bool
+ * Determine if the batch modification is valid in its current state.
*/
- public function isValid()
+ public function isValid(): bool
{
return ! is_null($this->get());
}
@@ -189,51 +162,43 @@ class BatchModification
/**
* Builds the type of modification automatically
* based on the current and original values.
- *
- * @return $this
*/
- public function build()
+ public function build(): static
{
- switch (true) {
- case empty($this->original) && empty($this->values):
- return $this;
- case ! empty($this->original) && empty($this->values):
- return $this->setType(LDAP_MODIFY_BATCH_REMOVE_ALL);
- case empty($this->original) && ! empty($this->values):
- return $this->setType(LDAP_MODIFY_BATCH_ADD);
- default:
- return $this->determineBatchTypeFromOriginal();
- }
+ return match (true) {
+ empty($this->original) && empty($this->values) => $this,
+
+ ! empty($this->original) && empty($this->values) => $this->setType(LDAP_MODIFY_BATCH_REMOVE_ALL),
+
+ empty($this->original) && ! empty($this->values) => $this->setType(LDAP_MODIFY_BATCH_ADD),
+
+ default => $this->determineBatchTypeFromOriginal(),
+ };
}
/**
* Determine the batch modification type from the original values.
- *
- * @return $this
*/
- protected function determineBatchTypeFromOriginal()
+ protected function determineBatchTypeFromOriginal(): static
{
$added = $this->getAddedValues();
$removed = $this->getRemovedValues();
- switch (true) {
- case ! empty($added) && ! empty($removed):
- return $this->setType(LDAP_MODIFY_BATCH_REPLACE);
- case ! empty($added):
- return $this->setValues($added)->setType(LDAP_MODIFY_BATCH_ADD);
- case ! empty($removed):
- return $this->setValues($removed)->setType(LDAP_MODIFY_BATCH_REMOVE);
- default:
- return $this;
- }
+ return match (true) {
+ ! empty($added) && ! empty($removed) => $this->setType(LDAP_MODIFY_BATCH_REPLACE),
+
+ ! empty($added) => $this->setValues($added)->setType(LDAP_MODIFY_BATCH_ADD),
+
+ ! empty($removed) => $this->setValues($removed)->setType(LDAP_MODIFY_BATCH_REMOVE),
+
+ default => $this,
+ };
}
/**
* Get the values that were added to the attribute.
- *
- * @return array
*/
- protected function getAddedValues()
+ protected function getAddedValues(): array
{
return array_values(
array_diff($this->values, $this->original)
@@ -242,10 +207,8 @@ class BatchModification
/**
* Get the values that were removed from the attribute.
- *
- * @return array
*/
- protected function getRemovedValues()
+ protected function getRemovedValues(): array
{
return array_values(
array_diff($this->original, $this->values)
@@ -253,43 +216,30 @@ class BatchModification
}
/**
- * Returns the built batch modification array.
- *
- * @return array|null
+ * Get the batch modification array.
*/
- public function get()
+ public function get(): ?array
{
- switch ($this->type) {
- case LDAP_MODIFY_BATCH_REMOVE_ALL:
- // A values key cannot be provided when
- // a remove all type is selected.
- return [
- static::KEY_ATTRIB => $this->attribute,
- static::KEY_MODTYPE => $this->type,
- ];
- case LDAP_MODIFY_BATCH_REMOVE:
- // Fallthrough.
- case LDAP_MODIFY_BATCH_ADD:
- // Fallthrough.
- case LDAP_MODIFY_BATCH_REPLACE:
- return [
- static::KEY_ATTRIB => $this->attribute,
- static::KEY_MODTYPE => $this->type,
- static::KEY_VALUES => $this->values,
- ];
- default:
- // If the modtype isn't recognized, we'll return null.
- return;
- }
+ return match ($this->type) {
+ LDAP_MODIFY_BATCH_REMOVE_ALL => [
+ static::KEY_ATTRIB => $this->attribute,
+ static::KEY_MODTYPE => $this->type,
+ ],
+
+ LDAP_MODIFY_BATCH_REMOVE, LDAP_MODIFY_BATCH_ADD, LDAP_MODIFY_BATCH_REPLACE => [
+ static::KEY_ATTRIB => $this->attribute,
+ static::KEY_MODTYPE => $this->type,
+ static::KEY_VALUES => $this->values,
+ ],
+
+ default => null,
+ };
}
/**
- * Determines if the given modtype is valid.
- *
- * @param int $type
- * @return bool
+ * Determine if the given modtype is valid.
*/
- protected function isValidType($type)
+ protected function isValidType(int $type): bool
{
return in_array($type, [
LDAP_MODIFY_BATCH_REMOVE_ALL,
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Collection.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Collection.php
index 11b4ca522..a0d8126a0 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Collection.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Collection.php
@@ -11,10 +11,8 @@ class Collection extends QueryCollection
{
/**
* Get a collection of the model's distinguished names.
- *
- * @return static
*/
- public function modelDns()
+ public function modelDns(): static
{
return $this->map(function (Model $model) {
return $model->getDn();
@@ -22,12 +20,11 @@ class Collection extends QueryCollection
}
/**
- * Determine if the collection contains all of the given models, or any models.
+ * Determine if the collection contains all the given models, or any models.
*
- * @param mixed $models
- * @return bool
+ * @param QueryCollection|Model|array|string|null $models
*/
- public function exists($models = null)
+ public function exists(mixed $models = null): bool
{
$models = $this->getArrayableModels($models);
@@ -57,19 +54,11 @@ class Collection extends QueryCollection
/**
* Determine if any of the given models are contained in the collection.
- *
- * @param mixed $key
- * @param mixed $operator
- * @param mixed $value
- * @return bool
*/
- public function contains($key, $operator = null, $value = null)
+ public function contains($key, $operator = null, $value = null): bool
{
if (func_num_args() > 1 || $key instanceof Closure) {
- // If we are supplied with more than one argument, or
- // we were passed a closure, we will utilize the
- // parents contains method, for compatibility.
- return parent::contains($key, $operator, $value);
+ return parent::contains(...func_get_args());
}
foreach ($this->getArrayableModels($key) as $model) {
@@ -87,25 +76,20 @@ class Collection extends QueryCollection
/**
* Get the provided models as an array.
- *
- * @param mixed $models
- * @return array
*/
- protected function getArrayableModels($models = null)
+ protected function getArrayableModels(mixed $models = null): array
{
- return $models instanceof QueryCollection
- ? $models->toArray()
- : Arr::wrap($models);
+ if ($models instanceof QueryCollection) {
+ return $models->all();
+ }
+
+ return Arr::wrap($models);
}
/**
* Compare the related model with the given.
- *
- * @param Model|string $model
- * @param Model $related
- * @return bool
*/
- protected function compareModelWithRelated($model, $related)
+ protected function compareModelWithRelated(Model|string $model, Model $related): bool
{
if (is_string($model)) {
return $this->isValidDn($model)
@@ -118,11 +102,8 @@ class Collection extends QueryCollection
/**
* Determine if the given string is a valid distinguished name.
- *
- * @param string $dn
- * @return bool
*/
- protected function isValidDn($dn)
+ protected function isValidDn(string $dn): bool
{
return ! empty((new DistinguishedName($dn))->components());
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/CanAuthenticate.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/CanAuthenticate.php
index 6e8d4fb5d..e52657a44 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/CanAuthenticate.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/CanAuthenticate.php
@@ -7,60 +7,58 @@ trait CanAuthenticate
{
/**
* Get the name of the unique identifier for the user.
- *
- * @return string
*/
- public function getAuthIdentifierName()
+ public function getAuthIdentifierName(): string
{
return $this->guidKey;
}
/**
* Get the unique identifier for the user.
- *
- * @return string
*/
- public function getAuthIdentifier()
+ public function getAuthIdentifier(): string
{
- return $this->getConvertedGuid();
+ return $this->getConvertedGuid(
+ $this->getFirstAttribute($this->getAuthIdentifierName())
+ );
}
/**
* Get the password for the user.
- *
- * @return string
*/
- public function getAuthPassword()
+ public function getAuthPassword(): string
{
return '';
}
/**
- * Get the token value for the "remember me" session.
- *
- * @return string
+ * Get the name of the password attribute for the user.
*/
- public function getRememberToken()
+ public function getAuthPasswordName(): string
+ {
+ return 'password';
+ }
+
+ /**
+ * Get the token value for the "remember me" session.
+ */
+ public function getRememberToken(): string
{
return '';
}
/**
* Set the token value for the "remember me" session.
- *
- * @param string $value
- * @return void
*/
- public function setRememberToken($value)
+ public function setRememberToken($value): void
{
+ // Do nothing.
}
/**
* Get the column name for the "remember me" token.
- *
- * @return string
*/
- public function getRememberTokenName()
+ public function getRememberTokenName(): string
{
return '';
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasAttributes.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasAttributes.php
index a3d9df7d9..67b4cf703 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasAttributes.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasAttributes.php
@@ -10,6 +10,7 @@ use LdapRecord\Models\Attributes\MbString;
use LdapRecord\Models\Attributes\Timestamp;
use LdapRecord\Models\DetectsResetIntegers;
use LdapRecord\Support\Arr;
+use RuntimeException;
trait HasAttributes
{
@@ -17,69 +18,56 @@ trait HasAttributes
/**
* The models original attributes.
- *
- * @var array
*/
- protected $original = [];
+ protected array $original = [];
+
+ /**
+ * The models changed attributes.
+ */
+ protected array $changes = [];
/**
* The models attributes.
- *
- * @var array
*/
- protected $attributes = [];
+ protected array $attributes = [];
/**
* The attributes that should be mutated to dates.
- *
- * @var array
*/
- protected $dates = [];
+ protected array $dates = [];
/**
* The attributes that should be cast to their native types.
- *
- * @var array
*/
- protected $casts = [];
+ protected array $casts = [];
/**
* The accessors to append to the model's array form.
- *
- * @var array
*/
- protected $appends = [];
+ protected array $appends = [];
/**
* The format that dates must be output to for serialization.
- *
- * @var string
*/
- protected $dateFormat;
+ protected ?string $dateFormat = null;
/**
* The default attributes that should be mutated to dates.
- *
- * @var array
*/
- protected $defaultDates = [
+ protected array $defaultDates = [
'createtimestamp' => 'ldap',
'modifytimestamp' => 'ldap',
];
/**
* The cache of the mutated attributes for each class.
- *
- * @var array
*/
- protected static $mutatorCache = [];
+ protected static array $mutatorCache = [];
/**
* Convert the model's original attributes to an array.
- *
- * @return array
*/
- public function originalToArray()
+ public function originalToArray(): array
{
return $this->encodeAttributes(
$this->convertAttributesForJson($this->original)
@@ -88,16 +76,14 @@ trait HasAttributes
/**
* Convert the model's attributes to an array.
- *
- * @return array
*/
- public function attributesToArray()
+ public function attributesToArray(): array
{
// Here we will replace our LDAP formatted dates with
// properly formatted ones, so dates do not need to
// be converted manually after being returned.
$attributes = $this->addDateAttributesToArray(
- $attributes = $this->getArrayableAttributes()
+ $this->getArrayableAttributes()
);
$attributes = $this->addMutatedAttributesToArray(
@@ -125,39 +111,30 @@ trait HasAttributes
/**
* Convert the model's serialized original attributes to their original form.
- *
- * @param array $attributes
- * @return array
*/
- public function arrayToOriginal(array $attributes)
+ public function arrayToOriginal(array $attributes): array
{
- return $this->decodeAttributes(
- $this->convertAttributesFromJson($attributes)
- );
+ $attributes = $this->decodeAttributes($attributes);
+
+ return $this->convertAttributesFromJson($attributes);
}
/**
* Convert the model's serialized attributes to their original form.
- *
- * @param array $attributes
- * @return array
*/
- public function arrayToAttributes(array $attributes)
+ public function arrayToAttributes(array $attributes): array
{
$attributes = $this->restoreDateAttributesFromArray($attributes);
- return $this->decodeAttributes(
- $this->convertAttributesFromJson($attributes)
- );
+ $attributes = $this->decodeAttributes($attributes);
+
+ return $this->convertAttributesFromJson($attributes);
}
/**
* Add the date attributes to the attributes array.
- *
- * @param array $attributes
- * @return array
*/
- protected function addDateAttributesToArray(array $attributes)
+ protected function addDateAttributesToArray(array $attributes): array
{
foreach ($this->getDates() as $attribute => $type) {
if (! isset($attributes[$attribute])) {
@@ -176,18 +153,15 @@ trait HasAttributes
/**
* Restore the date attributes to their true value from serialized attributes.
- *
- * @param array $attributes
- * @return array
*/
- protected function restoreDateAttributesFromArray(array $attributes)
+ protected function restoreDateAttributesFromArray(array $attributes): array
{
foreach ($this->getDates() as $attribute => $type) {
if (! isset($attributes[$attribute])) {
continue;
}
- $date = $this->fromDateTime($type, $attributes[$attribute]);
+ $date = $this->fromDateTime($attributes[$attribute], $type);
$attributes[$attribute] = Arr::wrap($date);
}
@@ -197,21 +171,16 @@ trait HasAttributes
/**
* Prepare a date for array / JSON serialization.
- *
- * @param DateTimeInterface $date
- * @return string
*/
- protected function serializeDate(DateTimeInterface $date)
+ protected function serializeDate(DateTimeInterface $date): string
{
return $date->format($this->getDateFormat());
}
/**
* Recursively UTF-8 encode the given attributes.
- *
- * @return array
*/
- public function encodeAttributes($attributes)
+ protected function encodeAttributes($attributes): array
{
array_walk_recursive($attributes, function (&$value) {
$value = $this->encodeValue($value);
@@ -222,11 +191,8 @@ trait HasAttributes
/**
* Recursively UTF-8 decode the given attributes.
- *
- * @param array $attributes
- * @return array
*/
- public function decodeAttributes($attributes)
+ public function decodeAttributes(array $attributes): array
{
array_walk_recursive($attributes, function (&$value) {
$value = $this->decodeValue($value);
@@ -237,11 +203,8 @@ trait HasAttributes
/**
* Encode the value for serialization.
- *
- * @param string $value
- * @return string
*/
- protected function encodeValue($value)
+ protected function encodeValue(string $value): string
{
// If we are able to detect the encoding, we will
// encode only the attributes that need to be,
@@ -250,18 +213,15 @@ trait HasAttributes
return $value;
}
- return utf8_encode($value);
+ return mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1');
}
/**
* Decode the value from serialization.
- *
- * @param string $value
- * @return string
*/
- protected function decodeValue($value)
+ protected function decodeValue(string $value): string
{
- if (MbString::isLoaded() && MbString::isUtf8($value)) {
+ if (MbString::isLoaded() && ! MbString::isUtf8($value)) {
return mb_convert_encoding($value, 'UTF-8', 'ISO-8859-1');
}
@@ -270,12 +230,8 @@ trait HasAttributes
/**
* Add the mutated attributes to the attributes array.
- *
- * @param array $attributes
- * @param array $mutatedAttributes
- * @return array
*/
- protected function addMutatedAttributesToArray(array $attributes, array $mutatedAttributes)
+ protected function addMutatedAttributesToArray(array $attributes, array $mutatedAttributes): array
{
foreach ($mutatedAttributes as $key) {
// We want to spin through all the mutated attributes for this model and call
@@ -299,10 +255,8 @@ trait HasAttributes
/**
* Set the model's original attributes with the model's current attributes.
- *
- * @return $this
*/
- public function syncOriginal()
+ public function syncOriginal(): static
{
$this->original = $this->attributes;
@@ -310,12 +264,19 @@ trait HasAttributes
}
/**
- * Fills the entry with the supplied attributes.
- *
- * @param array $attributes
- * @return $this
+ * Sync the changed attributes.
*/
- public function fill(array $attributes = [])
+ public function syncChanges(): static
+ {
+ $this->changes = $this->getDirty();
+
+ return $this;
+ }
+
+ /**
+ * Fills the entry with the supplied attributes.
+ */
+ public function fill(array $attributes = []): static
{
foreach ($attributes as $key => $value) {
$this->setAttribute($key, $value);
@@ -325,29 +286,21 @@ trait HasAttributes
}
/**
- * Returns the models attribute by its key.
- *
- * @param int|string $key
- * @param mixed $default
- * @return mixed
+ * Get the models attribute by its key.
*/
- public function getAttribute($key, $default = null)
+ public function getAttribute(?string $key = null, mixed $default = null): mixed
{
if (! $key) {
- return;
+ return null;
}
return $this->getAttributeValue($key, $default);
}
/**
- * Get an attributes value.
- *
- * @param string $key
- * @param mixed $default
- * @return mixed
+ * Get an attribute's value.
*/
- public function getAttributeValue($key, $default = null)
+ public function getAttributeValue(string $key, mixed $default = null): mixed
{
$key = $this->normalizeAttributeKey($key);
$value = $this->getAttributeFromArray($key);
@@ -368,42 +321,56 @@ trait HasAttributes
}
/**
- * Determine if the given attribute is a date.
- *
- * @param string $key
- * @return bool
+ * Get the model's raw attribute value.
*/
- public function isDateAttribute($key)
+ public function getRawAttribute(string $key, mixed $default = null): mixed
+ {
+ return Arr::get($this->attributes, $this->normalizeAttributeKey($key), $default);
+ }
+
+ /**
+ * Determine if the given attribute is a date.
+ */
+ public function isDateAttribute(string $key): bool
{
return array_key_exists($key, $this->getDates());
}
/**
* Get the attributes that should be mutated to dates.
- *
- * @return array
*/
- public function getDates()
+ public function getDates(): array
{
// Since array string keys can be unique depending
// on casing differences, we need to normalize the
// array key case so they are merged properly.
return array_merge(
- array_change_key_case($this->defaultDates, CASE_LOWER),
- array_change_key_case($this->dates, CASE_LOWER)
+ array_change_key_case($this->defaultDates),
+ array_change_key_case($this->dates),
+ array_change_key_case($this->getDateCasts()),
);
}
+ /**
+ * Get the attributes casts that should be mutated to dates.
+ */
+ protected function getDateCasts(): array
+ {
+ return array_map(function (string $cast) {
+ return explode(':', $cast, 2)[1] ?? throw new RuntimeException(
+ "Invalid date cast [$cast]. A date cast must be in the format 'datetime:format'."
+ );
+ }, array_filter($this->getCasts(), function ($cast) {
+ return $this->isDateTimeCast($cast);
+ }));
+ }
+
/**
* Convert the given date value to an LDAP compatible value.
*
- * @param string $type
- * @param mixed $value
- * @return float|string
- *
* @throws LdapRecordException
*/
- public function fromDateTime($type, $value)
+ public function fromDateTime(mixed $value, string $type): float|int|string
{
return (new Timestamp($type))->fromDateTime($value);
}
@@ -411,28 +378,20 @@ trait HasAttributes
/**
* Convert the given LDAP date value to a Carbon instance.
*
- * @param mixed $value
- * @param string $type
- * @return Carbon|false
- *
* @throws LdapRecordException
*/
- public function asDateTime($value, $type)
+ public function asDateTime(mixed $value, string $type): Carbon|int|false
{
return (new Timestamp($type))->toDateTime($value);
}
/**
* Determine whether an attribute should be cast to a native type.
- *
- * @param string $key
- * @param array|string|null $types
- * @return bool
*/
- public function hasCast($key, $types = null)
+ public function hasCast(string $key, array|string|null $types = null): bool
{
if (array_key_exists($key, $this->getCasts())) {
- return $types ? in_array($this->getCastType($key), (array) $types, true) : true;
+ return ! $types || in_array($this->getCastType($key), (array) $types, true);
}
return false;
@@ -440,32 +399,24 @@ trait HasAttributes
/**
* Get the attributes that should be cast to their native types.
- *
- * @return array
*/
- protected function getCasts()
+ protected function getCasts(): array
{
- return array_change_key_case($this->casts, CASE_LOWER);
+ return array_change_key_case($this->casts);
}
/**
* Determine whether a value is JSON castable for inbound manipulation.
- *
- * @param string $key
- * @return bool
*/
- protected function isJsonCastable($key)
+ protected function isJsonCastable(string $key): bool
{
return $this->hasCast($key, ['array', 'json', 'object', 'collection']);
}
/**
* Get the type of cast for a model attribute.
- *
- * @param string $key
- * @return string
*/
- protected function getCastType($key)
+ protected function getCastType(string $key): string
{
if ($this->isDecimalCast($this->getCasts()[$key])) {
return 'decimal';
@@ -480,45 +431,32 @@ trait HasAttributes
/**
* Determine if the cast is a decimal.
- *
- * @param string $cast
- * @return bool
*/
- protected function isDecimalCast($cast)
+ protected function isDecimalCast(string $cast): bool
{
return strncmp($cast, 'decimal:', 8) === 0;
}
/**
* Determine if the cast is a datetime.
- *
- * @param string $cast
- * @return bool
*/
- protected function isDateTimeCast($cast)
+ protected function isDateTimeCast(string $cast): bool
{
return strncmp($cast, 'datetime:', 8) === 0;
}
/**
* Determine if the given attribute must be casted.
- *
- * @param string $key
- * @return bool
*/
- protected function isCastedAttribute($key)
+ protected function isCastedAttribute(string $key): bool
{
- return array_key_exists($key, array_change_key_case($this->casts, CASE_LOWER));
+ return array_key_exists($key, array_change_key_case($this->casts));
}
/**
* Cast an attribute to a native PHP type.
- *
- * @param string $key
- * @param array|null $value
- * @return mixed
*/
- protected function castAttribute($key, $value)
+ protected function castAttribute(string $key, ?array $value): mixed
{
$value = $this->castRequiresArrayValue($key) ? $value : Arr::first($value);
@@ -542,7 +480,7 @@ trait HasAttributes
case 'boolean':
return $this->asBoolean($value);
case 'object':
- return $this->fromJson($value, $asObject = true);
+ return $this->fromJson($value, true);
case 'array':
case 'json':
return $this->fromJson($value);
@@ -557,22 +495,16 @@ trait HasAttributes
/**
* Determine if the cast type requires the first attribute value.
- *
- * @return bool
*/
- protected function castRequiresArrayValue($key)
+ protected function castRequiresArrayValue(string $key): bool
{
- return in_array($this->getCastType($key), ['collection']);
+ return $this->getCastType($key) === 'collection';
}
/**
* Cast the given attribute to JSON.
- *
- * @param string $key
- * @param mixed $value
- * @return string
*/
- protected function castAttributeAsJson($key, $value)
+ protected function castAttributeAsJson(string $key, mixed $value): string
{
$value = $this->asJson($value);
@@ -580,107 +512,104 @@ trait HasAttributes
$class = get_class($this);
$message = json_last_error_msg();
- throw new Exception("Unable to encode attribute [{$key}] for model [{$class}] to JSON: {$message}.");
+ throw new Exception("Unable to encode attribute [$key] for model [$class] to JSON: $message.");
}
return $value;
}
/**
- * Convert the model to its JSON representation.
- *
- * @return string
+ * Cast the given attribute to an LDAP primitive type.
*/
- public function toJson()
+ protected function castAttributeAsPrimitive(string $key, mixed $value): string
+ {
+ return match ($this->getCastType($key)) {
+ 'bool', 'boolean' => $this->fromBoolean($value),
+ default => (string) $value,
+ };
+ }
+
+ /**
+ * Convert the model to its JSON representation.
+ */
+ public function toJson(): string
{
return json_encode($this);
}
/**
* Encode the given value as JSON.
- *
- * @param mixed $value
- * @return string
*/
- protected function asJson($value)
+ protected function asJson(mixed $value): string|false
{
return json_encode($value);
}
/**
* Decode the given JSON back into an array or object.
- *
- * @param string $value
- * @param bool $asObject
- * @return mixed
*/
- public function fromJson($value, $asObject = false)
+ public function fromJson(string $value, bool $asObject = false): mixed
{
return json_decode($value, ! $asObject);
}
/**
* Decode the given float.
- *
- * @param mixed $value
- * @return mixed
*/
- public function fromFloat($value)
+ public function fromFloat(float $value): float
{
- switch ((string) $value) {
- case 'Infinity':
- return INF;
- case '-Infinity':
- return -INF;
- case 'NaN':
- return NAN;
- default:
- return (float) $value;
- }
+ return match ((string) $value) {
+ 'NaN' => NAN,
+ 'Infinity' => INF,
+ '-Infinity' => -INF,
+ default => $value,
+ };
}
/**
- * Cast the value to a boolean.
- *
- * @param mixed $value
- * @return bool
+ * Cast the value from an LDAP boolean string to a primitive boolean.
*/
- protected function asBoolean($value)
+ protected function asBoolean(mixed $value): bool
{
- $map = ['true' => true, 'false' => false];
+ return match (strtolower($value)) {
+ 'true' => true,
+ 'false' => false,
+ default => (bool) $value,
+ };
+ }
- return $map[strtolower($value)] ?? (bool) $value;
+ /**
+ * Cast the value from a primitive boolean to an LDAP boolean string.
+ */
+ protected function fromBoolean(mixed $value): string
+ {
+ if (is_string($value)) {
+ $value = $this->asBoolean($value);
+ }
+
+ return $value ? 'TRUE' : 'FALSE';
}
/**
* Cast a decimal value as a string.
- *
- * @param float $value
- * @param int $decimals
- * @return string
*/
- protected function asDecimal($value, $decimals)
+ protected function asDecimal(float $value, int $decimals): string
{
return number_format($value, $decimals, '.', '');
}
/**
* Get an attribute array of all arrayable attributes.
- *
- * @return array
*/
- protected function getArrayableAttributes()
+ protected function getArrayableAttributes(): array
{
return $this->getArrayableItems($this->attributes);
}
/**
* Get an attribute array of all arrayable values.
- *
- * @param array $values
- * @return array
*/
- protected function getArrayableItems(array $values)
+ protected function getArrayableItems(array $values): array
{
if (count($visible = $this->getVisible()) > 0) {
$values = array_intersect_key($values, array_flip($visible));
@@ -694,11 +623,9 @@ trait HasAttributes
}
/**
- * Get all of the appendable values that are arrayable.
- *
- * @return array
+ * Get all the appendable values that are arrayable.
*/
- protected function getArrayableAppends()
+ protected function getArrayableAppends(): array
{
if (empty($this->appends)) {
return [];
@@ -711,21 +638,16 @@ trait HasAttributes
/**
* Get the format for date serialization.
- *
- * @return string
*/
- public function getDateFormat()
+ public function getDateFormat(): string
{
return $this->dateFormat ?: DateTimeInterface::ISO8601;
}
/**
* Set the date format used by the model for serialization.
- *
- * @param string $format
- * @return $this
*/
- public function setDateFormat($format)
+ public function setDateFormat(string $format): static
{
$this->dateFormat = $format;
@@ -734,33 +656,24 @@ trait HasAttributes
/**
* Get an attribute from the $attributes array.
- *
- * @param string $key
- * @return mixed
*/
- protected function getAttributeFromArray($key)
+ protected function getAttributeFromArray(string $key): mixed
{
return $this->getNormalizedAttributes()[$key] ?? null;
}
/**
* Get the attributes with their keys normalized.
- *
- * @return array
*/
- protected function getNormalizedAttributes()
+ protected function getNormalizedAttributes(): array
{
- return array_change_key_case($this->attributes, CASE_LOWER);
+ return array_change_key_case($this->attributes);
}
/**
- * Returns the first attribute by the specified key.
- *
- * @param string $key
- * @param mixed $default
- * @return mixed
+ * Get the first attribute by the specified key.
*/
- public function getFirstAttribute($key, $default = null)
+ public function getFirstAttribute(string $key, mixed $default = null): mixed
{
return Arr::first(
Arr::wrap($this->getAttribute($key, $default)),
@@ -768,38 +681,36 @@ trait HasAttributes
}
/**
- * Returns all of the models attributes.
- *
- * @return array
+ * Returns all the model's attributes.
*/
- public function getAttributes()
+ public function getAttributes(): array
{
return $this->attributes;
}
/**
* Set an attribute value by the specified key.
- *
- * @param string $key
- * @param mixed $value
- * @return $this
*/
- public function setAttribute($key, $value)
+ public function setAttribute(string $key, mixed $value): static
{
$key = $this->normalizeAttributeKey($key);
if ($this->hasSetMutator($key)) {
return $this->setMutatedAttributeValue($key, $value);
- } elseif (
+ }
+
+ if (
$value &&
$this->isDateAttribute($key) &&
! $this->valueIsResetInteger($value)
) {
- $value = $this->fromDateTime($this->getDates()[$key], $value);
+ $value = (string) $this->fromDateTime($value, $this->getDates()[$key]);
}
if ($this->isJsonCastable($key) && ! is_null($value)) {
$value = $this->castAttributeAsJson($key, $value);
+ } elseif ($this->hasCast($key) && ! is_null($value)) {
+ $value = $this->castAttributeAsPrimitive($key, $value);
}
$this->attributes[$key] = Arr::wrap($value);
@@ -809,12 +720,8 @@ trait HasAttributes
/**
* Set an attribute on the model. No checking is done.
- *
- * @param string $key
- * @param mixed $value
- * @return $this
*/
- public function setRawAttribute($key, $value)
+ public function setRawAttribute(string $key, mixed $value): static
{
$key = $this->normalizeAttributeKey($key);
@@ -825,75 +732,71 @@ trait HasAttributes
/**
* Set the models first attribute value.
- *
- * @param string $key
- * @param mixed $value
- * @return $this
*/
- public function setFirstAttribute($key, $value)
+ public function setFirstAttribute(string $key, mixed $value): static
{
return $this->setAttribute($key, Arr::wrap($value));
}
/**
* Add a unique value to the given attribute.
- *
- * @param string $key
- * @param mixed $value
- * @return $this
*/
- public function addAttributeValue($key, $value)
+ public function addAttributeValue(string $key, mixed $value): static
{
- return $this->setAttribute($key, array_unique(
- array_merge(
- Arr::wrap($this->getAttribute($key)),
- Arr::wrap($value)
- )
- ));
+ return $this->setRawAttribute($key, array_unique(array_merge(
+ $this->getRawAttribute($key, []),
+ Arr::wrap($value)
+ )));
+ }
+
+ /**
+ * Remove a unique value from the given attribute.
+ */
+ public function removeAttributeValue(string $key, mixed $value): static
+ {
+ $values = $this->getRawAttribute($key, []);
+
+ foreach (Arr::wrap($value) as $value) {
+ $index = array_search($value, $values);
+
+ if ($index !== false) {
+ unset($values[$index]);
+ }
+ }
+
+ return $this->setRawAttribute($key, array_values($values));
}
/**
* Determine if a get mutator exists for an attribute.
- *
- * @param string $key
- * @return bool
*/
- public function hasGetMutator($key)
+ public function hasGetMutator(string $key): bool
{
return method_exists($this, 'get'.$this->getMutatorMethodName($key).'Attribute');
}
/**
* Determine if a set mutator exists for an attribute.
- *
- * @param string $key
- * @return bool
*/
- public function hasSetMutator($key)
+ public function hasSetMutator(string $key): bool
{
return method_exists($this, 'set'.$this->getMutatorMethodName($key).'Attribute');
}
/**
* Set the value of an attribute using its mutator.
- *
- * @param string $key
- * @param mixed $value
- * @return mixed
*/
- protected function setMutatedAttributeValue($key, $value)
+ protected function setMutatedAttributeValue(string $key, mixed $value): static
{
- return $this->{'set'.$this->getMutatorMethodName($key).'Attribute'}($value);
+ $this->{'set'.$this->getMutatorMethodName($key).'Attribute'}($value);
+
+ return $this;
}
/**
* Get the value of an attribute using its mutator.
- *
- * @param string $key
- * @param mixed $value
- * @return mixed
*/
- protected function getMutatedAttributeValue($key, $value)
+ protected function getMutatedAttributeValue(string $key, mixed $value): mixed
{
return $this->{'get'.$this->getMutatorMethodName($key).'Attribute'}($value);
}
@@ -902,11 +805,8 @@ trait HasAttributes
* Get the mutator attribute method name.
*
* Hyphenated attributes will use pascal cased methods.
- *
- * @param string $key
- * @return mixed
*/
- protected function getMutatorMethodName($key)
+ protected function getMutatorMethodName(string $key): string
{
$key = ucwords(str_replace('-', ' ', $key));
@@ -915,12 +815,8 @@ trait HasAttributes
/**
* Get the value of an attribute using its mutator for array conversion.
- *
- * @param string $key
- * @param mixed $value
- * @return array
*/
- protected function mutateAttributeForArray($key, $value)
+ protected function mutateAttributeForArray(string $key, mixed $value): array
{
return Arr::wrap(
$this->getMutatedAttributeValue($key, $value)
@@ -928,27 +824,22 @@ trait HasAttributes
}
/**
- * Set the attributes property.
+ * Set the raw model attributes.
*
* Used when constructing an existing LDAP record.
- *
- * @param array $attributes
- * @return $this
*/
- public function setRawAttributes(array $attributes = [])
+ public function setRawAttributes(array $attributes = []): static
{
// We will filter out those annoying 'count' keys
// returned with LDAP results and lowercase all
// root array keys to prevent any casing issues.
- $raw = array_change_key_case($this->filterRawAttributes($attributes), CASE_LOWER);
+ $raw = array_change_key_case($this->filterRawAttributes($attributes));
// Before setting the models attributes, we will filter
// out the attributes that contain an integer key. LDAP
// search results will contain integer keys that have
// attribute names as values. We don't need these.
- $this->attributes = array_filter($raw, function ($key) {
- return ! is_int($key);
- }, ARRAY_FILTER_USE_KEY);
+ $this->attributes = array_filter($raw, fn ($key) => ! is_int($key), ARRAY_FILTER_USE_KEY);
// LDAP search results will contain the distinguished
// name inside of the `dn` key. We will retrieve this,
@@ -971,12 +862,8 @@ trait HasAttributes
/**
* Filters the count key recursively from raw LDAP attributes.
- *
- * @param array $attributes
- * @param array $keys
- * @return array
*/
- public function filterRawAttributes(array $attributes = [], array $keys = ['count', 'dn'])
+ public function filterRawAttributes(array $attributes = [], array $keys = ['count', 'dn']): array
{
foreach ($keys as $key) {
unset($attributes[$key]);
@@ -993,41 +880,40 @@ trait HasAttributes
/**
* Determine if the model has the given attribute.
- *
- * @param int|string $key
- * @return bool
*/
- public function hasAttribute($key)
+ public function hasAttribute(int|string $key): bool
{
- return [] !== ($this->attributes[$this->normalizeAttributeKey($key)] ?? []);
+ return ($this->attributes[$this->normalizeAttributeKey($key)] ?? []) !== [];
}
/**
- * Returns the number of attributes.
- *
- * @return int
+ * Get the number of attributes.
*/
- public function countAttributes()
+ public function countAttributes(): int
{
return count($this->getAttributes());
}
/**
- * Returns the models original attributes.
- *
- * @return array
+ * Get the model's original attributes.
*/
- public function getOriginal()
+ public function getOriginal(): array
{
return $this->original;
}
/**
- * Get the attributes that have been changed since last sync.
- *
- * @return array
+ * Get the model's raw original attribute values.
*/
- public function getDirty()
+ public function getRawOriginal(string $key, mixed $default = null): mixed
+ {
+ return Arr::get($this->original, $key, $default);
+ }
+
+ /**
+ * Get the attributes that have been changed since last sync.
+ */
+ public function getDirty(): array
{
$dirty = [];
@@ -1044,33 +930,69 @@ trait HasAttributes
}
/**
- * Determine if the given attribute is dirty.
- *
- * @param string $key
- * @return bool
+ * Get the attributes that have been changed since the model was last saved.
*/
- public function isDirty($key)
+ public function getChanges(): array
+ {
+ return $this->changes;
+ }
+
+ /**
+ * Determine if the given attribute is dirty.
+ */
+ public function isDirty(string $key): bool
{
return ! $this->originalIsEquivalent($key);
}
/**
- * Get the accessors being appended to the models array form.
- *
- * @return array
+ * Determine if given attribute has remained the same.
*/
- public function getAppends()
+ public function isClean(string $key): bool
+ {
+ return ! $this->isDirty($key);
+ }
+
+ /**
+ * Discard attribute changes and reset the attributes to their original state.
+ */
+ public function discardChanges(): static
+ {
+ [$this->attributes, $this->changes] = [$this->original, []];
+
+ return $this;
+ }
+
+ /**
+ * Determine if the model or any of the given attribute(s) were changed when the model was last saved.
+ */
+ public function wasChanged(array|string|null $attributes = null): bool
+ {
+ if (func_num_args() === 0) {
+ return count($this->changes) > 0;
+ }
+
+ foreach ((array) $attributes as $attribute) {
+ if (array_key_exists($attribute, $this->changes)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the accessors being appended to the models array form.
+ */
+ public function getAppends(): array
{
return $this->appends;
}
/**
* Set the accessors to append to model arrays.
- *
- * @param array $appends
- * @return $this
*/
- public function setAppends(array $appends)
+ public function setAppends(array $appends): static
{
$this->appends = $appends;
@@ -1079,22 +1001,16 @@ trait HasAttributes
/**
* Return whether the accessor attribute has been appended.
- *
- * @param string $attribute
- * @return bool
*/
- public function hasAppended($attribute)
+ public function hasAppended(string $attribute): bool
{
return in_array($attribute, $this->appends);
}
/**
* Returns a normalized attribute key.
- *
- * @param string $key
- * @return string
*/
- public function normalizeAttributeKey($key)
+ public function normalizeAttributeKey(string $key): string
{
// Since LDAP supports hyphens in attribute names,
// we'll convert attributes being retrieved by
@@ -1106,11 +1022,8 @@ trait HasAttributes
/**
* Determine if the new and old values for a given key are equivalent.
- *
- * @param string $key
- * @return bool
*/
- protected function originalIsEquivalent($key)
+ protected function originalIsEquivalent(string $key): bool
{
if (! array_key_exists($key, $this->original)) {
return false;
@@ -1123,17 +1036,15 @@ trait HasAttributes
return true;
}
- return is_numeric($current) &&
+ return is_numeric($current) &&
is_numeric($original) &&
strcmp((string) $current, (string) $original) === 0;
}
/**
* Get the mutated attributes for a given instance.
- *
- * @return array
*/
- public function getMutatedAttributes()
+ public function getMutatedAttributes(): array
{
$class = static::class;
@@ -1146,26 +1057,19 @@ trait HasAttributes
/**
* Extract and cache all the mutated attributes of a class.
- *
- * @param string $class
- * @return void
*/
- public static function cacheMutatedAttributes($class)
+ public static function cacheMutatedAttributes(string $class): void
{
- static::$mutatorCache[$class] = collect(static::getMutatorMethods($class))->reject(function ($match) {
- return $match === 'First';
- })->map(function ($match) {
- return lcfirst($match);
- })->all();
+ static::$mutatorCache[$class] = collect(static::getMutatorMethods($class))
+ ->reject(fn ($match) => $match === 'First')
+ ->map(fn ($match) => lcfirst($match))
+ ->all();
}
/**
* Get all of the attribute mutator methods.
- *
- * @param mixed $class
- * @return array
*/
- protected static function getMutatorMethods($class)
+ protected static function getMutatorMethods(string $class): array
{
preg_match_all('/(?<=^|;)get([^;]+?)Attribute(;|$)/', implode(';', get_class_methods($class)), $matches);
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasEvents.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasEvents.php
index d9a41b892..7537f62f6 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasEvents.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasEvents.php
@@ -13,18 +13,15 @@ trait HasEvents
{
/**
* Execute the callback without raising any events.
- *
- * @param Closure $callback
- * @return mixed
*/
- protected static function withoutEvents(Closure $callback)
+ protected static function withoutEvents(Closure $callback): mixed
{
$container = static::getConnectionContainer();
- $dispatcher = $container->getEventDispatcher();
+ $dispatcher = $container->getDispatcher();
if ($dispatcher) {
- $container->setEventDispatcher(
+ $container->setDispatcher(
new NullDispatcher($dispatcher)
);
}
@@ -33,19 +30,15 @@ trait HasEvents
return $callback();
} finally {
if ($dispatcher) {
- $container->setEventDispatcher($dispatcher);
+ $container->setDispatcher($dispatcher);
}
}
}
/**
* Dispatch the given model events.
- *
- * @param string|array $events
- * @param array $args
- * @return void
*/
- protected function dispatch($events, array $args = [])
+ protected function dispatch(array|string $events, array $args = []): void
{
foreach (Arr::wrap($events) as $name) {
$this->fireCustomModelEvent($name, $args);
@@ -54,38 +47,27 @@ trait HasEvents
/**
* Fire a custom model event.
- *
- * @param string $name
- * @param array $args
- * @return mixed
*/
- protected function fireCustomModelEvent($name, array $args = [])
+ protected function fireCustomModelEvent(string $name, array $args = []): void
{
$event = implode('\\', [Events::class, ucfirst($name)]);
- return $this->fireModelEvent(new $event($this, ...$args));
+ $this->fireModelEvent(new $event($this, ...$args));
}
/**
* Fire a model event.
- *
- * @param Event $event
- * @return mixed
*/
- protected function fireModelEvent(Event $event)
+ protected function fireModelEvent(Event $event): void
{
- return static::getConnectionContainer()->getEventDispatcher()->fire($event);
+ static::getConnectionContainer()->getDispatcher()->fire($event);
}
/**
* Listen to a model event.
- *
- * @param string $event
- * @param Closure $listener
- * @return mixed
*/
- protected function listenForModelEvent($event, Closure $listener)
+ protected function listenForModelEvent(string $event, Closure $listener): void
{
- return static::getConnectionContainer()->getEventDispatcher()->listen($event, $listener);
+ static::getConnectionContainer()->getDispatcher()->listen($event, $listener);
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasGlobalScopes.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasGlobalScopes.php
index 4d0f2968f..855ba37c3 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasGlobalScopes.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasGlobalScopes.php
@@ -12,43 +12,33 @@ trait HasGlobalScopes
/**
* Register a new global scope on the model.
*
- * @param Scope|Closure|string $scope
- * @param Closure|null $implementation
- * @return mixed
- *
* @throws InvalidArgumentException
*/
- public static function addGlobalScope($scope, Closure $implementation = null)
+ public static function addGlobalScope(Scope|Closure|string $scope, ?Closure $implementation = null): void
{
if (is_string($scope) && ! is_null($implementation)) {
- return static::$globalScopes[static::class][$scope] = $implementation;
+ static::$globalScopes[static::class][$scope] = $implementation;
} elseif ($scope instanceof Closure) {
- return static::$globalScopes[static::class][spl_object_hash($scope)] = $scope;
+ static::$globalScopes[static::class][spl_object_hash($scope)] = $scope;
} elseif ($scope instanceof Scope) {
- return static::$globalScopes[static::class][get_class($scope)] = $scope;
+ static::$globalScopes[static::class][get_class($scope)] = $scope;
+ } else {
+ throw new InvalidArgumentException('Global scope must be an instance of Closure or Scope.');
}
-
- throw new InvalidArgumentException('Global scope must be an instance of Closure or Scope.');
}
/**
* Determine if a model has a global scope.
- *
- * @param Scope|string $scope
- * @return bool
*/
- public static function hasGlobalScope($scope)
+ public static function hasGlobalScope(Scope|string $scope): bool
{
return ! is_null(static::getGlobalScope($scope));
}
/**
* Get a global scope registered with the model.
- *
- * @param Scope|string $scope
- * @return Scope|Closure|null
*/
- public static function getGlobalScope($scope)
+ public static function getGlobalScope(Scope|string $scope): Scope|Closure|null
{
if (array_key_exists(static::class, static::$globalScopes)) {
$scopeName = is_string($scope) ? $scope : get_class($scope);
@@ -57,14 +47,14 @@ trait HasGlobalScopes
? static::$globalScopes[static::class][$scopeName]
: null;
}
+
+ return null;
}
/**
* Get the global scopes for this class instance.
- *
- * @return array
*/
- public function getGlobalScopes()
+ public function getGlobalScopes(): array
{
return array_key_exists(static::class, static::$globalScopes)
? static::$globalScopes[static::class]
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasPassword.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasPassword.php
index 194efa8cf..c84bd977d 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasPassword.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasPassword.php
@@ -12,13 +12,11 @@ trait HasPassword
/**
* Set the password on the user.
*
- * @param string|array $password
- *
* @throws ConnectionException
*/
- public function setPasswordAttribute($password)
+ public function setPasswordAttribute(array|string $password): void
{
- $this->validateSecureConnection();
+ $this->assertSecureConnection();
// Here we will attempt to determine the password hash method in use
// by parsing the users hashed password (if it as available). If a
@@ -49,31 +47,25 @@ trait HasPassword
/**
* Alias for setting the password on the user.
*
- * @param string|array $password
- *
* @throws ConnectionException
*/
- public function setUnicodepwdAttribute($password)
+ public function setUnicodepwdAttribute(array|string $password): void
{
$this->setPasswordAttribute($password);
}
/**
* An accessor for retrieving the user's hashed password value.
- *
- * @return string|null
*/
- public function getPasswordAttribute()
+ public function getPasswordAttribute(): ?string
{
return $this->getAttribute($this->getPasswordAttributeName())[0] ?? null;
}
/**
* Get the name of the attribute that contains the user's password.
- *
- * @return string
*/
- public function getPasswordAttributeName()
+ public function getPasswordAttributeName(): string
{
if (property_exists($this, 'passwordAttribute')) {
return $this->passwordAttribute;
@@ -88,10 +80,8 @@ trait HasPassword
/**
* Get the name of the method to use for hashing the user's password.
- *
- * @return string
*/
- public function getPasswordHashMethod()
+ public function getPasswordHashMethod(): string
{
if (property_exists($this, 'passwordHashMethod')) {
return $this->passwordHashMethod;
@@ -106,13 +96,8 @@ trait HasPassword
/**
* Set the changed password.
- *
- * @param string $oldPassword
- * @param string $newPassword
- * @param string $attribute
- * @return void
*/
- protected function setChangedPassword($oldPassword, $newPassword, $attribute)
+ protected function setChangedPassword(string $oldPassword, string $newPassword, string $attribute): void
{
// Create batch modification for removing the old password.
$this->addModification(
@@ -135,13 +120,15 @@ trait HasPassword
/**
* Set the password on the model.
- *
- * @param string $password
- * @param string $attribute
- * @return void
*/
- protected function setPassword($password, $attribute)
+ protected function setPassword(string $password, string $attribute): void
{
+ if (! $this->exists) {
+ $this->setRawAttribute($attribute, $password);
+
+ return;
+ }
+
$this->addModification(
$this->newBatchModification(
$attribute,
@@ -154,14 +141,9 @@ trait HasPassword
/**
* Encode / hash the given password.
*
- * @param string $method
- * @param string $password
- * @param string $salt
- * @return string
- *
* @throws LdapRecordException
*/
- protected function getHashedPassword($method, $password, $salt = null)
+ protected function getHashedPassword(string $method, string $password, ?string $salt = null): string
{
if (! method_exists(Password::class, $method)) {
throw new LdapRecordException("Password hashing method [{$method}] does not exist.");
@@ -177,18 +159,22 @@ trait HasPassword
/**
* Validates that the current LDAP connection is secure.
*
- * @return void
- *
* @throws ConnectionException
*/
- protected function validateSecureConnection()
+ protected function assertSecureConnection(): void
{
$connection = $this->getConnection();
+ $config = $connection->getConfiguration();
+
+ if ($config->get('allow_insecure_password_changes') === true) {
+ return;
+ }
+
if ($connection->isConnected()) {
$secure = $connection->getLdapConnection()->canChangePasswords();
} else {
- $secure = $connection->getConfiguration()->get('use_ssl') || $connection->getConfiguration()->get('use_tls');
+ $secure = $config->get('use_ssl') || $config->get('use_tls');
}
if (! $secure) {
@@ -200,14 +186,11 @@ trait HasPassword
/**
* Attempt to retrieve the password's salt.
- *
- * @param string $method
- * @return string|null
*/
- public function getPasswordSalt($method)
+ public function getPasswordSalt(string $method): ?string
{
if (! Password::hashMethodRequiresSalt($method)) {
- return;
+ return null;
}
return Password::getSalt($this->password);
@@ -234,15 +217,11 @@ trait HasPassword
$value = null
);
- switch ($algo) {
- case Password::CRYPT_SALT_TYPE_MD5:
- return 'md5'.$method;
- case Password::CRYPT_SALT_TYPE_SHA256:
- return 'sha256'.$method;
- case Password::CRYPT_SALT_TYPE_SHA512:
- return 'sha512'.$method;
- default:
- return $method;
- }
+ return match ((int) $algo) {
+ Password::CRYPT_SALT_TYPE_MD5 => 'md5'.$method,
+ Password::CRYPT_SALT_TYPE_SHA256 => 'sha256'.$method,
+ Password::CRYPT_SALT_TYPE_SHA512 => 'sha512'.$method,
+ default => $method,
+ };
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasRelationships.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasRelationships.php
index 87c0a7cc8..e81c3a15e 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasRelationships.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasRelationships.php
@@ -12,61 +12,47 @@ trait HasRelationships
{
/**
* Returns a new has one relationship.
- *
- * @param mixed $related
- * @param string $relationKey
- * @param string $foreignKey
- * @return HasOne
*/
- public function hasOne($related, $relationKey, $foreignKey = 'dn')
+ public function hasOne(array|string $related, string $relationKey, string $foreignKey = 'dn'): HasOne
{
return new HasOne($this->newQuery(), $this, $related, $relationKey, $foreignKey);
}
/**
* Returns a new has many relationship.
- *
- * @param mixed $related
- * @param string $relationKey
- * @param string $foreignKey
- * @return HasMany
*/
- public function hasMany($related, $relationKey, $foreignKey = 'dn')
+ public function hasMany(array|string $related, string $relationKey, string $foreignKey = 'dn'): HasMany
{
return new HasMany($this->newQuery(), $this, $related, $relationKey, $foreignKey, $this->guessRelationshipName());
}
/**
* Returns a new has many in relationship.
- *
- * @param mixed $related
- * @param string $relationKey
- * @param string $foreignKey
- * @return HasManyIn
*/
- public function hasManyIn($related, $relationKey, $foreignKey = 'dn')
+ public function hasManyIn(array|string $related, string $relationKey, string $foreignKey = 'dn'): HasManyIn
{
return new HasManyIn($this->newQuery(), $this, $related, $relationKey, $foreignKey, $this->guessRelationshipName());
}
/**
* Get a relationship by its name.
- *
- * @param string $relationName
- * @return Relation|null
*/
- public function getRelation($relationName)
+ public function getRelation(?string $relationName = null): ?Relation
{
+ if (is_null($relationName)) {
+ return null;
+ }
+
if (! method_exists($this, $relationName)) {
- return;
+ return null;
}
if (! $relation = $this->{$relationName}()) {
- return;
+ return null;
}
if (! $relation instanceof Relation) {
- return;
+ return null;
}
return $relation;
@@ -74,10 +60,8 @@ trait HasRelationships
/**
* Get the relationships name.
- *
- * @return string|null
*/
- protected function guessRelationshipName()
+ protected function guessRelationshipName(): ?string
{
return Arr::last(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3))['function'];
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasScopes.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasScopes.php
index cb227fecc..7420620ce 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasScopes.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HasScopes.php
@@ -2,38 +2,34 @@
namespace LdapRecord\Models\Concerns;
+use LdapRecord\Query\Model\Builder;
+
/** @mixin \LdapRecord\Models\Model */
trait HasScopes
{
/**
* Begin querying the direct descendants of the model.
- *
- * @return \LdapRecord\Query\Model\Builder
*/
- public function descendants()
+ public function descendants(): Builder
{
- return $this->in($this->getDn())->listing();
+ return $this->in($this->getDn())->list();
}
/**
* Begin querying the direct ancestors of the model.
- *
- * @return \LdapRecord\Query\Model\Builder
*/
- public function ancestors()
+ public function ancestors(): Builder
{
$parent = $this->getParentDn($this->getDn());
- return $this->in($this->getParentDn($parent))->listing();
+ return $this->in($this->getParentDn($parent))->list();
}
/**
* Begin querying the direct siblings of the model.
- *
- * @return \LdapRecord\Query\Model\Builder
*/
- public function siblings()
+ public function siblings(): Builder
{
- return $this->in($this->getParentDn($this->getDn()))->listing();
+ return $this->in($this->getParentDn($this->getDn()))->list();
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HidesAttributes.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HidesAttributes.php
index ecd328dab..533e8fc58 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HidesAttributes.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/HidesAttributes.php
@@ -13,37 +13,29 @@ trait HidesAttributes
{
/**
* The attributes that should be hidden for serialization.
- *
- * @var array
*/
- protected $hidden = [];
+ protected array $hidden = [];
/**
* The attributes that should be visible in serialization.
- *
- * @var array
*/
- protected $visible = [];
+ protected array $visible = [];
/**
* Get the hidden attributes for the model.
- *
- * @return array
*/
- public function getHidden()
+ public function getHidden(): array
{
- return array_map(function ($key) {
- return $this->normalizeAttributeKey($key);
- }, $this->hidden);
+ return array_map(
+ $this->normalizeAttributeKey(...),
+ $this->hidden
+ );
}
/**
* Set the hidden attributes for the model.
- *
- * @param array $hidden
- * @return $this
*/
- public function setHidden(array $hidden)
+ public function setHidden(array $hidden): static
{
$this->hidden = $hidden;
@@ -52,11 +44,8 @@ trait HidesAttributes
/**
* Add hidden attributes for the model.
- *
- * @param array|string|null $attributes
- * @return void
*/
- public function addHidden($attributes = null)
+ public function addHidden(array|string|null $attributes = null): void
{
$this->hidden = array_merge(
$this->hidden,
@@ -66,23 +55,19 @@ trait HidesAttributes
/**
* Get the visible attributes for the model.
- *
- * @return array
*/
- public function getVisible()
+ public function getVisible(): array
{
- return array_map(function ($key) {
- return $this->normalizeAttributeKey($key);
- }, $this->visible);
+ return array_map(
+ $this->normalizeAttributeKey(...),
+ $this->visible
+ );
}
/**
* Set the visible attributes for the model.
- *
- * @param array $visible
- * @return $this
*/
- public function setVisible(array $visible)
+ public function setVisible(array $visible): static
{
$this->visible = $visible;
@@ -91,11 +76,8 @@ trait HidesAttributes
/**
* Add visible attributes for the model.
- *
- * @param array|string|null $attributes
- * @return void
*/
- public function addVisible($attributes = null)
+ public function addVisible(array|string|null $attributes = null): void
{
$this->visible = array_merge(
$this->visible,
@@ -105,11 +87,8 @@ trait HidesAttributes
/**
* Make the given, typically hidden, attributes visible.
- *
- * @param array|string $attributes
- * @return $this
*/
- public function makeVisible($attributes)
+ public function makeVisible(array|string $attributes): static
{
$this->hidden = array_diff($this->hidden, (array) $attributes);
@@ -122,11 +101,8 @@ trait HidesAttributes
/**
* Make the given, typically visible, attributes hidden.
- *
- * @param array|string $attributes
- * @return $this
*/
- public function makeHidden($attributes)
+ public function makeHidden(array|string $attributes): static
{
$attributes = (array) $attributes;
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesAndRestoresPropertyValues.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesAndRestoresPropertyValues.php
index cf550c749..bc4fa28cd 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesAndRestoresPropertyValues.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesAndRestoresPropertyValues.php
@@ -7,12 +7,8 @@ trait SerializesAndRestoresPropertyValues
{
/**
* Get the property value prepared for serialization.
- *
- * @param string $property
- * @param mixed $value
- * @return mixed
*/
- protected function getSerializedPropertyValue($property, $value)
+ protected function getSerializedPropertyValue(string $property, mixed $value): mixed
{
if ($property === 'original') {
return $this->originalToArray();
@@ -27,12 +23,8 @@ trait SerializesAndRestoresPropertyValues
/**
* Get the unserialized property value after deserialization.
- *
- * @param string $property
- * @param mixed $value
- * @return mixed
*/
- protected function getUnserializedPropertyValue($property, $value)
+ protected function getUnserializedPropertyValue(string $property, mixed $value): mixed
{
if ($property === 'original') {
return $this->arrayToOriginal($value);
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesProperties.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesProperties.php
index 91f4bcfe3..65428fa40 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesProperties.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Concerns/SerializesProperties.php
@@ -11,10 +11,8 @@ trait SerializesProperties
/**
* Prepare the attributes for serialization.
- *
- * @return array
*/
- public function __sleep()
+ public function __sleep(): array
{
$properties = (new ReflectionClass($this))->getProperties();
@@ -25,17 +23,15 @@ trait SerializesProperties
));
}
- return array_values(array_filter(array_map(function ($p) {
- return $p->isStatic() ? null : $p->getName();
- }, $properties)));
+ return array_values(array_filter(
+ array_map(fn ($p) => $p->isStatic() ? null : $p->getName(), $properties)
+ ));
}
/**
* Restore the attributes after serialization.
- *
- * @return void
*/
- public function __wakeup()
+ public function __wakeup(): void
{
foreach ((new ReflectionClass($this))->getProperties() as $property) {
if ($property->isStatic()) {
@@ -51,10 +47,8 @@ trait SerializesProperties
/**
* Prepare the model for serialization.
- *
- * @return array
*/
- public function __serialize()
+ public function __serialize(): array
{
$values = [];
@@ -92,11 +86,8 @@ trait SerializesProperties
/**
* Restore the model after serialization.
- *
- * @param array $values
- * @return void
*/
- public function __unserialize(array $values)
+ public function __unserialize(array $values): void
{
$properties = (new ReflectionClass($this))->getProperties();
@@ -130,11 +121,8 @@ trait SerializesProperties
/**
* Get the property value for the given property.
- *
- * @param ReflectionProperty $property
- * @return mixed
*/
- protected function getPropertyValue(ReflectionProperty $property)
+ protected function getPropertyValue(ReflectionProperty $property): mixed
{
$property->setAccessible(true);
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DetectsResetIntegers.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DetectsResetIntegers.php
index 7b8d1830e..1f2e826bf 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DetectsResetIntegers.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DetectsResetIntegers.php
@@ -10,12 +10,9 @@ trait DetectsResetIntegers
* The integer values '0' and '-1' can be used on certain
* LDAP attributes to instruct the server to reset the
* value to an 'unset' or 'cleared' state.
- *
- * @param mixed $value
- * @return bool
*/
- protected function valueIsResetInteger($value)
+ protected function valueIsResetInteger(mixed $value): bool
{
- return in_array($value, [0, -1], $strict = true);
+ return in_array($value, [0, -1], true);
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Entry.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Entry.php
index a67200e94..947daca1a 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Entry.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Entry.php
@@ -9,8 +9,6 @@ class Entry extends Model implements DirectoryServer
{
/**
* The attribute key that contains the models object GUID.
- *
- * @var string
*/
- protected $guidKey = 'gidNumber';
+ protected string $guidKey = 'gidNumber';
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Group.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Group.php
index 49a6e0aae..c5b0c17d8 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Group.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/Group.php
@@ -6,10 +6,8 @@ class Group extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'groupOfUniqueNames',
'posixGroup',
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/User.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/User.php
index 430588b0a..4a3bc143c 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/User.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/DirectoryServer/User.php
@@ -6,10 +6,8 @@ class User extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'nsPerson',
'nsAccount',
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Event.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Event.php
index 8dbd1d29a..340bc2ea5 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Event.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Event.php
@@ -8,15 +8,11 @@ abstract class Event
{
/**
* The model that the event is being triggered on.
- *
- * @var Model
*/
- protected $model;
+ protected Model $model;
/**
* Constructor.
- *
- * @param Model $model
*/
public function __construct(Model $model)
{
@@ -24,11 +20,9 @@ abstract class Event
}
/**
- * Returns the model that generated the event.
- *
- * @return Model
+ * Get the model that generated the event.
*/
- public function getModel()
+ public function getModel(): Model
{
return $this->model;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Renaming.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Renaming.php
index 5e7be97d7..4890e2bfc 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Renaming.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Events/Renaming.php
@@ -8,26 +8,18 @@ class Renaming extends Event
{
/**
* The models RDN.
- *
- * @var string
*/
- protected $rdn;
+ protected string $rdn;
/**
* The models new parent DN.
- *
- * @var string
*/
- protected $newParentDn;
+ protected string $newParentDn;
/**
* Constructor.
- *
- * @param Model $model
- * @param string $rdn
- * @param string $newParentDn
*/
- public function __construct(Model $model, $rdn, $newParentDn)
+ public function __construct(Model $model, string $rdn, string $newParentDn)
{
parent::__construct($model);
@@ -37,20 +29,16 @@ class Renaming extends Event
/**
* Get the models RDN.
- *
- * @return string
*/
- public function getRdn()
+ public function getRdn(): string
{
return $this->rdn;
}
/**
* Get the models parent DN.
- *
- * @return string
*/
- public function getNewParentDn()
+ public function getNewParentDn(): string
{
return $this->newParentDn;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Entry.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Entry.php
index be6322b15..4f29ef033 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Entry.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Entry.php
@@ -13,41 +13,34 @@ class Entry extends BaseEntry implements FreeIPA
{
/**
* The attribute key that contains the models object GUID.
- *
- * @var string
*/
- protected $guidKey = 'ipauniqueid';
+ protected string $guidKey = 'ipauniqueid';
/**
* The default attributes that should be mutated to dates.
- *
- * @var array
*/
- protected $defaultDates = [
+ protected array $defaultDates = [
'krblastpwdchange' => 'ldap',
'krbpasswordexpiration' => 'ldap',
];
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- protected static function boot()
+ protected static function boot(): void
{
parent::boot();
// Here we'll add a global scope to all FreeIPA models to ensure the
// Entry UUID is always selected on each query. This attribute is
// virtual, so it must be manually selected to be included.
- static::addGlobalScope(new AddEntryUuidToSelects());
+ static::addGlobalScope(new AddEntryUuidToSelects);
}
/**
* Create a new query builder.
- *
- * @param Connection $connection
- * @return FreeIpaBuilder
*/
- public function newQueryBuilder(Connection $connection)
+ public function newQueryBuilder(Connection $connection): FreeIpaBuilder
{
return new FreeIpaBuilder($connection);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Group.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Group.php
index 10fd93404..941977595 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Group.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Group.php
@@ -2,14 +2,14 @@
namespace LdapRecord\Models\FreeIPA;
+use LdapRecord\Models\Relations\HasMany;
+
class Group extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'groupofnames',
'nestedgroup',
@@ -20,21 +20,17 @@ class Group extends Entry
/**
* The groups relationship.
*
- * Retrieves groups that the current group is apart of.
- *
- * @return \LdapRecord\Models\Relations\HasMany
+ * Retrieves groups that the current group is a part of.
*/
- public function groups()
+ public function groups(): HasMany
{
return $this->hasMany(self::class, 'member');
}
/**
* Retrieve the members of the group.
- *
- * @return \LdapRecord\Models\Relations\HasMany
*/
- public function members()
+ public function members(): HasMany
{
return $this->hasMany(User::class, 'memberof')->using($this, 'member');
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Scopes/AddEntryUuidToSelects.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Scopes/AddEntryUuidToSelects.php
index 581b5beed..d35ed9141 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Scopes/AddEntryUuidToSelects.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/Scopes/AddEntryUuidToSelects.php
@@ -10,12 +10,8 @@ class AddEntryUuidToSelects implements Scope
{
/**
* Add the entry UUID to the selected attributes.
- *
- * @param Builder $query
- * @param Model $model
- * @return void
*/
- public function apply(Builder $query, Model $model)
+ public function apply(Builder $query, Model $model): void
{
empty($query->columns)
? $query->addSelect(['*', $model->getGuidKey()])
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/User.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/User.php
index 24c7f3b7d..47964f010 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/User.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/FreeIPA/User.php
@@ -2,14 +2,14 @@
namespace LdapRecord\Models\FreeIPA;
+use LdapRecord\Models\Relations\HasMany;
+
class User extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'person',
'inetorgperson',
@@ -17,11 +17,9 @@ class User extends Entry
];
/**
- * Retrieve groups that the current user is apart of.
- *
- * @return \LdapRecord\Models\Relations\HasMany
+ * Retrieve groups that the current user is a part of.
*/
- public function groups()
+ public function groups(): HasMany
{
return $this->hasMany(Group::class, 'member');
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Model.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Model.php
index 932c1a3b1..b17d0793a 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Model.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Model.php
@@ -11,110 +11,92 @@ use LdapRecord\Container;
use LdapRecord\EscapesValues;
use LdapRecord\Models\Attributes\DistinguishedName;
use LdapRecord\Models\Attributes\Guid;
+use LdapRecord\Query\Builder as BaseBuilder;
use LdapRecord\Query\Model\Builder;
use LdapRecord\Support\Arr;
+use RuntimeException;
+use Stringable;
use UnexpectedValueException;
/** @mixin Builder */
-abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
+abstract class Model implements Arrayable, ArrayAccess, JsonSerializable, Stringable
{
- use EscapesValues;
- use Concerns\HasEvents;
- use Concerns\HasScopes;
use Concerns\HasAttributes;
+ use Concerns\HasEvents;
use Concerns\HasGlobalScopes;
- use Concerns\HidesAttributes;
use Concerns\HasRelationships;
+ use Concerns\HasScopes;
+ use Concerns\HidesAttributes;
use Concerns\SerializesProperties;
+ use EscapesValues;
/**
* Indicates if the model exists in the directory.
- *
- * @var bool
*/
- public $exists = false;
+ public bool $exists = false;
/**
* Indicates whether the model was created during the current request lifecycle.
- *
- * @var bool
*/
- public $wasRecentlyCreated = false;
+ public bool $wasRecentlyCreated = false;
/**
* Indicates whether the model was renamed during the current request lifecycle.
- *
- * @var bool
*/
- public $wasRecentlyRenamed = false;
+ public bool $wasRecentlyRenamed = false;
/**
* The models distinguished name.
- *
- * @var string|null
*/
- protected $dn;
+ protected ?string $dn = null;
/**
* The base DN of where the model should be created in.
- *
- * @var string|null
*/
- protected $in;
+ protected ?string $in = null;
/**
* The object classes of the model.
- *
- * @var array
*/
- public static $objectClasses = [];
+ public static array $objectClasses = [];
/**
* The connection container instance.
- *
- * @var Container
*/
- protected static $container;
+ protected static ?Container $container = null;
/**
* The connection name for the model.
- *
- * @var string|null
*/
- protected $connection;
+ protected ?string $connection = null;
/**
- * The attribute key that contains the models object GUID.
- *
- * @var string
+ * The attribute key containing the models object GUID.
*/
- protected $guidKey = 'objectguid';
+ protected string $guidKey = 'objectguid';
/**
- * Contains the models modifications.
- *
- * @var array
+ * The array of the model's modifications.
*/
- protected $modifications = [];
-
- /**
- * The array of global scopes on the model.
- *
- * @var array
- */
- protected static $globalScopes = [];
+ protected array $modifications = [];
/**
* The array of booted models.
- *
- * @var array
*/
- protected static $booted = [];
+ protected static array $booted = [];
+
+ /**
+ * The array of global scopes on the model.
+ */
+ protected static array $globalScopes = [];
+
+ /**
+ * The morph model cache containing object classes and their corresponding models.
+ */
+ protected static array $morphCache = [];
/**
* Constructor.
- *
- * @param array $attributes
*/
public function __construct(array $attributes = [])
{
@@ -125,10 +107,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Check if the model needs to be booted and if so, do it.
- *
- * @return void
*/
- protected function bootIfNotBooted()
+ protected function bootIfNotBooted(): void
{
if (! isset(static::$booted[static::class])) {
static::$booted[static::class] = true;
@@ -139,20 +119,16 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* The "boot" method of the model.
- *
- * @return void
*/
- protected static function boot()
+ protected static function boot(): void
{
//
}
/**
- * Clear the list of booted models so they will be re-booted.
- *
- * @return void
+ * Clear the list of booted models, so they will be re-booted.
*/
- public static function clearBootedModels()
+ public static function clearBootedModels(): void
{
static::$booted = [];
@@ -161,12 +137,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Handle dynamic method calls into the model.
- *
- * @param string $method
- * @param array $parameters
- * @return mixed
*/
- public function __call($method, $parameters)
+ public function __call(string $method, array $parameters): mixed
{
if (method_exists($this, $method)) {
return $this->$method(...$parameters);
@@ -177,88 +149,66 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Handle dynamic static method calls into the method.
- *
- * @param string $method
- * @param array $parameters
- * @return mixed
*/
- public static function __callStatic($method, $parameters)
+ public static function __callStatic(string $method, array $parameters): mixed
{
- return (new static())->$method(...$parameters);
+ return (new static)->$method(...$parameters);
}
/**
- * Returns the models distinguished name.
- *
- * @return string|null
+ * Get the models distinguished name.
*/
- public function getDn()
+ public function getDn(): ?string
{
return $this->dn;
}
/**
- * Set the models distinguished name.
- *
- * @param string $dn
- * @return $this
+ * Set the model's distinguished name.
*/
- public function setDn($dn)
+ public function setDn(?string $dn = null): static
{
- $this->dn = (string) $dn;
+ $this->dn = $dn;
return $this;
}
/**
- * A mutator for setting the models distinguished name.
- *
- * @param string $dn
- * @return $this
+ * A mutator for setting the model's distinguished name.
*/
- public function setDnAttribute($dn)
+ public function setDnAttribute(string $dn): static
{
return $this->setRawAttribute('dn', $dn)->setDn($dn);
}
/**
- * A mutator for setting the models distinguished name.
- *
- * @param string $dn
- * @return $this
+ * A mutator for setting the model's distinguished name.
*/
- public function setDistinguishedNameAttribute($dn)
+ public function setDistinguishedNameAttribute(string $dn): static
{
return $this->setRawAttribute('distinguishedname', $dn)->setDn($dn);
}
/**
* Get the connection for the model.
- *
- * @return Connection
*/
- public function getConnection()
+ public function getConnection(): Connection
{
return static::resolveConnection($this->getConnectionName());
}
/**
* Get the current connection name for the model.
- *
- * @return string
*/
- public function getConnectionName()
+ public function getConnectionName(): ?string
{
return $this->connection;
}
/**
* Set the connection associated with the model.
- *
- * @param string $name
- * @return $this
*/
- public function setConnection($name)
+ public function setConnection(?string $name = null): static
{
$this->connection = $name;
@@ -267,24 +217,18 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Make a new model instance.
- *
- * @param array $attributes
- * @return static
*/
- public static function make($attributes = [])
+ public static function make(array $attributes = []): static
{
return new static($attributes);
}
/**
* Begin querying the model on a given connection.
- *
- * @param string|null $connection
- * @return Builder
*/
- public static function on($connection = null)
+ public static function on(?string $connection = null): Builder
{
- $instance = new static();
+ $instance = new static;
$instance->setConnection($connection);
@@ -293,11 +237,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Get all the models from the directory.
- *
- * @param array|mixed $attributes
- * @return Collection|static[]
*/
- public static function all($attributes = ['*'])
+ public static function all(array|string $attributes = ['*']): array|Collection
{
return static::query()->select($attributes)->paginate();
}
@@ -305,17 +246,15 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Get the RootDSE (AD schema) record from the directory.
*
- * @param string|null $connection
- * @return Model
- *
* @throws \LdapRecord\Models\ModelNotFoundException
*/
- public static function getRootDse($connection = null)
+ public static function getRootDse(?string $connection = null): Model
{
+ /** @var Model $model */
$model = static::getRootDseModel();
return $model::on($connection ?? (new $model)->getConnectionName())
- ->in(null)
+ ->in()
->read()
->whereHas('objectclass')
->firstOrFail();
@@ -326,40 +265,31 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
*
* @return class-string
*/
- protected static function getRootDseModel()
+ protected static function getRootDseModel(): string
{
- $instance = (new static);
+ $instance = new static;
- switch (true) {
- case $instance instanceof Types\ActiveDirectory:
- return ActiveDirectory\Entry::class;
- case $instance instanceof Types\DirectoryServer:
- return OpenLDAP\Entry::class;
- case $instance instanceof Types\OpenLDAP:
- return OpenLDAP\Entry::class;
- case $instance instanceof Types\FreeIPA:
- return FreeIPA\Entry::class;
- default:
- return Entry::class;
- }
+ return match (true) {
+ $instance instanceof Types\ActiveDirectory => ActiveDirectory\Entry::class,
+ $instance instanceof Types\DirectoryServer => DirectoryServer\Entry::class,
+ $instance instanceof Types\OpenLDAP => OpenLDAP\Entry::class,
+ $instance instanceof Types\FreeIPA => FreeIPA\Entry::class,
+ default => Entry::class,
+ };
}
/**
* Begin querying the model.
- *
- * @return Builder
*/
- public static function query()
+ public static function query(): Builder
{
- return (new static())->newQuery();
+ return (new static)->newQuery();
}
/**
* Get a new query for builder filtered by the current models object classes.
- *
- * @return Builder
*/
- public function newQuery()
+ public function newQuery(): Builder
{
return $this->registerModelScopes(
$this->newQueryWithoutScopes()
@@ -368,10 +298,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Get a new query builder that doesn't have any global scopes.
- *
- * @return Builder
*/
- public function newQueryWithoutScopes()
+ public function newQueryWithoutScopes(): Builder
{
return static::resolveConnection(
$this->getConnectionName()
@@ -380,85 +308,64 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Create a new query builder.
- *
- * @param Connection $connection
- * @return Builder
*/
- public function newQueryBuilder(Connection $connection)
+ public function newQueryBuilder(Connection $connection): Builder
{
return new Builder($connection);
}
/**
* Create a new model instance.
- *
- * @param array $attributes
- * @return static
*/
- public function newInstance(array $attributes = [])
+ public function newInstance(array $attributes = []): static
{
return (new static($attributes))->setConnection($this->getConnectionName());
}
/**
* Resolve a connection instance.
- *
- * @param string|null $connection
- * @return Connection
*/
- public static function resolveConnection($connection = null)
+ public static function resolveConnection(?string $connection = null): Connection
{
- return static::getConnectionContainer()->get($connection);
+ return static::getConnectionContainer()->getConnection($connection);
}
/**
* Get the connection container.
- *
- * @return Container
*/
- public static function getConnectionContainer()
+ public static function getConnectionContainer(): Container
{
return static::$container ?? static::getDefaultConnectionContainer();
}
/**
* Get the default singleton container instance.
- *
- * @return Container
*/
- public static function getDefaultConnectionContainer()
+ public static function getDefaultConnectionContainer(): Container
{
return Container::getInstance();
}
/**
* Set the connection container.
- *
- * @param Container $container
- * @return void
*/
- public static function setConnectionContainer(Container $container)
+ public static function setConnectionContainer(Container $container): void
{
static::$container = $container;
}
/**
* Unset the connection container.
- *
- * @return void
*/
- public static function unsetConnectionContainer()
+ public static function unsetConnectionContainer(): void
{
static::$container = null;
}
/**
* Register the query scopes for this builder instance.
- *
- * @param Builder $builder
- * @return Builder
*/
- public function registerModelScopes($builder)
+ public function registerModelScopes(Builder $builder): Builder
{
$this->applyObjectClassScopes($builder);
@@ -469,11 +376,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Register the global model scopes.
- *
- * @param Builder $builder
- * @return Builder
*/
- public function registerGlobalScopes($builder)
+ public function registerGlobalScopes(Builder $builder): Builder
{
foreach ($this->getGlobalScopes() as $identifier => $scope) {
$builder->withGlobalScope($identifier, $scope);
@@ -484,11 +388,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Apply the model object class scopes to the given builder instance.
- *
- * @param Builder $query
- * @return void
*/
- public function applyObjectClassScopes(Builder $query)
+ public function applyObjectClassScopes(Builder $query): void
{
foreach (static::$objectClasses as $objectClass) {
$query->where('objectclass', '=', $objectClass);
@@ -496,164 +397,121 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
}
/**
- * Returns the models distinguished name when the model is converted to a string.
- *
- * @return null|string
+ * Get the models distinguished name when the model is converted to a string.
*/
- public function __toString()
+ public function __toString(): string
{
- return $this->getDn();
+ return (string) $this->getDn();
}
/**
* Returns a new batch modification.
- *
- * @param string|null $attribute
- * @param string|int|null $type
- * @param array $values
- * @return BatchModification
*/
- public function newBatchModification($attribute = null, $type = null, $values = [])
+ public function newBatchModification(?string $attribute = null, ?int $type = null, array $values = []): BatchModification
{
return new BatchModification($attribute, $type, $values);
}
/**
* Returns a new collection with the specified items.
- *
- * @param mixed $items
- * @return Collection
*/
- public function newCollection($items = [])
+ public function newCollection(mixed $items = []): Collection
{
return new Collection($items);
}
/**
* Dynamically retrieve attributes on the object.
- *
- * @param string $key
- * @return mixed
*/
- public function __get($key)
+ public function __get(string $key): mixed
{
return $this->getAttribute($key);
}
/**
* Dynamically set attributes on the object.
- *
- * @param string $key
- * @param mixed $value
- * @return $this
*/
- public function __set($key, $value)
+ public function __set(string $key, mixed $value): void
{
- return $this->setAttribute($key, $value);
+ $this->setAttribute($key, $value);
}
/**
* Determine if the given offset exists.
- *
- * @param string $offset
- * @return bool
*/
#[\ReturnTypeWillChange]
- public function offsetExists($offset)
+ public function offsetExists(mixed $offset): bool
{
return ! is_null($this->getAttribute($offset));
}
/**
* Get the value for a given offset.
- *
- * @param string $offset
- * @return mixed
*/
#[\ReturnTypeWillChange]
- public function offsetGet($offset)
+ public function offsetGet(mixed $offset): mixed
{
return $this->getAttribute($offset);
}
/**
* Set the value at the given offset.
- *
- * @param string $offset
- * @param mixed $value
- * @return void
*/
#[\ReturnTypeWillChange]
- public function offsetSet($offset, $value)
+ public function offsetSet(mixed $offset, mixed $value): void
{
$this->setAttribute($offset, $value);
}
/**
* Unset the value at the given offset.
- *
- * @param string $offset
- * @return void
*/
#[\ReturnTypeWillChange]
- public function offsetUnset($offset)
+ public function offsetUnset(mixed $offset): void
{
unset($this->attributes[$offset]);
}
/**
* Determine if an attribute exists on the model.
- *
- * @param string $key
- * @return bool
*/
- public function __isset($key)
+ public function __isset(string $key): bool
{
return $this->offsetExists($key);
}
/**
* Unset an attribute on the model.
- *
- * @param string $key
- * @return void
*/
- public function __unset($key)
+ public function __unset(string $key): void
{
$this->offsetUnset($key);
}
/**
* Convert the model to its JSON encodeable array form.
- *
- * @return array
*/
- public function toArray()
+ public function toArray(): array
{
return $this->attributesToArray();
}
/**
* Convert the model's attributes into JSON encodeable values.
- *
- * @return array
*/
#[\ReturnTypeWillChange]
- public function jsonSerialize()
+ public function jsonSerialize(): array
{
return $this->toArray();
}
/**
* Convert the attributes for JSON serialization.
- *
- * @param array $attributes
- * @return array
*/
- protected function convertAttributesForJson(array $attributes = [])
+ protected function convertAttributesForJson(array $attributes = []): array
{
// If the model has a GUID set, we need to convert it to its
- // string format, due to it being in binary. Otherwise
+ // string format, due to it being in binary. Otherwise,
// we will receive a JSON serialization exception.
if (isset($attributes[$this->guidKey])) {
$attributes[$this->guidKey] = [$this->getConvertedGuid(
@@ -666,21 +524,25 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Convert the attributes from JSON serialization.
- *
- * @param array $attributes
- * @return array
*/
- protected function convertAttributesFromJson(array $attributes = [])
+ protected function convertAttributesFromJson(array $attributes = []): array
{
+ // Here we are converting the model's GUID and SID attributes
+ // back to their original values from serialization, so that
+ // their original value may be used and compared against.
+ if (isset($attributes[$this->guidKey])) {
+ $attributes[$this->guidKey] = [$this->getBinaryGuid(
+ Arr::first($attributes[$this->guidKey])
+ )];
+ }
+
return $attributes;
}
/**
* Reload a fresh model instance from the directory.
- *
- * @return static|false
*/
- public function fresh()
+ public function fresh(): static|false
{
if (! $this->exists) {
return false;
@@ -691,50 +553,106 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Determine if two models have the same distinguished name and belong to the same connection.
- *
- * @param Model|null $model
- * @return bool
*/
- public function is($model)
+ public function is(?Model $model = null): bool
{
return ! is_null($model)
- && $this->dn == $model->getDn()
- && $this->getConnectionName() == $model->getConnectionName();
+ && ! empty($this->dn)
+ && ! empty($model->getDn())
+ && $this->dn == $model->getDn()
+ && $this->getConnectionName() == $model->getConnectionName();
}
/**
* Determine if two models are not the same.
- *
- * @param Model|null $model
- * @return bool
*/
- public function isNot($model)
+ public function isNot(?Model $model = null): bool
{
return ! $this->is($model);
}
/**
* Hydrate a new collection of models from search results.
- *
- * @param array $records
- * @return Collection
*/
- public function hydrate($records)
+ public function hydrate(array $records): Collection
{
return $this->newCollection($records)->transform(function ($attributes) {
- return $attributes instanceof static
- ? $attributes
- : static::newInstance()->setRawAttributes($attributes);
+ if ($attributes instanceof static) {
+ return $attributes;
+ }
+
+ return static::newInstance()->setRawAttributes($attributes);
});
}
/**
- * Converts the current model into the given model.
- *
- * @param Model $into
- * @return Model
+ * Morph the model into a one of matching models using their object classes.
*/
- public function convert(self $into)
+ public function morphInto(array $models, ?callable $resolver = null): Model
+ {
+ if (class_exists($model = $this->determineMorphModel($this, $models, $resolver))) {
+ return $this->convert(new $model);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Morph the model into a one of matching models or throw an exception.
+ */
+ public function morphIntoOrFail(array $models, ?callable $resolver = null): Model
+ {
+ $model = $this->morphInto($models, $resolver);
+
+ if ($model instanceof $this) {
+ throw new RuntimeException(
+ 'The model could not be morphed into any of the given models.'
+ );
+ }
+
+ return $model;
+ }
+
+ /**
+ * Determine the model to morph into from the given models.
+ *
+ * @return class-string|bool
+ */
+ protected function determineMorphModel(Model $model, array $models, ?callable $resolver = null): string|bool
+ {
+ $morphModelMap = [];
+
+ foreach ($models as $modelClass) {
+ $morphModelMap[$modelClass] = static::$morphCache[$modelClass] ??= $this->normalizeObjectClasses(
+ $modelClass::$objectClasses
+ );
+ }
+
+ $objectClasses = $this->normalizeObjectClasses(
+ $model->getObjectClasses()
+ );
+
+ $resolver ??= function (array $objectClasses, array $morphModelMap) {
+ return array_search($objectClasses, $morphModelMap);
+ };
+
+ return $resolver($objectClasses, $morphModelMap);
+ }
+
+ /**
+ * Sort and normalize the object classes.
+ */
+ protected function normalizeObjectClasses(array $classes): array
+ {
+ sort($classes);
+
+ return array_map('strtolower', $classes);
+ }
+
+ /**
+ * Converts the current model into the given model.
+ */
+ public function convert(self $into): Model
{
$into->setDn($this->getDn());
$into->setConnection($this->getConnectionName());
@@ -748,10 +666,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Refreshes the current models attributes with the directory values.
- *
- * @return bool
*/
- public function refresh()
+ public function refresh(): bool
{
if ($model = $this->fresh()) {
$this->setRawAttributes($model->getAttributes());
@@ -764,10 +680,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Get the model's batch modifications to be processed.
- *
- * @return array
*/
- public function getModifications()
+ public function getModifications(): array
{
$builtModifications = [];
@@ -780,11 +694,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Set the models batch modifications.
- *
- * @param array $modifications
- * @return $this
*/
- public function setModifications(array $modifications = [])
+ public function setModifications(array $modifications = []): static
{
$this->modifications = [];
@@ -798,12 +709,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Adds a batch modification to the model.
*
- * @param array|BatchModification $mod
- * @return $this
- *
* @throws InvalidArgumentException
*/
- public function addModification($mod = [])
+ public function addModification(BatchModification|array $mod = []): static
{
if ($mod instanceof BatchModification) {
$mod = $mod->get();
@@ -822,85 +730,68 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Get the model's guid attribute key name.
- *
- * @return string
*/
- public function getGuidKey()
+ public function getGuidKey(): string
{
return $this->guidKey;
}
/**
* Get the model's ANR attributes for querying when incompatible with ANR.
- *
- * @return array
*/
- public function getAnrAttributes()
+ public function getAnrAttributes(): array
{
return ['cn', 'sn', 'uid', 'name', 'mail', 'givenname', 'displayname'];
}
/**
* Get the name of the model, or the given DN.
- *
- * @param string|null $dn
- * @return string|null
*/
- public function getName($dn = null)
+ public function getName(?string $dn = null): ?string
{
return $this->newDn($dn ?? $this->dn)->name();
}
/**
* Get the head attribute of the model, or the given DN.
- *
- * @param string|null $dn
- * @return string|null
*/
- public function getHead($dn = null)
+ public function getHead(?string $dn = null): ?string
{
return $this->newDn($dn ?? $this->dn)->head();
}
/**
* Get the RDN of the model, of the given DN.
- *
- * @param string|null
- * @return string|null
*/
- public function getRdn($dn = null)
+ public function getRdn(?string $dn = null): ?string
{
return $this->newDn($dn ?? $this->dn)->relative();
}
/**
* Get the parent distinguished name of the model, or the given DN.
- *
- * @param string|null
- * @return string|null
*/
- public function getParentDn($dn = null)
+ public function getParentDn(?string $dn = null): ?string
{
return $this->newDn($dn ?? $this->dn)->parent();
}
/**
- * Create a new Distinguished Name object.
- *
- * @param string|null $dn
- * @return DistinguishedName
+ * Create a new distinguished name.
*/
- public function newDn($dn = null)
+ public function newDn(?string $dn = null): DistinguishedName
{
+ if (! is_null($dn) && str_contains($dn, BaseBuilder::BASE_DN_PLACEHOLDER)) {
+ $dn = $this->newQuery()->substituteBaseDn($dn);
+ }
+
return new DistinguishedName($dn);
}
/**
* Get the model's object GUID key.
- *
- * @return string
*/
- public function getObjectGuidKey()
+ public function getObjectGuidKey(): string
{
return $this->guidKey;
}
@@ -909,76 +800,60 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
* Get the model's binary object GUID.
*
* @see https://msdn.microsoft.com/en-us/library/ms679021(v=vs.85).aspx
- *
- * @return string|null
*/
- public function getObjectGuid()
+ public function getObjectGuid(): ?string
{
return $this->getFirstAttribute($this->guidKey);
}
/**
* Get the model's object classes.
- *
- * @return array
*/
- public function getObjectClasses()
+ public function getObjectClasses(): array
{
return $this->getAttribute('objectclass', static::$objectClasses);
}
/**
* Get the model's string GUID.
- *
- * @param string|null $guid
- * @return string|null
*/
- public function getConvertedGuid($guid = null)
+ public function getConvertedGuid(?string $guid = null): ?string
{
try {
- return (string) $this->newObjectGuid(
- $guid ?? $this->getObjectGuid()
+ return $this->newObjectGuid(
+ (string) ($guid ?? $this->getObjectGuid())
);
- } catch (InvalidArgumentException $e) {
- return;
+ } catch (InvalidArgumentException) {
+ return null;
}
}
/**
* Get the model's binary GUID.
- *
- * @param string|null $guid
- * @return string|null
*/
- public function getBinaryGuid($guid = null)
+ public function getBinaryGuid(?string $guid = null): ?string
{
try {
return $this->newObjectGuid(
$guid ?? $this->getObjectGuid()
)->getBinary();
- } catch (InvalidArgumentException $e) {
- return;
+ } catch (InvalidArgumentException) {
+ return null;
}
}
/**
* Make a new object Guid instance.
- *
- * @param string $value
- * @return Guid
*/
- protected function newObjectGuid($value)
+ protected function newObjectGuid(string $value): Guid
{
return new Guid($value);
}
/**
* Determine if the current model is a direct descendant of the given.
- *
- * @param static|string $parent
- * @return bool
*/
- public function isChildOf($parent)
+ public function isChildOf(Model|string|null $parent = null): bool
{
return $this->newDn($this->getDn())->isChildOf(
$this->newDn((string) $parent)
@@ -986,12 +861,19 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
}
/**
- * Determine if the current model is a direct ascendant of the given.
- *
- * @param static|string $child
- * @return bool
+ * Determine if the current model is a sibling of the given.
*/
- public function isParentOf($child)
+ public function isSiblingOf(Model|string|null $model = null): bool
+ {
+ return $this->newDn($this->getDn())->isSiblingOf(
+ $this->newDn((string) $model)
+ );
+ }
+
+ /**
+ * Determine if the current model is a direct ascendant of the given.
+ */
+ public function isParentOf(Model|string|null $child = null): bool
{
return $this->newDn($this->getDn())->isParentOf(
$this->newDn((string) $child)
@@ -1000,34 +882,24 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Determine if the current model is a descendant of the given.
- *
- * @param static|string $model
- * @return bool
*/
- public function isDescendantOf($model)
+ public function isDescendantOf(Model|string|null $model = null): bool
{
return $this->dnIsInside($this->getDn(), $model);
}
/**
* Determine if the current model is a ancestor of the given.
- *
- * @param static|string $model
- * @return bool
*/
- public function isAncestorOf($model)
+ public function isAncestorOf(Model|string|null $model = null): bool
{
return $this->dnIsInside($model, $this->getDn());
}
/**
- * Determines if the DN is inside of the parent DN.
- *
- * @param static|string $dn
- * @param static|string $parentDn
- * @return bool
+ * Determine if the DN is inside the parent DN.
*/
- protected function dnIsInside($dn, $parentDn)
+ protected function dnIsInside(Model|string|null $dn = null, Model|string|null $parentDn = null): bool
{
return $this->newDn((string) $dn)->isDescendantOf(
$this->newDn($parentDn)
@@ -1036,11 +908,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Set the base DN of where the model should be created in.
- *
- * @param static|string $dn
- * @return $this
*/
- public function inside($dn)
+ public function inside(Model|string $dn): static
{
$this->in = $dn instanceof self ? $dn->getDn() : $dn;
@@ -1050,12 +919,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Save the model to the directory without raising any events.
*
- * @param array $attributes
- * @return void
- *
* @throws \LdapRecord\LdapRecordException
*/
- public function saveQuietly(array $attributes = [])
+ public function saveQuietly(array $attributes = []): void
{
static::withoutEvents(function () use ($attributes) {
$this->save($attributes);
@@ -1065,12 +931,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Save the model to the directory.
*
- * @param array $attributes The attributes to update or create for the current entry.
- * @return void
- *
* @throws \LdapRecord\LdapRecordException
*/
- public function save(array $attributes = [])
+ public function save(array $attributes = []): void
{
$this->fill($attributes);
@@ -1088,11 +951,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Inserts the model into the directory.
*
- * @return void
- *
* @throws \LdapRecord\LdapRecordException
*/
- protected function performInsert()
+ protected function performInsert(): void
{
// Here we will populate the models object classes if it
// does not already have any set. An LDAP object cannot
@@ -1112,11 +973,18 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
$this->dispatch('creating');
+ // Some PHP versions prevent non-numerically indexed arrays
+ // from being sent to the server. To resolve this, we will
+ // convert the attributes to numerically indexed arrays.
+ $attributes = array_map('array_values', array_filter($this->getAttributes()));
+
// Here we perform the insert of new object in the directory,
// but filter out any empty attributes before sending them
// to the server. LDAP servers will throw an exception if
// attributes have been given empty or null values.
- $query->insert($this->getDn(), array_filter($this->getAttributes()));
+ $this->dn = $query->insertAndGetDn($this->getDn(), $attributes);
+
+ $this->attributes = $attributes;
$this->dispatch('created');
@@ -1130,11 +998,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Updates the model in the directory.
*
- * @return void
- *
* @throws \LdapRecord\LdapRecordException
*/
- protected function performUpdate()
+ protected function performUpdate(): void
{
if (! count($modifications = $this->getModifications())) {
return;
@@ -1146,18 +1012,17 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
$this->dispatch('updated');
+ $this->syncChanges();
+
$this->syncOriginal();
}
/**
* Create the model in the directory.
*
- * @param array $attributes The attributes for the new entry.
- * @return Model
- *
* @throws \LdapRecord\LdapRecordException
*/
- public static function create(array $attributes = [])
+ public static function create(array $attributes = []): static
{
$instance = new static($attributes);
@@ -1167,22 +1032,18 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
}
/**
- * Create an attribute on the model.
- *
- * @param string $attribute The attribute to create
- * @param mixed $value The value of the new attribute
- * @return void
+ * Add an attribute on the model with the given value.
*
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
*/
- public function createAttribute($attribute, $value)
+ public function addAttribute(string $attribute, mixed $value): void
{
$this->assertExists();
$this->dispatch(['saving', 'updating']);
- $this->newQuery()->insertAttributes($this->dn, [$attribute => (array) $value]);
+ $this->newQuery()->add($this->dn, [$attribute => (array) $value]);
$this->addAttributeValue($attribute, $value);
@@ -1192,13 +1053,10 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Update the model.
*
- * @param array $attributes The attributes to update for the current entry.
- * @return void
- *
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
*/
- public function update(array $attributes = [])
+ public function update(array $attributes = []): void
{
$this->assertExists();
@@ -1208,20 +1066,16 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Update the model attribute with the specified value.
*
- * @param string $attribute The attribute to modify
- * @param mixed $value The new value for the attribute
- * @return void
- *
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
*/
- public function updateAttribute($attribute, $value)
+ public function replaceAttribute(string $attribute, mixed $value): void
{
$this->assertExists();
$this->dispatch(['saving', 'updating']);
- $this->newQuery()->updateAttributes($this->dn, [$attribute => (array) $value]);
+ $this->newQuery()->replace($this->dn, [$attribute => (array) $value]);
$this->addAttributeValue($attribute, $value);
@@ -1231,17 +1085,13 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Destroy the models for the given distinguished names.
*
- * @param Collection|array|string $dns
- * @param bool $recursive
- * @return int
- *
* @throws \LdapRecord\LdapRecordException
*/
- public static function destroy($dns, $recursive = false)
+ public static function destroy(mixed $dns, bool $recursive = false): int
{
$count = 0;
- $instance = new static();
+ $instance = new static;
if ($dns instanceof Collection) {
$dns = $dns->modelDns()->toArray();
@@ -1270,13 +1120,10 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
* Throws a ModelNotFoundException if the current model does
* not exist or does not contain a distinguished name.
*
- * @param bool $recursive Whether to recursively delete leaf nodes (models that are children).
- * @return void
- *
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
*/
- public function delete($recursive = false)
+ public function delete(bool $recursive = false): void
{
$this->assertExists();
@@ -1299,38 +1146,44 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Deletes leaf nodes that are attached to the model.
*
- * @return void
- *
* @throws \LdapRecord\LdapRecordException
*/
- protected function deleteLeafNodes()
+ protected function deleteLeafNodes(): void
{
$this->newQueryWithoutScopes()
->in($this->dn)
- ->listing()
+ ->list()
->each(function (Model $model) {
- $model->delete($recursive = true);
+ $model->delete(recursive: true);
});
}
/**
- * Delete an attribute on the model.
- *
- * @param string|array $attributes The attribute(s) to delete
- *
- * Delete specific values in attributes:
- *
- * ["memberuid" => "jdoe"]
- *
- * Delete an entire attribute:
- *
- * ["memberuid" => []]
- * @return void
+ * Remove an attribute on the model.
*
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
*/
- public function deleteAttribute($attributes)
+ public function removeAttribute(string $attribute, mixed $value = null): void
+ {
+ $this->removeAttributes([$attribute => $value]);
+ }
+
+ /**
+ * Remove an attribute on the model.
+ *
+ * Remove specific values in attributes:
+ *
+ * ["memberuid" => "jdoe"]
+ *
+ * Remove an entire attribute:
+ *
+ * ["memberuid" => []]
+ *
+ * @throws ModelDoesNotExistException
+ * @throws \LdapRecord\LdapRecordException
+ */
+ public function removeAttributes(array|string $attributes): void
{
$this->assertExists();
@@ -1338,7 +1191,7 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
$this->dispatch(['saving', 'updating']);
- $this->newQuery()->deleteAttributes($this->dn, $attributes);
+ $this->newQuery()->remove($this->dn, $attributes);
foreach ($attributes as $attribute => $value) {
// If the attribute value is empty, we can assume the
@@ -1364,11 +1217,8 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Make a deletable attribute array.
- *
- * @param string|array $attributes
- * @return array
*/
- protected function makeDeletableAttributes($attributes)
+ protected function makeDeletableAttributes(string|array $attributes): array
{
$delete = [];
@@ -1386,15 +1236,11 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
*
* For example: $user->move($ou);
*
- * @param static|string $newParentDn The new parent of the current model.
- * @param bool $deleteOldRdn Whether to delete the old models relative distinguished name once renamed / moved.
- * @return void
- *
* @throws UnexpectedValueException
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
*/
- public function move($newParentDn, $deleteOldRdn = true)
+ public function move(Model|string $newParentDn, bool $deleteOldRdn = true): void
{
$this->assertExists();
@@ -1408,15 +1254,10 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Rename the model to a new RDN and new parent.
*
- * @param string $rdn The models new relative distinguished name. Example: "cn=JohnDoe"
- * @param static|string|null $newParentDn The models new parent distinguished name (if moving). Leave this null if you are only renaming. Example: "ou=MovedUsers,dc=acme,dc=org"
- * @param bool|true $deleteOldRdn Whether to delete the old models relative distinguished name once renamed / moved.
- * @return void
- *
* @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException
*/
- public function rename($rdn, $newParentDn = null, $deleteOldRdn = true)
+ public function rename(string $rdn, Model|string|null $newParentDn = null, bool $deleteOldRdn = true): void
{
$this->assertExists();
@@ -1428,6 +1269,13 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
$newParentDn = $this->getParentDn($this->dn);
}
+ // If the RDN we have been given is empty when parsed, we must
+ // have been given a string, with no attribute. In this case,
+ // we will create a new RDN using the current DN's head.
+ if ($this->newDn($rdn)->isEmpty()) {
+ $rdn = $this->getUpdateableRdn($rdn);
+ }
+
// If the RDN and the new parent DN are the same as the current,
// we will simply return here to prevent a rename operation
// being sent, which would fail anyway in such case.
@@ -1438,21 +1286,12 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
return;
}
- // If the RDN we have been given is empty when parsed, we must
- // have been given a string, with no attribute. In this case,
- // we will create a new RDN using the current DN's head.
- if ($this->newDn($rdn)->isEmpty()) {
- $rdn = $this->getUpdateableRdn($rdn);
- }
-
$this->dispatch('renaming', [$rdn, $newParentDn]);
- $this->newQuery()->rename($this->dn, $rdn, $newParentDn, $deleteOldRdn);
-
// If the model was successfully renamed, we will set
// its new DN so any further updates to the model
// can be performed without any issues.
- $this->dn = implode(',', [$rdn, $newParentDn]);
+ $this->dn = $this->newQuery()->renameAndGetDn($this->dn, $rdn, $newParentDn, $deleteOldRdn);
$map = $this->newDn($this->dn)->assoc();
@@ -1471,24 +1310,17 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
}
/**
- * Get an updateable RDN for the model.
- *
- * @param string $name
- * @return string
+ * Get an updatable RDN for the model.
*/
- public function getUpdateableRdn($name)
+ public function getUpdateableRdn(string $name): string
{
return $this->getCreatableRdn($name, $this->newDn($this->dn)->head());
}
/**
* Get a distinguished name that is creatable for the model.
- *
- * @param string|null $name
- * @param string|null $attribute
- * @return string
*/
- public function getCreatableDn($name = null, $attribute = null)
+ public function getCreatableDn(?string $name = null, ?string $attribute = null): string
{
return implode(',', [
$this->getCreatableRdn($name, $attribute),
@@ -1498,39 +1330,30 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Get a creatable (escaped) RDN for the model.
- *
- * @param string|null $name
- * @param string|null $attribute
- * @return string
*/
- public function getCreatableRdn($name = null, $attribute = null)
+ public function getCreatableRdn(?string $name = null, ?string $attribute = null): string
{
$attribute = $attribute ?? $this->getCreatableRdnAttribute();
$name = $this->escape(
$name ?? $this->getFirstAttribute($attribute)
- )->dn();
+ )->forDn();
return "$attribute=$name";
}
/**
* Get the creatable RDN attribute name.
- *
- * @return string
*/
- protected function getCreatableRdnAttribute()
+ protected function getCreatableRdnAttribute(): string
{
return 'cn';
}
/**
- * Determines if the given modification is valid.
- *
- * @param mixed $mod
- * @return bool
+ * Determine if the given modification is valid.
*/
- protected function isValidModification($mod)
+ protected function isValidModification(mixed $mod): bool
{
return Arr::accessible($mod)
&& Arr::exists($mod, BatchModification::KEY_MODTYPE)
@@ -1542,7 +1365,7 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
*
* @return BatchModification[]
*/
- protected function buildModificationsFromDirty()
+ protected function buildModificationsFromDirty(): array
{
$modifications = [];
@@ -1569,25 +1392,9 @@ abstract class Model implements ArrayAccess, Arrayable, JsonSerializable
/**
* Throw an exception if the model does not exist.
*
- * @deprecated
- *
- * @return void
- *
* @throws ModelDoesNotExistException
*/
- protected function requireExistence()
- {
- return $this->assertExists();
- }
-
- /**
- * Throw an exception if the model does not exist.
- *
- * @return void
- *
- * @throws ModelDoesNotExistException
- */
- protected function assertExists()
+ protected function assertExists(): void
{
if (! $this->exists || is_null($this->dn)) {
throw ModelDoesNotExistException::forModel($this);
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ModelDoesNotExistException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ModelDoesNotExistException.php
index 508414911..98efa9865 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ModelDoesNotExistException.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/ModelDoesNotExistException.php
@@ -7,30 +7,22 @@ use LdapRecord\LdapRecordException;
class ModelDoesNotExistException extends LdapRecordException
{
/**
- * The class name of the model that does not exist.
- *
- * @var Model
+ * The instance of the model that does not exist.
*/
- protected $model;
+ protected Model $model;
/**
* Create a new exception for the given model.
- *
- * @param Model $model
- * @return ModelDoesNotExistException
*/
- public static function forModel(Model $model)
+ public static function forModel(Model $model): static
{
- return (new static())->setModel($model);
+ return (new static)->setModel($model);
}
/**
- * Set the model that does not exist.
- *
- * @param Model $model
- * @return ModelDoesNotExistException
+ * Set the model instance that does not exist.
*/
- public function setModel(Model $model)
+ public function setModel(Model $model): static
{
$this->model = $model;
@@ -40,4 +32,12 @@ class ModelDoesNotExistException extends LdapRecordException
return $this;
}
+
+ /**
+ * Get the instance of the model that does not exist.
+ */
+ public function getModel(): Model
+ {
+ return $this->model;
+ }
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Entry.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Entry.php
index c11ca72d4..e20016a45 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Entry.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Entry.php
@@ -13,31 +13,26 @@ class Entry extends BaseEntry implements OpenLDAP
{
/**
* The attribute key that contains the models object GUID.
- *
- * @var string
*/
- protected $guidKey = 'entryuuid';
+ protected string $guidKey = 'entryuuid';
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- protected static function boot()
+ protected static function boot(): void
{
parent::boot();
// Here we'll add a global scope to all OpenLDAP models to ensure the
// Entry UUID is always selected on each query. This attribute is
// virtual, so it must be manually selected to be included.
- static::addGlobalScope(new AddEntryUuidToSelects());
+ static::addGlobalScope(new AddEntryUuidToSelects);
}
/**
* Create a new query builder.
- *
- * @param Connection $connection
- * @return OpenLdapBuilder
*/
- public function newQueryBuilder(Connection $connection)
+ public function newQueryBuilder(Connection $connection): OpenLdapBuilder
{
return new OpenLdapBuilder($connection);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Group.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Group.php
index a9a682a06..e7d81ef28 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Group.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Group.php
@@ -2,27 +2,23 @@
namespace LdapRecord\Models\OpenLDAP;
+use LdapRecord\Models\Relations\HasManyIn;
+
class Group extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'groupofuniquenames',
];
/**
* The members relationship.
- *
- * Retrieves members that are apart of the group.
- *
- * @return \LdapRecord\Models\Relations\HasMany
*/
- public function members()
+ public function members(): HasManyIn
{
- return $this->hasMany([static::class, User::class], 'memberUid');
+ return $this->hasManyIn([static::class, User::class], 'uniquemember')->using($this, 'uniquemember');
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/OrganizationalUnit.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/OrganizationalUnit.php
index 7ae0a37a4..e304237e7 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/OrganizationalUnit.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/OrganizationalUnit.php
@@ -6,20 +6,16 @@ class OrganizationalUnit extends Entry
{
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'organizationalunit',
];
/**
* Get the creatable RDN attribute name.
- *
- * @return string
*/
- public function getCreatableRdnAttribute()
+ public function getCreatableRdnAttribute(): string
{
return 'ou';
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Scopes/AddEntryUuidToSelects.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Scopes/AddEntryUuidToSelects.php
index 780a633f3..78efa95f4 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Scopes/AddEntryUuidToSelects.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/Scopes/AddEntryUuidToSelects.php
@@ -10,12 +10,8 @@ class AddEntryUuidToSelects implements Scope
{
/**
* Add the entry UUID to the selected attributes.
- *
- * @param Builder $query
- * @param Model $model
- * @return void
*/
- public function apply(Builder $query, Model $model)
+ public function apply(Builder $query, Model $model): void
{
empty($query->columns)
? $query->addSelect(['*', $model->getGuidKey()])
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/User.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/User.php
index c8626de6d..beaba9e4c 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/User.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/OpenLDAP/User.php
@@ -5,32 +5,27 @@ namespace LdapRecord\Models\OpenLDAP;
use Illuminate\Contracts\Auth\Authenticatable;
use LdapRecord\Models\Concerns\CanAuthenticate;
use LdapRecord\Models\Concerns\HasPassword;
+use LdapRecord\Models\Relations\HasMany;
class User extends Entry implements Authenticatable
{
- use HasPassword;
use CanAuthenticate;
+ use HasPassword;
/**
* The password's attribute name.
- *
- * @var string
*/
- protected $passwordAttribute = 'userpassword';
+ protected string $passwordAttribute = 'userpassword';
/**
* The password's hash method.
- *
- * @var string
*/
- protected $passwordHashMethod = 'ssha';
+ protected string $passwordHashMethod = 'ssha';
/**
* The object classes of the LDAP model.
- *
- * @var array
*/
- public static $objectClasses = [
+ public static array $objectClasses = [
'top',
'person',
'organizationalperson',
@@ -38,14 +33,18 @@ class User extends Entry implements Authenticatable
];
/**
- * The groups relationship.
- *
- * Retrieve groups that the user is a part of.
- *
- * @return \LdapRecord\Models\Relations\HasMany
+ * Get the unique identifier for the user.
*/
- public function groups()
+ public function getAuthIdentifier(): string
{
- return $this->hasMany(Group::class, 'memberuid', 'uid');
+ return $this->getFirstAttribute($this->guidKey);
+ }
+
+ /**
+ * The groups relationship.
+ */
+ public function groups(): HasMany
+ {
+ return $this->hasMany(Group::class, 'uniquemember');
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasMany.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasMany.php
index 583f81c30..16e65b14c 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasMany.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasMany.php
@@ -3,73 +3,21 @@
namespace LdapRecord\Models\Relations;
use Closure;
-use LdapRecord\DetectsErrors;
-use LdapRecord\LdapRecordException;
use LdapRecord\Models\Collection;
use LdapRecord\Models\Model;
-use LdapRecord\Models\ModelNotFoundException;
+use LdapRecord\Query\Model\Builder;
class HasMany extends OneToMany
{
- use DetectsErrors;
-
- /**
- * The model to use for attaching / detaching.
- *
- * @var Model
- */
- protected $using;
-
- /**
- * The attribute key to use for attaching / detaching.
- *
- * @var string
- */
- protected $usingKey;
-
/**
* The pagination page size.
- *
- * @var int
*/
- protected $pageSize = 1000;
-
- /**
- * The exceptions to bypass for each relation operation.
- *
- * @var array
- */
- protected $bypass = [
- 'attach' => [
- 'Already exists', 'Type or value exists',
- ],
- 'detach' => [
- 'No such attribute', 'Server is unwilling to perform',
- ],
- ];
-
- /**
- * Set the model and attribute to use for attaching / detaching.
- *
- * @param Model $using
- * @param string $usingKey
- * @return $this
- */
- public function using(Model $using, $usingKey)
- {
- $this->using = $using;
- $this->usingKey = $usingKey;
-
- return $this;
- }
+ protected int $pageSize = 1000;
/**
* Set the pagination page size of the relation query.
- *
- * @param int $pageSize
- * @return $this
*/
- public function setPageSize($pageSize)
+ public function setPageSize(int $pageSize): static
{
$this->pageSize = $pageSize;
@@ -78,22 +26,16 @@ class HasMany extends OneToMany
/**
* Paginate the relation using the given page size.
- *
- * @param int $pageSize
- * @return Collection
*/
- public function paginate($pageSize = 1000)
+ public function paginate(int $pageSize = 1000): Collection
{
return $this->paginateOnceUsing($pageSize);
}
/**
* Paginate the relation using the page size once.
- *
- * @param int $pageSize
- * @return Collection
*/
- protected function paginateOnceUsing($pageSize)
+ protected function paginateOnceUsing(int $pageSize): Collection
{
$size = $this->pageSize;
@@ -106,44 +48,32 @@ class HasMany extends OneToMany
/**
* Execute a callback over each result while chunking.
- *
- * @param Closure $callback
- * @param int $pageSize
- * @return bool
*/
- public function each(Closure $callback, $pageSize = 1000)
+ public function each(Closure $callback, int $pageSize = 1000): bool
{
- $this->chunk($pageSize, function ($results) use ($callback) {
+ return $this->chunk($pageSize, function ($results) use ($callback) {
foreach ($results as $key => $value) {
if ($callback($value, $key) === false) {
return false;
}
}
+
+ return true;
});
}
/**
* Chunk the relation results using the given callback.
- *
- * @param int $pageSize
- * @param Closure $callback
- * @param array $loaded
- * @return bool
*/
- public function chunk($pageSize, Closure $callback)
+ public function chunk(int $pageSize, Closure $callback): bool
{
return $this->chunkRelation($pageSize, $callback);
}
/**
* Execute the callback over chunks of relation results.
- *
- * @param int $pageSize
- * @param Closure $callback
- * @param array $loaded
- * @return bool
*/
- protected function chunkRelation($pageSize, Closure $callback, $loaded = [])
+ protected function chunkRelation(int $pageSize, Closure $callback, array $loaded = []): bool
{
return $this->getRelationQuery()->chunk($pageSize, function (Collection $results) use ($pageSize, $callback, $loaded) {
$models = $this->transformResults($results)->when($this->recursive, function (Collection $models) use ($loaded) {
@@ -165,15 +95,15 @@ class HasMany extends OneToMany
}
});
});
+
+ return true;
});
}
/**
* Get the relationships results.
- *
- * @return Collection
*/
- public function getRelationResults()
+ public function getRelationResults(): Collection
{
return $this->transformResults(
$this->getRelationQuery()->paginate($this->pageSize)
@@ -182,10 +112,8 @@ class HasMany extends OneToMany
/**
* Get the prepared relationship query.
- *
- * @return \LdapRecord\Query\Model\Builder
*/
- public function getRelationQuery()
+ public function getRelationQuery(): Builder
{
$columns = $this->query->getSelects();
@@ -209,212 +137,4 @@ class HasMany extends OneToMany
$this->getEscapedForeignValueFromModel($this->parent)
);
}
-
- /**
- * Attach a model to the relation.
- *
- * @param Model|string $model
- * @return Model|string|false
- */
- public function attach($model)
- {
- return $this->attemptFailableOperation(
- $this->buildAttachCallback($model),
- $this->bypass['attach'],
- $model
- );
- }
-
- /**
- * Build the attach callback.
- *
- * @param Model|string $model
- * @return \Closure
- */
- protected function buildAttachCallback($model)
- {
- return function () use ($model) {
- $foreign = $this->getAttachableForeignValue($model);
-
- if ($this->using) {
- return $this->using->createAttribute($this->usingKey, $foreign);
- }
-
- if (! $model instanceof Model) {
- $model = $this->getForeignModelByValueOrFail($model);
- }
-
- return $model->createAttribute($this->relationKey, $foreign);
- };
- }
-
- /**
- * Attach a collection of models to the parent instance.
- *
- * @param iterable $models
- * @return iterable
- */
- public function attachMany($models)
- {
- foreach ($models as $model) {
- $this->attach($model);
- }
-
- return $models;
- }
-
- /**
- * Detach the model from the relation.
- *
- * @param Model|string $model
- * @return Model|string|false
- */
- public function detach($model)
- {
- return $this->attemptFailableOperation(
- $this->buildDetachCallback($model),
- $this->bypass['detach'],
- $model
- );
- }
-
- /**
- * Detach the model or delete the parent if the relation is empty.
- *
- * @param Model|string $model
- * @return void
- */
- public function detachOrDeleteParent($model)
- {
- $count = $this->onceWithoutMerging(function () {
- return $this->count();
- });
-
- if ($count <= 1) {
- return $this->getParent()->delete();
- }
-
- return $this->detach($model);
- }
-
- /**
- * Build the detach callback.
- *
- * @param Model|string $model
- * @return \Closure
- */
- protected function buildDetachCallback($model)
- {
- return function () use ($model) {
- $foreign = $this->getAttachableForeignValue($model);
-
- if ($this->using) {
- return $this->using->deleteAttribute([$this->usingKey => $foreign]);
- }
-
- if (! $model instanceof Model) {
- $model = $this->getForeignModelByValueOrFail($model);
- }
-
- return $model->deleteAttribute([$this->relationKey => $foreign]);
- };
- }
-
- /**
- * Get the attachable foreign value from the model.
- *
- * @param Model|string $model
- * @return string
- */
- protected function getAttachableForeignValue($model)
- {
- if ($model instanceof Model) {
- return $this->using
- ? $this->getForeignValueFromModel($model)
- : $this->getParentForeignValue();
- }
-
- return $this->using ? $model : $this->getParentForeignValue();
- }
-
- /**
- * Get the foreign model by the given value, or fail.
- *
- * @param string $model
- * @return Model
- *
- * @throws ModelNotFoundException
- */
- protected function getForeignModelByValueOrFail($model)
- {
- if (! is_null($model = $this->getForeignModelByValue($model))) {
- return $model;
- }
-
- throw ModelNotFoundException::forQuery(
- $this->query->getUnescapedQuery(),
- $this->query->getDn()
- );
- }
-
- /**
- * Attempt a failable operation and return the value if successful.
- *
- * If a bypassable exception is encountered, the value will be returned.
- *
- * @param callable $operation
- * @param string|array $bypass
- * @param mixed $value
- * @return mixed
- *
- * @throws LdapRecordException
- */
- protected function attemptFailableOperation($operation, $bypass, $value)
- {
- try {
- $operation();
-
- return $value;
- } catch (LdapRecordException $e) {
- if ($this->errorContainsMessage($e->getMessage(), $bypass)) {
- return $value;
- }
-
- throw $e;
- }
- }
-
- /**
- * Detach all relation models.
- *
- * @return Collection
- */
- public function detachAll()
- {
- return $this->onceWithoutMerging(function () {
- return $this->get()->each(function (Model $model) {
- $this->detach($model);
- });
- });
- }
-
- /**
- * Detach all relation models or delete the model if its relation is empty.
- *
- * @return Collection
- */
- public function detachAllOrDelete()
- {
- return $this->onceWithoutMerging(function () {
- return $this->get()->each(function (Model $model) {
- $relation = $model->getRelation($this->relationName);
-
- if ($relation && $relation->count() >= 1) {
- $model->delete();
- } else {
- $this->detach($model);
- }
- });
- });
- }
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasManyIn.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasManyIn.php
index 303a1440d..8b5d561f0 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasManyIn.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasManyIn.php
@@ -2,21 +2,19 @@
namespace LdapRecord\Models\Relations;
-use LdapRecord\Query\Collection;
+use LdapRecord\Models\Collection;
class HasManyIn extends OneToMany
{
/**
* Get the relationships results.
- *
- * @return Collection
*/
- public function getRelationResults()
+ public function getRelationResults(): Collection
{
$results = $this->parent->newCollection();
foreach ((array) $this->parent->getAttribute($this->relationKey) as $value) {
- if ($foreign = $this->getForeignModelByValue($value)) {
+ if ($value && $foreign = $this->getForeignModelByValue($value)) {
$results->push($foreign);
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasOne.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasOne.php
index 243cd2ed9..0199f2178 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasOne.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/HasOne.php
@@ -2,20 +2,19 @@
namespace LdapRecord\Models\Relations;
+use LdapRecord\Models\Collection;
use LdapRecord\Models\Model;
class HasOne extends Relation
{
/**
* Get the results of the relationship.
- *
- * @return \LdapRecord\Query\Collection
*/
- public function getResults()
+ public function getResults(): Collection
{
- $model = $this->getForeignModelByValue(
- $this->getFirstAttributeValue($this->parent, $this->relationKey)
- );
+ $relationValue = $this->getFirstAttributeValue($this->parent, $this->relationKey);
+
+ $model = $relationValue ? $this->getForeignModelByValue($relationValue) : null;
return $this->transformResults(
$this->parent->newCollection($model ? [$model] : null)
@@ -24,31 +23,20 @@ class HasOne extends Relation
/**
* Attach a model instance to the parent model.
- *
- * @param Model|string $model
- * @return Model|string
- *
- * @throws \LdapRecord\LdapRecordException
*/
- public function attach($model)
+ public function attach(Model|string $model): void
{
$foreign = $model instanceof Model
? $this->getForeignValueFromModel($model)
: $model;
$this->parent->setAttribute($this->relationKey, $foreign)->save();
-
- return $model;
}
/**
* Detach the related model from the parent.
- *
- * @return void
- *
- * @throws \LdapRecord\LdapRecordException
*/
- public function detach()
+ public function detach(): void
{
$this->parent->setAttribute($this->relationKey, null)->save();
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/OneToMany.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/OneToMany.php
index aa873b60b..8eb88cbcf 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/OneToMany.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/OneToMany.php
@@ -2,44 +2,59 @@
namespace LdapRecord\Models\Relations;
+use Closure;
+use LdapRecord\DetectsErrors;
+use LdapRecord\LdapRecordException;
+use LdapRecord\Models\Collection;
use LdapRecord\Models\Model;
-use LdapRecord\Query\Collection;
+use LdapRecord\Models\ModelNotFoundException;
use LdapRecord\Query\Model\Builder;
abstract class OneToMany extends Relation
{
+ use DetectsErrors;
+
+ /**
+ * The model to use for attaching / detaching.
+ */
+ protected ?Model $using = null;
+
/**
* The relation to merge results with.
- *
- * @var OneToMany|null
*/
- protected $with;
+ protected ?Relation $with = null;
+
+ /**
+ * The attribute key to use for attaching / detaching.
+ */
+ protected ?string $usingKey = null;
/**
* The name of the relationship.
- *
- * @var string
*/
- protected $relationName;
+ protected ?string $relationName = null;
/**
* Whether to include recursive results.
- *
- * @var bool
*/
- protected $recursive = false;
+ protected bool $recursive = false;
+
+ /**
+ * The exceptions to bypass for each relation operation.
+ */
+ protected array $bypass = [
+ 'attach' => [
+ 'Already exists', 'Type or value exists',
+ ],
+ 'detach' => [
+ 'No such attribute', 'Server is unwilling to perform',
+ ],
+ ];
/**
* Constructor.
- *
- * @param Builder $query
- * @param Model $parent
- * @param string $related
- * @param string $relationKey
- * @param string $foreignKey
- * @param string $relationName
*/
- public function __construct(Builder $query, Model $parent, $related, $relationKey, $foreignKey, $relationName)
+ public function __construct(Builder $query, Model $parent, array|string $related, string $relationKey, string $foreignKey, string $relationName)
{
$this->relationName = $relationName;
@@ -47,12 +62,20 @@ abstract class OneToMany extends Relation
}
/**
- * Set the relation to load with its parent.
- *
- * @param Relation $relation
- * @return $this
+ * Set the model and attribute to use for attaching / detaching.
*/
- public function with(Relation $relation)
+ public function using(Model $using, string $usingKey): static
+ {
+ $this->using = $using;
+ $this->usingKey = $usingKey;
+
+ return $this;
+ }
+
+ /**
+ * Set the relation to load with its parent.
+ */
+ public function with(Relation $relation): static
{
$this->with = $relation;
@@ -61,30 +84,23 @@ abstract class OneToMany extends Relation
/**
* Whether to include recursive results.
- *
- * @param bool $enable
- * @return $this
*/
- public function recursive($enable = true)
+ public function recursive(bool $recursive = true): static
{
- $this->recursive = $enable;
+ $this->recursive = $recursive;
return $this;
}
/**
* Get the immediate relationships results.
- *
- * @return Collection
*/
- abstract public function getRelationResults();
+ abstract public function getRelationResults(): Collection;
/**
* Get the results of the relationship.
- *
- * @return Collection
*/
- public function getResults()
+ public function getResults(): Collection
{
$results = $this->recursive
? $this->getRecursiveResults()
@@ -97,11 +113,8 @@ abstract class OneToMany extends Relation
/**
* Execute the callback excluding the merged query result.
- *
- * @param callable $callback
- * @return mixed
*/
- protected function onceWithoutMerging($callback)
+ protected function onceWithoutMerging(Closure $callback): mixed
{
$merging = $this->with;
@@ -116,20 +129,262 @@ abstract class OneToMany extends Relation
/**
* Get the relation name.
- *
- * @return string
*/
- public function getRelationName()
+ public function getRelationName(): string
{
return $this->relationName;
}
/**
- * Get the results of the merging 'with' relation.
- *
- * @return Collection
+ * Attach the model in the relation.
*/
- protected function getMergingRelationResults()
+ public function attach(mixed $model): void
+ {
+ if (is_iterable($model)) {
+ array_map($this->attach(...), [...$model]);
+
+ return;
+ }
+
+ $this->attemptFailableOperation(
+ $this->buildAttachCallback($model),
+ $this->bypass['attach'],
+ $model
+ );
+ }
+
+ /**
+ * Build the attach callback.
+ */
+ protected function buildAttachCallback(Model|string $model): Closure
+ {
+ return function () use ($model) {
+ $foreign = $this->getAttachableForeignValue($model);
+
+ if ($this->using) {
+ $this->using->addAttribute($this->usingKey, $foreign);
+
+ return;
+ }
+
+ if (! $model instanceof Model) {
+ $model = $this->getForeignModelByValueOrFail($model);
+ }
+
+ $model->addAttribute($this->relationKey, $foreign);
+ };
+ }
+
+ /**
+ * Get the foreign model by the given value, or fail.
+ *
+ * @throws ModelNotFoundException
+ */
+ protected function getForeignModelByValueOrFail(string $model): Model
+ {
+ if (! is_null($model = $this->getForeignModelByValue($model))) {
+ return $model;
+ }
+
+ throw ModelNotFoundException::forQuery(
+ $this->query->getUnescapedQuery(),
+ $this->query->getDn()
+ );
+ }
+
+ /**
+ * Detach the model from the relation.
+ */
+ public function detach(mixed $model): void
+ {
+ if (is_iterable($model)) {
+ array_map($this->detach(...), [...$model]);
+
+ return;
+ }
+
+ $this->attemptFailableOperation(
+ $this->buildDetachCallback($model),
+ $this->bypass['detach'],
+ $model
+ );
+ }
+
+ /**
+ * Detach the model or delete the parent if the relation is empty.
+ */
+ public function detachOrDeleteParent(Model|string $model): void
+ {
+ /** @var Collection $related */
+ $related = $this->onceWithoutMerging(function () {
+ return $this->get('dn');
+ });
+
+ if (! $related->exists($model)) {
+ return;
+ }
+
+ if ($related->count() <= 1) {
+ $this->getParent()->delete();
+
+ return;
+ }
+
+ $this->detach($model);
+ }
+
+ /**
+ * Build the detach callback.
+ */
+ protected function buildDetachCallback(Model|string $model): Closure
+ {
+ return function () use ($model) {
+ $foreign = $this->getAttachableForeignValue($model);
+
+ if ($this->using) {
+ $this->using->removeAttribute($this->usingKey, $foreign);
+
+ return;
+ }
+
+ if (! $model instanceof Model) {
+ $model = $this->getForeignModelByValueOrFail($model);
+ }
+
+ $model->removeAttribute($this->relationKey, $foreign);
+ };
+ }
+
+ /**
+ * Associate the model in the relation.
+ */
+ public function associate(mixed $model): void
+ {
+ if (is_iterable($model)) {
+ array_map($this->associate(...), [...$model]);
+
+ return;
+ }
+
+ $foreign = $this->getAttachableForeignValue($model);
+
+ if ($this->using) {
+ $this->using->addAttributeValue($this->usingKey, $foreign);
+
+ return;
+ }
+
+ if (! $model instanceof Model) {
+ $model = $this->getForeignModelByValueOrFail($model);
+ }
+
+ $model->addAttributeValue($this->relationKey, $foreign);
+ }
+
+ /**
+ * Dissociate the model in the relation.
+ */
+ public function dissociate(mixed $model): void
+ {
+ if (is_iterable($model)) {
+ array_map($this->dissociate(...), [...$model]);
+
+ return;
+ }
+
+ $foreign = $this->getAttachableForeignValue($model);
+
+ if ($this->using) {
+ $this->using->removeAttributeValue($this->usingKey, $foreign);
+
+ return;
+ }
+
+ if (! $model instanceof Model) {
+ $model = $this->getForeignModelByValueOrFail($model);
+ }
+
+ $model->removeAttributeValue($this->relationKey, $foreign);
+ }
+
+ /**
+ * Alias of "dissociate" method.
+ */
+ public function disassociate(Model|string $model): void
+ {
+ $this->dissociate($model);
+ }
+
+ /**
+ * Get the attachable foreign value from the model.
+ */
+ protected function getAttachableForeignValue(Model|string $model): string
+ {
+ if ($model instanceof Model) {
+ return $this->using
+ ? $this->getForeignValueFromModel($model)
+ : $this->getParentForeignValue();
+ }
+
+ return $this->using ? $model : $this->getParentForeignValue();
+ }
+
+ /**
+ * Attempt a failable operation and return the value if successful.
+ *
+ * If a bypassable exception is encountered, the value will be returned.
+ *
+ * @throws LdapRecordException
+ */
+ protected function attemptFailableOperation(Closure $operation, string|array $bypass, mixed $value): mixed
+ {
+ try {
+ $operation();
+
+ return $value;
+ } catch (LdapRecordException $e) {
+ if ($this->errorContainsMessage($e->getMessage(), $bypass)) {
+ return $value;
+ }
+
+ throw $e;
+ }
+ }
+
+ /**
+ * Detach all relation models.
+ */
+ public function detachAll(): Collection
+ {
+ return $this->onceWithoutMerging(
+ fn () => $this->get()->each(function (Model $model) {
+ $this->detach($model);
+ })
+ );
+ }
+
+ /**
+ * Detach all relation models or delete the model if its relation is empty.
+ */
+ public function detachAllOrDelete(): Collection
+ {
+ return $this->onceWithoutMerging(
+ fn () => $this->get()->each(function (Model $model) {
+ $relation = $model->getRelation($this->relationName);
+
+ if ($relation && $relation->count() >= 1) {
+ $model->delete();
+ } else {
+ $this->detach($model);
+ }
+ })
+ );
+ }
+
+ /**
+ * Get the results of the merging 'with' relation.
+ */
+ protected function getMergingRelationResults(): Collection
{
return $this->with
? $this->with->recursive($this->recursive)->get()
@@ -137,24 +392,23 @@ abstract class OneToMany extends Relation
}
/**
- * Get the results for the models relation recursively.
+ * Get the results for the model's relation recursively.
*
* @param string[] $loaded The distinguished names of models already loaded
- * @return Collection
*/
- protected function getRecursiveResults(array $loaded = [])
+ protected function getRecursiveResults(array $loaded = []): Collection
{
- $results = $this->getRelationResults()->reject(function (Model $model) use ($loaded) {
+ $results = $this->getRelationResults()->reject(fn (Model $model) =>
// Here we will exclude the models that we have already
// loaded the recursive results for so we don't run
// into issues with circular relations in LDAP.
- return in_array($model->getDn(), $loaded);
- });
+ in_array($model->getDn(), $loaded)
+ );
foreach ($results as $model) {
$loaded[] = $model->getDn();
- // Finally, we will fetch the related models relations,
+ // Finally, we will fetch the related model's relations,
// passing along our loaded models, to ensure we do
// not attempt fetching already loaded relations.
$results = $results->merge(
@@ -167,12 +421,8 @@ abstract class OneToMany extends Relation
/**
* Get the recursive relation results for given model.
- *
- * @param Model $model
- * @param array $loaded
- * @return Collection
*/
- protected function getRecursiveRelationResults(Model $model, array $loaded)
+ protected function getRecursiveRelationResults(Model $model, array $loaded): Collection
{
return ($relation = $model->getRelation($this->relationName))
? $relation->getRecursiveResults($loaded)
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/Relation.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/Relation.php
index 31b0969c9..b2d26100e 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/Relation.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Relations/Relation.php
@@ -3,13 +3,13 @@
namespace LdapRecord\Models\Relations;
use Closure;
+use LdapRecord\Models\Collection;
use LdapRecord\Models\Entry;
use LdapRecord\Models\Model;
-use LdapRecord\Query\Collection;
use LdapRecord\Query\Model\Builder;
/**
- * @method bool exists($models = null) Determine if the relation contains all of the given models, or any models
+ * @method bool exists($models = null) Determine if the relation contains all the given models, or any models
* @method bool contains($models) Determine if any of the given models are contained in the relation
* @method bool count() Retrieve the "count" result of the query.
*/
@@ -17,70 +17,48 @@ abstract class Relation
{
/**
* The underlying LDAP query.
- *
- * @var Builder
*/
- protected $query;
+ protected Builder $query;
/**
* The parent model instance.
- *
- * @var Model
*/
- protected $parent;
+ protected Model $parent;
/**
* The related model class names.
- *
- * @var array
*/
- protected $related;
+ protected array $related;
/**
* The relation key.
- *
- * @var string
*/
- protected $relationKey;
+ protected string $relationKey;
/**
* The foreign key.
- *
- * @var string
*/
- protected $foreignKey;
+ protected string $foreignKey;
/**
* The default relation model.
- *
- * @var string
*/
- protected $default = Entry::class;
+ protected string $default = Entry::class;
/**
* The callback to use for resolving relation models.
- *
- * @var Closure
*/
- protected static $modelResolver;
+ protected static ?Closure $modelResolver = null;
/**
* The methods that should be passed along to a relation collection.
- *
- * @var string[]
*/
- protected $passthru = ['count', 'exists', 'contains'];
+ protected array $passthru = ['count', 'exists', 'contains'];
/**
* Constructor.
- *
- * @param Builder $query
- * @param Model $parent
- * @param string|array $related
- * @param string $relationKey
- * @param string $foreignKey
*/
- public function __construct(Builder $query, Model $parent, $related, $relationKey, $foreignKey)
+ public function __construct(Builder $query, Model $parent, array|string $related, string $relationKey, string $foreignKey)
{
$this->query = $query;
$this->parent = $parent;
@@ -88,21 +66,13 @@ abstract class Relation
$this->relationKey = $relationKey;
$this->foreignKey = $foreignKey;
- static::$modelResolver = static::$modelResolver ?? function (array $modelObjectClasses, array $relationMap) {
- return array_search($modelObjectClasses, $relationMap);
- };
-
$this->initRelation();
}
/**
* Handle dynamic method calls to the relationship.
- *
- * @param string $method
- * @param array $parameters
- * @return mixed
*/
- public function __call($method, $parameters)
+ public function __call(string $method, array $parameters): mixed
{
if (in_array($method, $this->passthru)) {
return $this->get('objectclass')->$method(...$parameters);
@@ -119,21 +89,16 @@ abstract class Relation
/**
* Set the callback to use for resolving models from relation results.
- *
- * @param Closure $callback
- * @return void
*/
- public static function resolveModelsUsing(Closure $callback)
+ public static function resolveModelsUsing(?Closure $callback = null): void
{
static::$modelResolver = $callback;
}
/**
* Only return objects matching the related model's object classes.
- *
- * @return $this
*/
- public function onlyRelated()
+ public function onlyRelated(): static
{
$relations = [];
@@ -158,18 +123,13 @@ abstract class Relation
/**
* Get the results of the relationship.
- *
- * @return Collection
*/
- abstract public function getResults();
+ abstract public function getResults(): Collection;
/**
* Execute the relationship query.
- *
- * @param array|string $columns
- * @return Collection
*/
- public function get($columns = ['*'])
+ public function get(array|string $columns = ['*']): Collection
{
return $this->getResultsWithColumns($columns);
}
@@ -178,11 +138,8 @@ abstract class Relation
* Get the results of the relationship while selecting the given columns.
*
* If the query columns are empty, the given columns are applied.
- *
- * @param array $columns
- * @return Collection
*/
- protected function getResultsWithColumns($columns)
+ protected function getResultsWithColumns(array|string $columns): Collection
{
if (is_null($this->query->columns)) {
$this->query->select($columns);
@@ -193,21 +150,16 @@ abstract class Relation
/**
* Get the first result of the relationship.
- *
- * @param array|string $columns
- * @return Model|null
*/
- public function first($columns = ['*'])
+ public function first(array|string $columns = ['*']): ?Model
{
return $this->get($columns)->first();
}
/**
* Prepare the relation query.
- *
- * @return static
*/
- public function initRelation()
+ public function initRelation(): static
{
$this->query
->clearFilters()
@@ -219,11 +171,8 @@ abstract class Relation
/**
* Set the underlying query for the relation.
- *
- * @param Builder $query
- * @return $this
*/
- public function setQuery(Builder $query)
+ public function setQuery(Builder $query): static
{
$this->query = $query;
@@ -234,72 +183,58 @@ abstract class Relation
/**
* Get the underlying query for the relation.
- *
- * @return Builder
*/
- public function getQuery()
+ public function getQuery(): Builder
{
return $this->query;
}
/**
* Get the parent model of the relation.
- *
- * @return Model
*/
- public function getParent()
+ public function getParent(): Model
{
return $this->parent;
}
/**
* Get the relation attribute key.
- *
- * @return string
*/
- public function getRelationKey()
+ public function getRelationKey(): string
{
return $this->relationKey;
}
/**
* Get the related model classes for the relation.
- *
- * @return array
*/
- public function getRelated()
+ public function getRelated(): array
{
return $this->related;
}
/**
* Get the relation foreign attribute key.
- *
- * @return string
*/
- public function getForeignKey()
+ public function getForeignKey(): string
{
return $this->foreignKey;
}
/**
* Get the class name of the default model.
- *
- * @return string
*/
- public function getDefaultModel()
+ public function getDefaultModel(): string
{
return $this->default;
}
/**
* Get a new instance of the default model on the relation.
- *
- * @return Model
*/
- public function getNewDefaultModel()
+ public function getNewDefaultModel(): Model
{
- $model = new $this->default();
+ $model = new $this->default;
$model->setConnection($this->parent->getConnectionName());
@@ -308,132 +243,65 @@ abstract class Relation
/**
* Get the foreign model by the given value.
- *
- * @param string $value
- * @return Model|null
*/
- protected function getForeignModelByValue($value)
+ protected function getForeignModelByValue(string $value): ?Model
{
return $this->foreignKeyIsDistinguishedName()
- ? $this->query->find($value)
- : $this->query->findBy($this->foreignKey, $value);
+ ? $this->query->clearFilters()->find($value)
+ : $this->query->clearFilters()->findBy($this->foreignKey, $value);
}
/**
- * Returns the escaped foreign key value for use in an LDAP filter from the model.
- *
- * @param Model $model
- * @return string
+ * Get the escaped foreign key value for use in an LDAP filter from the model.
*/
- protected function getEscapedForeignValueFromModel(Model $model)
+ protected function getEscapedForeignValueFromModel(Model $model): string
{
return $this->query->escape(
$this->getForeignValueFromModel($model)
- )->both();
+ )->forDnAndFilter();
}
/**
* Get the relation parents foreign value.
- *
- * @return string
*/
- protected function getParentForeignValue()
+ protected function getParentForeignValue(): ?string
{
return $this->getForeignValueFromModel($this->parent);
}
/**
* Get the foreign key value from the model.
- *
- * @param Model $model
- * @return string
*/
- protected function getForeignValueFromModel(Model $model)
+ protected function getForeignValueFromModel(Model $model): ?string
{
return $this->foreignKeyIsDistinguishedName()
- ? $model->getDn()
- : $this->getFirstAttributeValue($model, $this->foreignKey);
+ ? $model->getDn()
+ : $this->getFirstAttributeValue($model, $this->foreignKey);
}
/**
* Get the first attribute value from the model.
- *
- * @param Model $model
- * @param string $attribute
- * @return string|null
*/
- protected function getFirstAttributeValue(Model $model, $attribute)
+ protected function getFirstAttributeValue(Model $model, string $attribute): mixed
{
return $model->getFirstAttribute($attribute);
}
/**
* Transforms the results by converting the models into their related.
- *
- * @param Collection $results
- * @return Collection
*/
- protected function transformResults(Collection $results)
+ protected function transformResults(Collection $results): Collection
{
- $relationMap = [];
-
- foreach ($this->related as $relation) {
- $relationMap[$relation] = $this->normalizeObjectClasses(
- $relation::$objectClasses
- );
- }
-
- return $results->transform(function (Model $entry) use ($relationMap) {
- $model = $this->determineModelFromRelated($entry, $relationMap);
-
- return class_exists($model) ? $entry->convert(new $model()) : $entry;
- });
+ return $results->transform(
+ fn (Model $entry) => $entry->morphInto($this->related, static::$modelResolver)
+ );
}
/**
- * Determines if the foreign key is a distinguished name.
- *
- * @return bool
+ * Determine if the foreign key is a distinguished name.
*/
- protected function foreignKeyIsDistinguishedName()
+ protected function foreignKeyIsDistinguishedName(): bool
{
return in_array($this->foreignKey, ['dn', 'distinguishedname']);
}
-
- /**
- * Determines the model from the given relation map.
- *
- * @param Model $model
- * @param array $relationMap
- * @return class-string|bool
- */
- protected function determineModelFromRelated(Model $model, array $relationMap)
- {
- // We must normalize all the related models object class
- // names to the same case so we are able to properly
- // determine the owning model from search results.
- $modelObjectClasses = $this->normalizeObjectClasses(
- $model->getObjectClasses()
- );
-
- return call_user_func(
- static::$modelResolver,
- $modelObjectClasses,
- $relationMap,
- $model,
- );
- }
-
- /**
- * Sort and normalize the object classes.
- *
- * @param array $classes
- * @return array
- */
- protected function normalizeObjectClasses($classes)
- {
- sort($classes);
-
- return array_map('strtolower', $classes);
- }
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Scope.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Scope.php
index f61cf686b..09c0c0c2c 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Scope.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Scope.php
@@ -8,10 +8,6 @@ interface Scope
{
/**
* Apply the scope to the given query.
- *
- * @param Builder $query
- * @param Model $model
- * @return void
*/
- public function apply(Builder $query, Model $model);
+ public function apply(Builder $query, Model $model): void;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Types/ActiveDirectory.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Types/ActiveDirectory.php
index 3edcf88c9..2fc54e4a4 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Types/ActiveDirectory.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Models/Types/ActiveDirectory.php
@@ -5,34 +5,24 @@ namespace LdapRecord\Models\Types;
interface ActiveDirectory extends TypeInterface
{
/**
- * Returns the models object SID key.
- *
- * @return string
+ * Get the models object SID key.
*/
- public function getObjectSidKey();
+ public function getObjectSidKey(): string;
/**
- * Returns the model's hex object SID.
+ * Get the model's hex object SID.
*
* @see https://msdn.microsoft.com/en-us/library/ms679024(v=vs.85).aspx
- *
- * @return string
*/
- public function getObjectSid();
+ public function getObjectSid(): ?string;
/**
- * Returns the model's SID.
- *
- * @param string|null $sid
- * @return string|null
+ * Get the model's SID.
*/
- public function getConvertedSid($sid = null);
+ public function getConvertedSid(?string $sid = null): ?string;
/**
- * Returns the model's binary SID.
- *
- * @param string|null $sid
- * @return string|null
+ * Get the model's binary SID.
*/
- public function getBinarySid($sid = null);
+ public function getBinarySid(?string $sid = null): ?string;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ArrayCacheStore.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ArrayCacheStore.php
index 2fb9c9a72..d4a9137c0 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ArrayCacheStore.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ArrayCacheStore.php
@@ -10,15 +10,13 @@ class ArrayCacheStore implements CacheInterface
/**
* An array of stored values.
- *
- * @var array
*/
- protected $storage = [];
+ protected array $storage = [];
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function get($key, $default = null)
+ public function get($key, $default = null): mixed
{
if (! isset($this->storage[$key])) {
return $default;
@@ -38,9 +36,9 @@ class ArrayCacheStore implements CacheInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function set($key, $value, $ttl = null)
+ public function set($key, $value, $ttl = null): bool
{
$this->storage[$key] = [
'value' => $value,
@@ -52,30 +50,24 @@ class ArrayCacheStore implements CacheInterface
/**
* Get the expiration time of the key.
- *
- * @param int $seconds
- * @return int
*/
- protected function calculateExpiration($seconds)
+ protected function calculateExpiration($seconds = null): int
{
return $this->toTimestamp($seconds);
}
/**
* Get the UNIX timestamp for the given number of seconds.
- *
- * @param int $seconds
- * @return int
*/
- protected function toTimestamp($seconds)
+ protected function toTimestamp($seconds = null): int
{
return $seconds > 0 ? $this->availableAt($seconds) : 0;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function delete($key)
+ public function delete($key): bool
{
unset($this->storage[$key]);
@@ -83,9 +75,9 @@ class ArrayCacheStore implements CacheInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function clear()
+ public function clear(): bool
{
$this->storage = [];
@@ -93,9 +85,9 @@ class ArrayCacheStore implements CacheInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getMultiple($keys, $default = null)
+ public function getMultiple($keys, $default = null): iterable
{
$values = [];
@@ -107,9 +99,9 @@ class ArrayCacheStore implements CacheInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function setMultiple($values, $ttl = null)
+ public function setMultiple($values, $ttl = null): bool
{
foreach ($values as $key => $value) {
$this->set($key, $value, $ttl);
@@ -119,9 +111,9 @@ class ArrayCacheStore implements CacheInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function deleteMultiple($keys)
+ public function deleteMultiple($keys): bool
{
foreach ($keys as $key) {
$this->delete($key);
@@ -131,9 +123,9 @@ class ArrayCacheStore implements CacheInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function has($key)
+ public function has($key): bool
{
return isset($this->storage[$key]);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Builder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Builder.php
index c93c17809..642cf32af 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Builder.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Builder.php
@@ -5,6 +5,7 @@ namespace LdapRecord\Query;
use BadMethodCallException;
use Closure;
use DateTimeInterface;
+use Generator;
use InvalidArgumentException;
use LDAP\Result;
use LdapRecord\Connection;
@@ -12,31 +13,42 @@ use LdapRecord\Container;
use LdapRecord\EscapesValues;
use LdapRecord\LdapInterface;
use LdapRecord\LdapRecordException;
+use LdapRecord\Models\Attributes\EscapedValue;
use LdapRecord\Models\Model;
use LdapRecord\Query\Events\QueryExecuted;
use LdapRecord\Query\Model\Builder as ModelBuilder;
use LdapRecord\Query\Pagination\LazyPaginator;
use LdapRecord\Query\Pagination\Paginator;
use LdapRecord\Support\Arr;
-use LdapRecord\Utilities;
class Builder
{
use EscapesValues;
+ public const TYPE_SEARCH = 'search';
+
+ public const TYPE_READ = 'read';
+
+ public const TYPE_CHUNK = 'chunk';
+
+ public const TYPE_LIST = 'list';
+
+ public const TYPE_PAGINATE = 'paginate';
+
+ /**
+ * The base distinguished name placeholder.
+ */
+ public const BASE_DN_PLACEHOLDER = '{base}';
+
/**
* The selected columns to retrieve on the query.
- *
- * @var array
*/
- public $columns;
+ public ?array $columns = null;
/**
* The query filters.
- *
- * @var array
*/
- public $filters = [
+ public array $filters = [
'and' => [],
'or' => [],
'raw' => [],
@@ -44,120 +56,92 @@ class Builder
/**
* The LDAP server controls to be sent.
- *
- * @var array
*/
- public $controls = [];
+ public array $controls = [];
/**
* The LDAP server controls that were processed.
- *
- * @var array
*/
- public $controlsResponse = [];
+ public array $controlsResponse = [];
/**
* The size limit of the query.
- *
- * @var int
*/
- public $limit = 0;
+ public int $limit = 0;
/**
- * Determines whether the current query is paginated.
- *
- * @var bool
+ * Determine whether the current query is paginated.
*/
- public $paginated = false;
+ public bool $paginated = false;
/**
* The distinguished name to perform searches upon.
- *
- * @var string|null
*/
- protected $dn;
+ protected ?string $dn = null;
/**
* The base distinguished name to perform searches inside.
- *
- * @var string|null
*/
- protected $baseDn;
+ protected ?string $baseDn = null;
/**
* The default query type.
- *
- * @var string
*/
- protected $type = 'search';
+ protected string $type = self::TYPE_SEARCH;
/**
- * Determines whether the query is nested.
- *
- * @var bool
+ * Determine whether the query is nested.
*/
- protected $nested = false;
+ protected bool $nested = false;
/**
- * Determines whether the query should be cached.
- *
- * @var bool
+ * Determine whether the query should be cached.
*/
- protected $caching = false;
+ protected bool $caching = false;
+
+ /**
+ * The custom cache key to use when caching results.
+ */
+ protected ?string $cacheKey = null;
/**
* How long the query should be cached until.
- *
- * @var DateTimeInterface|null
*/
- protected $cacheUntil = null;
+ protected ?DateTimeInterface $cacheUntil = null;
/**
- * Determines whether the query cache must be flushed.
- *
- * @var bool
+ * Determine whether the query cache must be flushed.
*/
- protected $flushCache = false;
+ protected bool $flushCache = false;
/**
* The current connection instance.
- *
- * @var Connection
*/
- protected $connection;
+ protected Connection $connection;
/**
* The current grammar instance.
- *
- * @var Grammar
*/
- protected $grammar;
+ protected Grammar $grammar;
/**
* The current cache instance.
- *
- * @var Cache|null
*/
- protected $cache;
+ protected ?Cache $cache = null;
/**
* Constructor.
- *
- * @param Connection $connection
*/
public function __construct(Connection $connection)
{
$this->connection = $connection;
- $this->grammar = new Grammar();
+ $this->grammar = new Grammar;
}
/**
* Set the current connection.
- *
- * @param Connection $connection
- * @return $this
*/
- public function setConnection(Connection $connection)
+ public function setConnection(Connection $connection): static
{
$this->connection = $connection;
@@ -166,11 +150,8 @@ class Builder
/**
* Set the current filter grammar.
- *
- * @param Grammar $grammar
- * @return $this
*/
- public function setGrammar(Grammar $grammar)
+ public function setGrammar(Grammar $grammar): static
{
$this->grammar = $grammar;
@@ -179,11 +160,8 @@ class Builder
/**
* Set the cache to store query results.
- *
- * @param Cache|null $cache
- * @return $this
*/
- public function setCache(Cache $cache = null)
+ public function setCache(?Cache $cache = null): static
{
$this->cache = $cache;
@@ -192,26 +170,18 @@ class Builder
/**
* Returns a new Query Builder instance.
- *
- * @param string $baseDn
- * @return $this
*/
- public function newInstance($baseDn = null)
+ public function newInstance(?string $baseDn = null): Builder
{
- // We'll set the base DN of the new Builder so
- // developers don't need to do this manually.
- $dn = is_null($baseDn) ? $this->getDn() : $baseDn;
-
- return (new static($this->connection))->setDn($dn);
+ return (new static($this->connection))->setDn(
+ is_null($baseDn) ? $this->getDn() : $baseDn
+ );
}
/**
* Returns a new nested Query Builder instance.
- *
- * @param Closure|null $closure
- * @return $this
*/
- public function newNestedInstance(Closure $closure = null)
+ public function newNestedInstance(?Closure $closure = null): Builder
{
$query = $this->newInstance()->nested();
@@ -224,27 +194,20 @@ class Builder
/**
* Executes the LDAP query.
- *
- * @param string|array $columns
- * @return Collection|array
*/
- public function get($columns = ['*'])
+ public function get(array|string $columns = ['*']): Collection|array
{
- return $this->onceWithColumns(Arr::wrap($columns), function () {
- return $this->query($this->getQuery());
- });
+ return $this->onceWithColumns(
+ Arr::wrap($columns), fn () => $this->query($this->getQuery())
+ );
}
/**
* Execute the given callback while selecting the given columns.
*
* After running the callback, the columns are reset to the original value.
- *
- * @param array $columns
- * @param Closure $callback
- * @return mixed
*/
- protected function onceWithColumns($columns, Closure $callback)
+ protected function onceWithColumns(array $columns, Closure $callback): mixed
{
$original = $this->columns;
@@ -260,11 +223,9 @@ class Builder
}
/**
- * Compiles and returns the current query string.
- *
- * @return string
+ * Compile the query into an LDAP filter string.
*/
- public function getQuery()
+ public function getQuery(): string
{
// We need to ensure we have at least one filter, as
// no query results will be returned otherwise.
@@ -276,134 +237,101 @@ class Builder
}
/**
- * Returns the unescaped query.
- *
- * @return string
+ * Get the unescaped query.
*/
- public function getUnescapedQuery()
+ public function getUnescapedQuery(): string
{
- return Utilities::unescape($this->getQuery());
+ return EscapedValue::unescape($this->getQuery());
}
/**
- * Returns the current Grammar instance.
- *
- * @return Grammar
+ * Get the current Grammar instance.
*/
- public function getGrammar()
+ public function getGrammar(): Grammar
{
return $this->grammar;
}
/**
- * Returns the current Cache instance.
- *
- * @return Cache|null
+ * Get the current Cache instance.
*/
- public function getCache()
+ public function getCache(): ?Cache
{
return $this->cache;
}
/**
- * Returns the current Connection instance.
- *
- * @return Connection
+ * Get the current Connection instance.
*/
- public function getConnection()
+ public function getConnection(): Connection
{
return $this->connection;
}
/**
- * Returns the query type.
- *
- * @return string
+ * Get the query type.
*/
- public function getType()
+ public function getType(): string
{
return $this->type;
}
/**
* Set the base distinguished name of the query.
- *
- * @param Model|string $dn
- * @return $this
*/
- public function setBaseDn($dn)
+ public function setBaseDn(Model|string|null $dn = null): static
{
- $this->baseDn = $this->substituteBaseInDn($dn);
+ $this->baseDn = $this->substituteBaseDn($dn);
return $this;
}
/**
* Get the base distinguished name of the query.
- *
- * @return string|null
*/
- public function getBaseDn()
+ public function getBaseDn(): ?string
{
return $this->baseDn;
}
/**
* Get the distinguished name of the query.
- *
- * @return string
*/
- public function getDn()
+ public function getDn(): ?string
{
return $this->dn;
}
/**
* Set the distinguished name for the query.
- *
- * @param string|Model|null $dn
- * @return $this
*/
- public function setDn($dn = null)
+ public function setDn(Model|string|null $dn = null): static
{
- $this->dn = $this->substituteBaseInDn($dn);
+ $this->dn = $this->substituteBaseDn($dn);
return $this;
}
/**
* Substitute the base DN string template for the current base.
- *
- * @param Model|string $dn
- * @return string
*/
- protected function substituteBaseInDn($dn)
+ public function substituteBaseDn(Model|string|null $dn = null): string
{
- return str_replace(
- '{base}',
- $this->baseDn ?: '',
- (string) ($dn instanceof Model ? $dn->getDn() : $dn)
- );
+ return str_replace(static::BASE_DN_PLACEHOLDER, $this->baseDn ?? '', (string) $dn);
}
/**
* Alias for setting the distinguished name for the query.
- *
- * @param string|Model|null $dn
- * @return $this
*/
- public function in($dn = null)
+ public function in(Model|string|null $dn = null): static
{
return $this->setDn($dn);
}
/**
* Set the size limit of the current query.
- *
- * @param int $limit
- * @return $this
*/
- public function limit($limit = 0)
+ public function limit(int $limit = 0): static
{
$this->limit = $limit;
@@ -412,11 +340,8 @@ class Builder
/**
* Returns a new query for the given model.
- *
- * @param Model $model
- * @return ModelBuilder
*/
- public function model(Model $model)
+ public function model(Model $model): ModelBuilder
{
return $model->newQueryBuilder($this->connection)
->setCache($this->connection->getCache())
@@ -426,20 +351,15 @@ class Builder
/**
* Performs the specified query on the current LDAP connection.
- *
- * @param string $query
- * @return Collection|array
*/
- public function query($query)
+ public function query(string $query): Collection|array
{
$start = microtime(true);
// Here we will create the execution callback. This allows us
// to only execute an LDAP request if caching is disabled
// or if no cache of the given query exists yet.
- $callback = function () use ($query) {
- return $this->parse($this->run($query));
- };
+ $callback = fn () => $this->parse($this->run($query));
$results = $this->getCachedResponse($query, $callback);
@@ -450,12 +370,8 @@ class Builder
/**
* Paginates the current LDAP query.
- *
- * @param int $pageSize
- * @param bool $isCritical
- * @return Collection|array
*/
- public function paginate($pageSize = 1000, $isCritical = false)
+ public function paginate(int $pageSize = 1000, bool $isCritical = false): Collection|array
{
$this->paginated = true;
@@ -466,42 +382,37 @@ class Builder
// Here we will create the pagination callback. This allows us
// to only execute an LDAP request if caching is disabled
// or if no cache of the given query exists yet.
- $callback = function () use ($query, $pageSize, $isCritical) {
- return $this->runPaginate($query, $pageSize, $isCritical);
- };
+ $callback = fn () => $this->runPaginate($query, $pageSize, $isCritical);
$pages = $this->getCachedResponse($query, $callback);
- $this->logQuery($this, 'paginate', $this->getElapsedTime($start));
+ $this->logQuery($this, self::TYPE_PAGINATE, $this->getElapsedTime($start));
return $this->process($pages);
}
/**
* Runs the paginate operation with the given filter.
- *
- * @param string $filter
- * @param int $perPage
- * @param bool $isCritical
- * @return array
*/
- protected function runPaginate($filter, $perPage, $isCritical)
+ protected function runPaginate(string $filter, int $perPage, bool $isCritical): array
{
- return $this->connection->run(function (LdapInterface $ldap) use ($filter, $perPage, $isCritical) {
- return (new Paginator($this, $filter, $perPage, $isCritical))->execute($ldap);
- });
+ return $this->connection->run(
+ fn (LdapInterface $ldap) => $this->newPaginator($filter, $perPage, $isCritical)->execute($ldap)
+ );
+ }
+
+ /**
+ * Make a new paginator instance.
+ */
+ protected function newPaginator(string $filter, int $perPage, bool $isCritical): Paginator
+ {
+ return new Paginator($this, $filter, $perPage, $isCritical);
}
/**
* Execute a callback over each item while chunking.
- *
- * @param Closure $callback
- * @param int $pageSize
- * @param bool $isCritical
- * @param bool $isolate
- * @return bool
*/
- public function each(Closure $callback, $pageSize = 1000, $isCritical = false, $isolate = false)
+ public function each(Closure $callback, int $pageSize = 1000, bool $isCritical = false, bool $isolate = false): bool
{
return $this->chunk($pageSize, function ($results) use ($callback) {
foreach ($results as $key => $value) {
@@ -514,15 +425,11 @@ class Builder
/**
* Chunk the results of a paginated LDAP query.
- *
- * @param int $pageSize
- * @param Closure $callback
- * @param bool $isCritical
- * @param bool $isolate
- * @return bool
*/
- public function chunk($pageSize, Closure $callback, $isCritical = false, $isolate = false)
+ public function chunk(int $pageSize, Closure $callback, bool $isCritical = false, bool $isolate = false): bool
{
+ $this->limit(0);
+
$start = microtime(true);
$chunk = function (Builder $query) use ($pageSize, $callback, $isCritical) {
@@ -537,40 +444,40 @@ class Builder
}
};
- $isolate ? $this->connection->isolate(function (Connection $replicate) use ($chunk) {
- $chunk($this->clone()->setConnection($replicate));
- }) : $chunk($this);
+ // Connection isolation creates a new, temporary connection for the pagination
+ // request to occur on. This allows connections that do not support executing
+ // other queries during a pagination request, to do so without interruption.
+ $isolate ? $this->connection->isolate(
+ fn (Connection $replicate) => $chunk($this->clone()->setConnection($replicate))
+ ) : $chunk($this);
- $this->logQuery($this, 'chunk', $this->getElapsedTime($start));
+ $this->logQuery($this, self::TYPE_CHUNK, $this->getElapsedTime($start));
return true;
}
/**
* Runs the chunk operation with the given filter.
- *
- * @param string $filter
- * @param int $perPage
- * @param bool $isCritical
- * @return \Generator
*/
- protected function runChunk($filter, $perPage, $isCritical)
+ protected function runChunk(string $filter, int $perPage, bool $isCritical): Generator
{
- return $this->connection->run(function (LdapInterface $ldap) use ($filter, $perPage, $isCritical) {
- return (new LazyPaginator($this, $filter, $perPage, $isCritical))->execute($ldap);
- });
+ return $this->connection->run(
+ fn (LdapInterface $ldap) => $this->newLazyPaginator($filter, $perPage, $isCritical)->execute($ldap)
+ );
+ }
+
+ /**
+ * Make a new lazy paginator instance.
+ */
+ protected function newLazyPaginator(string $filter, int $perPage, bool $isCritical): LazyPaginator
+ {
+ return new LazyPaginator($this, $filter, $perPage, $isCritical);
}
/**
* Create a slice of the LDAP query into a page.
- *
- * @param int $page
- * @param int $perPage
- * @param string $orderBy
- * @param string $orderByDir
- * @return Slice
*/
- public function slice($page = 1, $perPage = 100, $orderBy = 'cn', $orderByDir = 'asc')
+ public function slice(int $page = 1, int $perPage = 100, string $orderBy = 'cn', string $orderByDir = 'asc'): Slice
{
$results = $this->forPage($page, $perPage, $orderBy, $orderByDir);
@@ -589,14 +496,8 @@ class Builder
/**
* Get the results of a query for a given page.
- *
- * @param int $page
- * @param int $perPage
- * @param string $orderBy
- * @param string $orderByDir
- * @return Collection|array
*/
- public function forPage($page = 1, $perPage = 100, $orderBy = 'cn', $orderByDir = 'asc')
+ public function forPage(int $page = 1, int $perPage = 100, string $orderBy = 'cn', string $orderByDir = 'asc'): Collection|array
{
if (! $this->hasOrderBy()) {
$this->orderBy($orderBy, $orderByDir);
@@ -614,11 +515,8 @@ class Builder
/**
* Processes and converts the given LDAP results into models.
- *
- * @param array $results
- * @return array
*/
- protected function process(array $results)
+ protected function process(array $results): mixed
{
unset($results['count']);
@@ -631,11 +529,8 @@ class Builder
/**
* Flattens LDAP paged results into a single array.
- *
- * @param array $pages
- * @return array
*/
- protected function flattenPages(array $pages)
+ protected function flattenPages(array $pages): array
{
$records = [];
@@ -650,15 +545,11 @@ class Builder
/**
* Get the cached response or execute and cache the callback value.
- *
- * @param string $query
- * @param Closure $callback
- * @return mixed
*/
- protected function getCachedResponse($query, Closure $callback)
+ protected function getCachedResponse(string $query, Closure $callback): mixed
{
if ($this->cache && $this->caching) {
- $key = $this->getCacheKey($query);
+ $key = $this->cacheKey ?? $this->getCacheKey($query);
if ($this->flushCache) {
$this->cache->delete($key);
@@ -667,16 +558,20 @@ class Builder
return $this->cache->remember($key, $this->cacheUntil, $callback);
}
- return $callback();
+ try {
+ return $callback();
+ } finally {
+ $this->caching = false;
+ $this->cacheKey = null;
+ $this->cacheUntil = null;
+ $this->flushCache = false;
+ }
}
/**
* Runs the query operation with the given filter.
- *
- * @param string $filter
- * @return resource
*/
- public function run($filter)
+ public function run(string $filter): mixed
{
return $this->connection->run(function (LdapInterface $ldap) use ($filter) {
// We will avoid setting the controls during any pagination
@@ -690,7 +585,7 @@ class Builder
}
return $ldap->{$this->type}(
- $this->dn ?? $this->baseDn,
+ (string) ($this->dn ?? $this->baseDn),
$filter,
$this->getSelects(),
$onlyAttributes = false,
@@ -701,11 +596,8 @@ class Builder
/**
* Parses the given LDAP resource by retrieving its entries.
- *
- * @param resource $resource
- * @return array
*/
- public function parse($resource)
+ public function parse(mixed $resource): array
{
if (! $resource) {
return [];
@@ -714,17 +606,10 @@ class Builder
return $this->connection->run(function (LdapInterface $ldap) use ($resource) {
$this->controlsResponse = $this->controls;
- $errorCode = 0;
- $dn = $errorMessage = $refs = null;
-
// Process the server controls response.
$ldap->parseResult(
- $resource,
- $errorCode,
- $dn,
- $errorMessage,
- $refs,
- $this->controlsResponse
+ result: $resource,
+ controls: $this->controlsResponse
);
$entries = $ldap->getEntries($resource);
@@ -739,16 +624,13 @@ class Builder
}
/**
- * Returns the cache key.
- *
- * @param string $query
- * @return string
+ * Get the cache key.
*/
- protected function getCacheKey($query)
+ protected function getCacheKey(string $query): string
{
- $host = $this->connection->run(function (LdapInterface $ldap) {
- return $ldap->getHost();
- });
+ $host = $this->connection->run(
+ fn (LdapInterface $ldap) => $ldap->getHost()
+ );
$key = $host
.$this->type
@@ -762,12 +644,9 @@ class Builder
}
/**
- * Returns the first entry in a search result.
- *
- * @param array|string $columns
- * @return Model|null
+ * Get the first entry in a search result.
*/
- public function first($columns = ['*'])
+ public function first(array|string $columns = ['*']): Model|array|null
{
return Arr::first(
$this->limit(1)->get($columns)
@@ -775,16 +654,13 @@ class Builder
}
/**
- * Returns the first entry in a search result.
+ * Get the first entry in a search result.
*
* If no entry is found, an exception is thrown.
*
- * @param array|string $columns
- * @return Model|array
- *
* @throws ObjectNotFoundException
*/
- public function firstOrFail($columns = ['*'])
+ public function firstOrFail(array|string $columns = ['*']): Model|array
{
if (! $record = $this->first($columns)) {
$this->throwNotFoundException($this->getUnescapedQuery(), $this->dn);
@@ -794,12 +670,9 @@ class Builder
}
/**
- * Return the first entry in a result, or execute the callback.
- *
- * @param Closure $callback
- * @return Model|mixed
+ * Get the first entry in a result, or execute the callback.
*/
- public function firstOr(Closure $callback)
+ public function firstOr(Closure $callback): mixed
{
return $this->first() ?: $callback();
}
@@ -807,13 +680,10 @@ class Builder
/**
* Execute the query and get the first result if it's the sole matching record.
*
- * @param array|string $columns
- * @return Model|array
- *
* @throws ObjectsNotFoundException
* @throws MultipleObjectsFoundException
*/
- public function sole($columns = ['*'])
+ public function sole(array|string $columns = ['*']): Model|array
{
$result = $this->limit(2)->get($columns);
@@ -830,31 +700,24 @@ class Builder
/**
* Determine if any results exist for the current query.
- *
- * @return bool
*/
- public function exists()
+ public function exists(): bool
{
return ! is_null($this->first());
}
/**
* Determine if no results exist for the current query.
- *
- * @return bool
*/
- public function doesntExist()
+ public function doesntExist(): bool
{
return ! $this->exists();
}
/**
* Execute the given callback if no rows exist for the current query.
- *
- * @param Closure $callback
- * @return bool|mixed
*/
- public function existsOr(Closure $callback)
+ public function existsOr(Closure $callback): mixed
{
return $this->exists() ? true : $callback();
}
@@ -862,12 +725,9 @@ class Builder
/**
* Throws a not found exception.
*
- * @param string $query
- * @param string $dn
- *
* @throws ObjectNotFoundException
*/
- protected function throwNotFoundException($query, $dn)
+ protected function throwNotFoundException(string $query, ?string $dn = null): void
{
throw ObjectNotFoundException::forQuery($query, $dn);
}
@@ -875,17 +735,14 @@ class Builder
/**
* Finds a record by the specified attribute and value.
*
- * @param string $attribute
- * @param string $value
- * @param array|string $columns
* @return Model|static|null
*/
- public function findBy($attribute, $value, $columns = ['*'])
+ public function findBy(string $attribute, string $value, array|string $columns = ['*']): Model|array|null
{
try {
return $this->findByOrFail($attribute, $value, $columns);
} catch (ObjectNotFoundException $e) {
- return;
+ return null;
}
}
@@ -894,26 +751,17 @@ class Builder
*
* If no record is found an exception is thrown.
*
- * @param string $attribute
- * @param string $value
- * @param array|string $columns
- * @return Model
- *
* @throws ObjectNotFoundException
*/
- public function findByOrFail($attribute, $value, $columns = ['*'])
+ public function findByOrFail(string $attribute, string $value, array|string $columns = ['*']): Model|array
{
return $this->whereEquals($attribute, $value)->firstOrFail($columns);
}
/**
* Find many records by distinguished name.
- *
- * @param string|array $dns
- * @param array $columns
- * @return array|Collection
*/
- public function findMany($dns, $columns = ['*'])
+ public function findMany(array|string $dns, array|string $columns = ['*']): Collection|array
{
if (empty($dns)) {
return $this->process([]);
@@ -932,13 +780,8 @@ class Builder
/**
* Finds many records by the specified attribute.
- *
- * @param string $attribute
- * @param array $values
- * @param array $columns
- * @return Collection
*/
- public function findManyBy($attribute, array $values = [], $columns = ['*'])
+ public function findManyBy(string $attribute, array $values = [], array|string $columns = ['*']): Collection|array
{
$query = $this->select($columns);
@@ -951,12 +794,8 @@ class Builder
/**
* Finds a record by its distinguished name.
- *
- * @param string|array $dn
- * @param array|string $columns
- * @return Model|static|array|Collection|null
*/
- public function find($dn, $columns = ['*'])
+ public function find(array|string $dn, array|string $columns = ['*']): Collection|Model|array|null
{
if (is_array($dn)) {
return $this->findMany($dn, $columns);
@@ -965,7 +804,7 @@ class Builder
try {
return $this->findOrFail($dn, $columns);
} catch (ObjectNotFoundException $e) {
- return;
+ return null;
}
}
@@ -974,13 +813,9 @@ class Builder
*
* Fails upon no records returned.
*
- * @param string $dn
- * @param array|string $columns
- * @return Model|static
- *
* @throws ObjectNotFoundException
*/
- public function findOrFail($dn, $columns = ['*'])
+ public function findOrFail(string $dn, array|string $columns = ['*']): Model|array
{
return $this->setDn($dn)
->read()
@@ -990,11 +825,8 @@ class Builder
/**
* Adds the inserted fields to query on the current LDAP connection.
- *
- * @param array|string $columns
- * @return $this
*/
- public function select($columns = ['*'])
+ public function select(array|string $columns = ['*']): static
{
$columns = is_array($columns) ? $columns : func_get_args();
@@ -1007,11 +839,8 @@ class Builder
/**
* Add a new select column to the query.
- *
- * @param array|mixed $column
- * @return $this
*/
- public function addSelect($column)
+ public function addSelect(array|string $column): static
{
$column = is_array($column) ? $column : func_get_args();
@@ -1022,46 +851,38 @@ class Builder
/**
* Add an order by control to the query.
- *
- * @param string $attribute
- * @param string $direction
- * @return $this
*/
- public function orderBy($attribute, $direction = 'asc')
+ public function orderBy(string $attribute, string $direction = 'asc', array $options = []): static
{
return $this->addControl(LDAP_CONTROL_SORTREQUEST, true, [
- ['attr' => $attribute, 'reverse' => $direction === 'desc'],
+ [
+ ...$options,
+ 'attr' => $attribute,
+ 'reverse' => $direction === 'desc',
+ ],
]);
}
/**
* Add an order by descending control to the query.
- *
- * @param string $attribute
- * @return $this
*/
- public function orderByDesc($attribute)
+ public function orderByDesc(string $attribute, array $options = []): static
{
- return $this->orderBy($attribute, 'desc');
+ return $this->orderBy($attribute, 'desc', $options);
}
/**
* Determine if the query has a sotr request control header.
- *
- * @return bool
*/
- public function hasOrderBy()
+ public function hasOrderBy(): bool
{
return $this->hasControl(LDAP_CONTROL_SORTREQUEST);
}
/**
* Adds a raw filter to the current query.
- *
- * @param array|string $filters
- * @return $this
*/
- public function rawFilter($filters = [])
+ public function rawFilter(array|string $filters = []): static
{
$filters = is_array($filters) ? $filters : func_get_args();
@@ -1074,11 +895,8 @@ class Builder
/**
* Adds a nested 'and' filter to the current query.
- *
- * @param Closure $closure
- * @return $this
*/
- public function andFilter(Closure $closure)
+ public function andFilter(Closure $closure): static
{
$query = $this->newNestedInstance($closure);
@@ -1089,11 +907,8 @@ class Builder
/**
* Adds a nested 'or' filter to the current query.
- *
- * @param Closure $closure
- * @return $this
*/
- public function orFilter(Closure $closure)
+ public function orFilter(Closure $closure): static
{
$query = $this->newNestedInstance($closure);
@@ -1104,11 +919,8 @@ class Builder
/**
* Adds a nested 'not' filter to the current query.
- *
- * @param Closure $closure
- * @return $this
*/
- public function notFilter(Closure $closure)
+ public function notFilter(Closure $closure): static
{
$query = $this->newNestedInstance($closure);
@@ -1120,30 +932,23 @@ class Builder
/**
* Adds a where clause to the current query.
*
- * @param string|array $field
- * @param string $operator
- * @param string $value
- * @param string $boolean
- * @param bool $raw
- * @return $this
- *
* @throws InvalidArgumentException
*/
- public function where($field, $operator = null, $value = null, $boolean = 'and', $raw = false)
+ public function where(array|string $field, mixed $operator = null, mixed $value = null, string $boolean = 'and', bool $raw = false): static
{
if (is_array($field)) {
// If the field is an array, we will assume we have been
// provided with an array of key-value pairs and can
- // add them each as their own seperate where clause.
+ // add them each as their own separate where clause.
return $this->addArrayOfWheres($field, $boolean, $raw);
}
// If we have been provided with two arguments not a "has" or
// "not has" operator, we'll assume the developer is creating
// an "equals" clause and set the proper operator in place.
- if (func_num_args() === 2 && ! in_array($operator, ['*', '!*'])) {
- [$value, $operator] = [$operator, '='];
- }
+ [$value, $operator] = $this->prepareValueAndOperator(
+ $value, $operator, func_num_args() === 2 && ! $this->operatorRequiresValue($operator)
+ );
if (! in_array($operator, $this->grammar->getOperators())) {
throw new InvalidArgumentException("Invalid LDAP filter operator [$operator]");
@@ -1152,7 +957,7 @@ class Builder
// We'll escape the value if raw isn't requested.
$value = $this->prepareWhereValue($field, $value, $raw);
- $field = $this->escape($field)->both()->get();
+ $field = $this->escape($field)->forDnAndFilter()->get();
$this->addFilter($boolean, compact('field', 'operator', 'value'));
@@ -1160,125 +965,114 @@ class Builder
}
/**
- * Prepare the value for being queried.
- *
- * @param string $field
- * @param string $value
- * @param bool $raw
- * @return string
+ * Prepare the value and operator for a where clause.
*/
- protected function prepareWhereValue($field, $value, $raw = false)
+ public function prepareValueAndOperator(mixed $value, mixed $operator, bool $useDefault = false): array
{
- return $raw ? $value : $this->escape($value);
+ if ($useDefault) {
+ return [$operator, '='];
+ }
+
+ return [$value, $operator];
+ }
+
+ /**
+ * Determine if the operator requires a value to be present.
+ */
+ protected function operatorRequiresValue(mixed $operator): bool
+ {
+ return in_array($operator, ['*', '!*']);
+ }
+
+ /**
+ * Prepare the value for being queried.
+ */
+ protected function prepareWhereValue(string $field, mixed $value = null, bool $raw = false): string
+ {
+ return $raw ? $value : $this->escape($value)->get();
}
/**
* Adds a raw where clause to the current query.
*
* Values given to this method are not escaped.
- *
- * @param string|array $field
- * @param string $operator
- * @param string $value
- * @return $this
*/
- public function whereRaw($field, $operator = null, $value = null)
+ public function whereRaw(array|string $field, ?string $operator = null, mixed $value = null): static
{
return $this->where($field, $operator, $value, 'and', true);
}
/**
* Adds a 'where equals' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function whereEquals($field, $value)
+ public function whereEquals(string $field, string $value): static
{
return $this->where($field, '=', $value);
}
/**
* Adds a 'where not equals' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function whereNotEquals($field, $value)
+ public function whereNotEquals(string $field, string $value): static
{
return $this->where($field, '!', $value);
}
/**
* Adds a 'where approximately equals' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function whereApproximatelyEquals($field, $value)
+ public function whereApproximatelyEquals(string $field, string $value): static
{
return $this->where($field, '~=', $value);
}
/**
* Adds a 'where has' clause to the current query.
- *
- * @param string $field
- * @return $this
*/
- public function whereHas($field)
+ public function whereHas(string $field): static
{
return $this->where($field, '*');
}
/**
* Adds a 'where not has' clause to the current query.
- *
- * @param string $field
- * @return $this
*/
- public function whereNotHas($field)
+ public function whereNotHas(string $field): static
{
return $this->where($field, '!*');
}
/**
* Adds a 'where contains' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function whereContains($field, $value)
+ public function whereContains(string $field, string $value): static
{
return $this->where($field, 'contains', $value);
}
/**
* Adds a 'where contains' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function whereNotContains($field, $value)
+ public function whereNotContains(string $field, string $value): static
{
return $this->where($field, 'not_contains', $value);
}
/**
* Query for entries that match any of the values provided for the given field.
- *
- * @param string $field
- * @param array $values
- * @return $this
*/
- public function whereIn($field, array $values)
+ public function whereIn(string $field, array $values): static
{
- return $this->orFilter(function (self $query) use ($field, $values) {
+ if (empty($values)) {
+ // If the array of values is empty, we will
+ // add an empty OR filter to the query to
+ // ensure that no results are returned.
+ $this->rawFilter('(|)');
+
+ return $this;
+ }
+
+ return $this->orFilter(function (Builder $query) use ($field, $values) {
foreach ($values as $value) {
$query->whereEquals($field, $value);
}
@@ -1287,12 +1081,8 @@ class Builder
/**
* Adds a 'between' clause to the current query.
- *
- * @param string $field
- * @param array $values
- * @return $this
*/
- public function whereBetween($field, array $values)
+ public function whereBetween(string $field, array $values): static
{
return $this->where([
[$field, '>=', $values[0]],
@@ -1302,81 +1092,56 @@ class Builder
/**
* Adds a 'where starts with' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function whereStartsWith($field, $value)
+ public function whereStartsWith(string $field, string $value): static
{
return $this->where($field, 'starts_with', $value);
}
/**
* Adds a 'where *not* starts with' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function whereNotStartsWith($field, $value)
+ public function whereNotStartsWith(string $field, string $value): static
{
return $this->where($field, 'not_starts_with', $value);
}
/**
* Adds a 'where ends with' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function whereEndsWith($field, $value)
+ public function whereEndsWith(string $field, string $value): static
{
return $this->where($field, 'ends_with', $value);
}
/**
* Adds a 'where *not* ends with' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function whereNotEndsWith($field, $value)
+ public function whereNotEndsWith(string $field, string $value): static
{
return $this->where($field, 'not_ends_with', $value);
}
/**
* Only include deleted models in the results.
- *
- * @return $this
*/
- public function whereDeleted()
+ public function whereDeleted(): static
{
return $this->withDeleted()->whereEquals('isDeleted', 'TRUE');
}
/**
* Set the LDAP control option to include deleted LDAP models.
- *
- * @return $this
*/
- public function withDeleted()
+ public function withDeleted(): static
{
return $this->addControl(LdapInterface::OID_SERVER_SHOW_DELETED, $isCritical = true);
}
/**
* Add a server control to the query.
- *
- * @param string $oid
- * @param bool $isCritical
- * @param mixed $value
- * @return $this
*/
- public function addControl($oid, $isCritical = false, $value = null)
+ public function addControl(string $oid, bool $isCritical = false, mixed $value = null): static
{
$this->controls[$oid] = compact('oid', 'isCritical', 'value');
@@ -1385,25 +1150,21 @@ class Builder
/**
* Determine if the server control exists on the query.
- *
- * @param string $oid
- * @return bool
*/
- public function hasControl($oid)
+ public function hasControl(string $oid): bool
{
return array_key_exists($oid, $this->controls);
}
/**
* Adds an 'or where' clause to the current query.
- *
- * @param array|string $field
- * @param string|null $operator
- * @param string|null $value
- * @return $this
*/
- public function orWhere($field, $operator = null, $value = null)
+ public function orWhere(array|string $field, ?string $operator = null, ?string $value = null): static
{
+ [$value, $operator] = $this->prepareValueAndOperator(
+ $value, $operator, func_num_args() === 2 && ! $this->operatorRequiresValue($operator)
+ );
+
return $this->where($field, $operator, $value, 'or');
}
@@ -1411,143 +1172,96 @@ class Builder
* Adds a raw or where clause to the current query.
*
* Values given to this method are not escaped.
- *
- * @param string $field
- * @param string $operator
- * @param string $value
- * @return $this
*/
- public function orWhereRaw($field, $operator = null, $value = null)
+ public function orWhereRaw(array|string $field, ?string $operator = null, ?string $value = null): static
{
return $this->where($field, $operator, $value, 'or', true);
}
/**
* Adds an 'or where has' clause to the current query.
- *
- * @param string $field
- * @return $this
*/
- public function orWhereHas($field)
+ public function orWhereHas(string $field): static
{
return $this->orWhere($field, '*');
}
/**
* Adds a 'where not has' clause to the current query.
- *
- * @param string $field
- * @return $this
*/
- public function orWhereNotHas($field)
+ public function orWhereNotHas(string $field): static
{
return $this->orWhere($field, '!*');
}
/**
* Adds an 'or where equals' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function orWhereEquals($field, $value)
+ public function orWhereEquals(string $field, string $value): static
{
return $this->orWhere($field, '=', $value);
}
/**
* Adds an 'or where not equals' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function orWhereNotEquals($field, $value)
+ public function orWhereNotEquals(string $field, string $value): static
{
return $this->orWhere($field, '!', $value);
}
/**
* Adds a 'or where approximately equals' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function orWhereApproximatelyEquals($field, $value)
+ public function orWhereApproximatelyEquals(string $field, string $value): static
{
return $this->orWhere($field, '~=', $value);
}
/**
* Adds an 'or where contains' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function orWhereContains($field, $value)
+ public function orWhereContains(string $field, string $value): static
{
return $this->orWhere($field, 'contains', $value);
}
/**
* Adds an 'or where *not* contains' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function orWhereNotContains($field, $value)
+ public function orWhereNotContains(string $field, string $value): static
{
return $this->orWhere($field, 'not_contains', $value);
}
/**
* Adds an 'or where starts with' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function orWhereStartsWith($field, $value)
+ public function orWhereStartsWith(string $field, string $value): static
{
return $this->orWhere($field, 'starts_with', $value);
}
/**
* Adds an 'or where *not* starts with' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function orWhereNotStartsWith($field, $value)
+ public function orWhereNotStartsWith(string $field, string $value): static
{
return $this->orWhere($field, 'not_starts_with', $value);
}
/**
* Adds an 'or where ends with' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function orWhereEndsWith($field, $value)
+ public function orWhereEndsWith(string $field, string $value): static
{
return $this->orWhere($field, 'ends_with', $value);
}
/**
* Adds an 'or where *not* ends with' clause to the current query.
- *
- * @param string $field
- * @param string $value
- * @return $this
*/
- public function orWhereNotEndsWith($field, $value)
+ public function orWhereNotEndsWith(string $field, string $value): static
{
return $this->orWhere($field, 'not_ends_with', $value);
}
@@ -1555,13 +1269,9 @@ class Builder
/**
* Adds a filter binding onto the current query.
*
- * @param string $type The type of filter to add.
- * @param array $bindings The bindings of the filter.
- * @return $this
- *
* @throws InvalidArgumentException
*/
- public function addFilter($type, array $bindings)
+ public function addFilter(string $type, array $bindings): static
{
if (! array_key_exists($type, $this->filters)) {
throw new InvalidArgumentException("Filter type: [$type] is invalid.");
@@ -1583,11 +1293,8 @@ class Builder
/**
* Extract any missing required binding keys.
- *
- * @param array $bindings
- * @return array
*/
- protected function missingBindingKeys($bindings)
+ protected function missingBindingKeys(array $bindings): array
{
$required = array_flip(['field', 'operator', 'value']);
@@ -1598,20 +1305,16 @@ class Builder
/**
* Get all the filters on the query.
- *
- * @return array
*/
- public function getFilters()
+ public function getFilters(): array
{
return $this->filters;
}
/**
* Clear the query filters.
- *
- * @return $this
*/
- public function clearFilters()
+ public function clearFilters(): static
{
foreach (array_keys($this->filters) as $type) {
$this->filters[$type] = [];
@@ -1622,20 +1325,16 @@ class Builder
/**
* Determine if the query has attributes selected.
- *
- * @return bool
*/
- public function hasSelects()
+ public function hasSelects(): bool
{
- return count($this->columns) > 0;
+ return count($this->columns ?? []) > 0;
}
/**
* Get the attributes to select on the search.
- *
- * @return array
*/
- public function getSelects()
+ public function getSelects(): array
{
$selects = $this->columns ?? ['*'];
@@ -1659,49 +1358,48 @@ class Builder
* Set the query to search on the base distinguished name.
*
* This will result in one record being returned.
- *
- * @return $this
*/
- public function read()
+ public function read(): static
{
- $this->type = 'read';
+ $this->type = self::TYPE_READ;
return $this;
}
/**
* Set the query to search one level on the base distinguished name.
- *
- * @return $this
*/
- public function listing()
+ public function list(): static
{
- $this->type = 'listing';
+ $this->type = self::TYPE_LIST;
return $this;
}
/**
- * Set the query to search the entire directory on the base distinguished name.
- *
- * @return $this
+ * Alias for the "search" method.
*/
- public function recursive()
+ public function recursive(): static
{
- $this->type = 'search';
+ return $this->search();
+ }
+
+ /**
+ * Set the query to search the entire directory on the base distinguished name.
+ */
+ public function search(): static
+ {
+ $this->type = self::TYPE_SEARCH;
return $this;
}
/**
* Whether to mark the current query as nested.
- *
- * @param bool $nested
- * @return $this
*/
- public function nested($nested = true)
+ public function nested(bool $nested = true): static
{
- $this->nested = (bool) $nested;
+ $this->nested = $nested;
return $this;
}
@@ -1710,14 +1408,11 @@ class Builder
* Enables caching on the current query until the given date.
*
* If flushing is enabled, the query cache will be flushed and then re-cached.
- *
- * @param DateTimeInterface $until When to expire the query cache.
- * @param bool $flush Whether to force-flush the query cache.
- * @return $this
*/
- public function cache(DateTimeInterface $until = null, $flush = false)
+ public function cache(?DateTimeInterface $until = null, bool $flush = false, ?string $key = null): static
{
$this->caching = true;
+ $this->cacheKey = $key;
$this->cacheUntil = $until;
$this->flushCache = $flush;
@@ -1726,20 +1421,16 @@ class Builder
/**
* Determine if the query is nested.
- *
- * @return bool
*/
- public function isNested()
+ public function isNested(): bool
{
return $this->nested === true;
}
/**
* Determine whether the query is paginated.
- *
- * @return bool
*/
- public function isPaginated()
+ public function isPaginated(): bool
{
return $this->paginated;
}
@@ -1747,14 +1438,22 @@ class Builder
/**
* Insert an entry into the directory.
*
- * @param string $dn
- * @param array $attributes
- * @return bool
+ * @throws LdapRecordException
+ */
+ public function insert(string $dn, array $attributes): bool
+ {
+ return (bool) $this->insertAndGetDn($dn, $attributes);
+ }
+
+ /**
+ * Insert an entry into the directory and get the inserted distinguished name.
*
* @throws LdapRecordException
*/
- public function insert($dn, array $attributes)
+ public function insertAndGetDn(string $dn, array $attributes): string|false
{
+ $dn = $this->substituteBaseDn($dn);
+
if (empty($dn)) {
throw new LdapRecordException('A new LDAP object must have a distinguished name (dn).');
}
@@ -1765,102 +1464,85 @@ class Builder
);
}
- return $this->connection->run(function (LdapInterface $ldap) use ($dn, $attributes) {
- return $ldap->add($dn, $attributes);
- });
+ return $this->connection->run(
+ fn (LdapInterface $ldap) => $ldap->add($dn, $attributes)
+ ) ? $dn : false;
}
/**
- * Create attributes on the entry in the directory.
- *
- * @param string $dn
- * @param array $attributes
- * @return bool
+ * Add attributes to an entry in the directory.
*/
- public function insertAttributes($dn, array $attributes)
+ public function add(string $dn, array $attributes): bool
{
- return $this->connection->run(function (LdapInterface $ldap) use ($dn, $attributes) {
- return $ldap->modAdd($dn, $attributes);
- });
+ return $this->connection->run(
+ fn (LdapInterface $ldap) => $ldap->modAdd($dn, $attributes)
+ );
}
/**
* Update the entry with the given modifications.
- *
- * @param string $dn
- * @param array $modifications
- * @return bool
*/
- public function update($dn, array $modifications)
+ public function update(string $dn, array $modifications): bool
{
- return $this->connection->run(function (LdapInterface $ldap) use ($dn, $modifications) {
- return $ldap->modifyBatch($dn, $modifications);
- });
+ return $this->connection->run(
+ fn (LdapInterface $ldap) => $ldap->modifyBatch($dn, $modifications)
+ );
}
/**
- * Update an entries attribute in the directory.
- *
- * @param string $dn
- * @param array $attributes
- * @return bool
+ * Replace an entry's attributes in the directory.
*/
- public function updateAttributes($dn, array $attributes)
+ public function replace(string $dn, array $attributes): bool
{
- return $this->connection->run(function (LdapInterface $ldap) use ($dn, $attributes) {
- return $ldap->modReplace($dn, $attributes);
- });
+ return $this->connection->run(
+ fn (LdapInterface $ldap) => $ldap->modReplace($dn, $attributes)
+ );
}
/**
* Delete an entry from the directory.
- *
- * @param string $dn
- * @return bool
*/
- public function delete($dn)
+ public function delete(string $dn): bool
{
- return $this->connection->run(function (LdapInterface $ldap) use ($dn) {
- return $ldap->delete($dn);
- });
+ return $this->connection->run(
+ fn (LdapInterface $ldap) => $ldap->delete($dn)
+ );
}
/**
- * Delete attributes on the entry in the directory.
- *
- * @param string $dn
- * @param array $attributes
- * @return bool
+ * Remove attributes on the entry in the directory.
*/
- public function deleteAttributes($dn, array $attributes)
+ public function remove(string $dn, array $attributes): bool
{
- return $this->connection->run(function (LdapInterface $ldap) use ($dn, $attributes) {
- return $ldap->modDelete($dn, $attributes);
- });
+ return $this->connection->run(
+ fn (LdapInterface $ldap) => $ldap->modDelete($dn, $attributes)
+ );
}
/**
* Rename an entry in the directory.
- *
- * @param string $dn
- * @param string $rdn
- * @param string $newParentDn
- * @param bool $deleteOldRdn
- * @return bool
*/
- public function rename($dn, $rdn, $newParentDn, $deleteOldRdn = true)
+ public function rename(string $dn, string $rdn, string $newParentDn, bool $deleteOldRdn = true): bool
{
- return $this->connection->run(function (LdapInterface $ldap) use ($dn, $rdn, $newParentDn, $deleteOldRdn) {
- return $ldap->rename($dn, $rdn, $newParentDn, $deleteOldRdn);
- });
+ return (bool) $this->renameAndGetDn($dn, $rdn, $newParentDn, $deleteOldRdn);
+ }
+
+ /**
+ * Rename an entry in the directory and get the new distinguished name.
+ */
+ public function renameAndGetDn(string $dn, string $rdn, string $newParentDn, bool $deleteOldRdn = true): string|false
+ {
+ $newParentDn = $this->substituteBaseDn($newParentDn);
+
+ return $this->connection->run(
+ fn (LdapInterface $ldap) => $ldap->rename($dn, $rdn, $newParentDn, $deleteOldRdn)
+ ) ? implode(',', [$rdn, $newParentDn]) : false;
}
/**
* Clone the query.
- *
- * @return static
*/
- public function clone()
+ public function clone(): static
{
return clone $this;
}
@@ -1868,18 +1550,14 @@ class Builder
/**
* Handle dynamic method calls on the query builder.
*
- * @param string $method
- * @param array $parameters
- * @return mixed
- *
* @throws BadMethodCallException
*/
- public function __call($method, $parameters)
+ public function __call(string $method, array $parameters): static
{
// If the beginning of the method being called contains
// 'where', we will assume a dynamic 'where' clause is
// being performed and pass the parameters to it.
- if (substr($method, 0, 5) === 'where') {
+ if (str_starts_with($method, 'where')) {
return $this->dynamicWhere($method, $parameters);
}
@@ -1893,11 +1571,9 @@ class Builder
/**
* Handles dynamic "where" clauses to the query.
*
- * @param string $method
- * @param array $parameters
* @return $this
*/
- public function dynamicWhere($method, $parameters)
+ public function dynamicWhere(string $method, array $parameters): static
{
$finder = substr($method, 5);
@@ -1933,13 +1609,8 @@ class Builder
/**
* Adds an array of wheres to the current query.
- *
- * @param array $wheres
- * @param string $boolean
- * @param bool $raw
- * @return $this
*/
- protected function addArrayOfWheres($wheres, $boolean, $raw)
+ protected function addArrayOfWheres(array $wheres, string $boolean, bool $raw): static
{
foreach ($wheres as $key => $value) {
if (is_numeric($key) && is_array($value)) {
@@ -1964,14 +1635,8 @@ class Builder
/**
* Add a single dynamic where clause statement to the query.
- *
- * @param string $segment
- * @param string $connector
- * @param array $parameters
- * @param int $index
- * @return void
*/
- protected function addDynamic($segment, $connector, $parameters, $index)
+ protected function addDynamic(string $segment, string $connector, array $parameters, int $index): void
{
// If no parameters were given to the dynamic where clause,
// we can assume a "has" attribute filter is being added.
@@ -1984,55 +1649,34 @@ class Builder
/**
* Logs the given executed query information by firing its query event.
- *
- * @param Builder $query
- * @param string $type
- * @param null|float $time
- * @return void
*/
- protected function logQuery($query, $type, $time = null)
+ protected function logQuery(Builder $query, string $type, ?float $time = null): void
{
$args = [$query, $time];
- switch ($type) {
- case 'listing':
- $event = new Events\Listing(...$args);
- break;
- case 'read':
- $event = new Events\Read(...$args);
- break;
- case 'chunk':
- $event = new Events\Chunk(...$args);
- break;
- case 'paginate':
- $event = new Events\Paginate(...$args);
- break;
- default:
- $event = new Events\Search(...$args);
- break;
- }
-
- $this->fireQueryEvent($event);
+ $this->fireQueryEvent(
+ match ($type) {
+ self::TYPE_READ => new Events\Read(...$args),
+ self::TYPE_CHUNK => new Events\Chunk(...$args),
+ self::TYPE_LIST => new Events\Listing(...$args),
+ self::TYPE_PAGINATE => new Events\Paginate(...$args),
+ default => new Events\Search(...$args),
+ }
+ );
}
/**
* Fires the given query event.
- *
- * @param QueryExecuted $event
- * @return void
*/
- protected function fireQueryEvent(QueryExecuted $event)
+ protected function fireQueryEvent(QueryExecuted $event): void
{
- Container::getInstance()->getEventDispatcher()->fire($event);
+ Container::getInstance()->getDispatcher()->fire($event);
}
/**
* Get the elapsed time since a given starting point.
- *
- * @param int $start
- * @return float
*/
- protected function getElapsedTime($start)
+ protected function getElapsedTime(float $start): float
{
return round((microtime(true) - $start) * 1000, 2);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Cache.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Cache.php
index d6057bfb3..184455ced 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Cache.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Cache.php
@@ -13,15 +13,11 @@ class Cache
/**
* The cache driver.
- *
- * @var CacheInterface
*/
- protected $store;
+ protected CacheInterface $store;
/**
* Constructor.
- *
- * @param CacheInterface $store
*/
public function __construct(CacheInterface $store)
{
@@ -30,47 +26,26 @@ class Cache
/**
* Get an item from the cache.
- *
- * @param string $key
- * @return mixed
*/
- public function get($key)
+ public function get(string $key): mixed
{
return $this->store->get($key);
}
/**
* Store an item in the cache.
- *
- * @param string $key
- * @param mixed $value
- * @param DateTimeInterface|DateInterval|int|null $ttl
- * @return bool
*/
- public function put($key, $value, $ttl = null)
+ public function put(string $key, mixed $value, DateTimeInterface|DateInterval|int|null $ttl = null): bool
{
- $seconds = $this->secondsUntil($ttl);
-
- if ($seconds <= 0) {
- return $this->delete($key);
- }
-
- return $this->store->set($key, $value, $seconds);
+ return $this->store->set($key, $value, $this->secondsUntil($ttl));
}
/**
* Get an item from the cache, or execute the given Closure and store the result.
- *
- * @param string $key
- * @param DateTimeInterface|DateInterval|int|null $ttl
- * @param Closure $callback
- * @return mixed
*/
- public function remember($key, $ttl, Closure $callback)
+ public function remember(string $key, DateTimeInterface|DateInterval|int|null $ttl, Closure $callback): mixed
{
- $value = $this->get($key);
-
- if (! is_null($value)) {
+ if (! is_null($value = $this->get($key))) {
return $value;
}
@@ -81,21 +56,16 @@ class Cache
/**
* Delete an item from the cache.
- *
- * @param string $key
- * @return bool
*/
- public function delete($key)
+ public function delete(string $key): bool
{
return $this->store->delete($key);
}
/**
* Get the underlying cache store.
- *
- * @return CacheInterface
*/
- public function store()
+ public function store(): CacheInterface
{
return $this->store;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Collection.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Collection.php
index 036affa22..9cda10cdb 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Collection.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Collection.php
@@ -2,25 +2,23 @@
namespace LdapRecord\Query;
+use Illuminate\Support\Collection as BaseCollection;
use LdapRecord\Models\Model;
-use Tightenco\Collect\Support\Collection as BaseCollection;
class Collection extends BaseCollection
{
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- protected function valueRetriever($value)
+ protected function valueRetriever(mixed $value): callable
{
if ($this->useAsCallable($value)) {
/** @var callable $value */
return $value;
}
- return function ($item) use ($value) {
- return $item instanceof Model
+ return fn ($item) => $item instanceof Model
? $item->getFirstAttribute($value)
: data_get($item, $value);
- };
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Events/QueryExecuted.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Events/QueryExecuted.php
index 8ed8f835d..95cadd6ae 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Events/QueryExecuted.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Events/QueryExecuted.php
@@ -8,46 +8,35 @@ class QueryExecuted
{
/**
* The LDAP filter that was used for the query.
- *
- * @var Builder
*/
- protected $query;
+ protected Builder $query;
/**
* The number of milliseconds it took to execute the query.
- *
- * @var ?float
*/
- protected $time;
+ protected ?float $time;
/**
* Constructor.
- *
- * @param Builder $query
- * @param null|float $time
*/
- public function __construct(Builder $query, $time = null)
+ public function __construct(Builder $query, ?float $time = null)
{
$this->query = $query;
$this->time = $time;
}
/**
- * Returns the LDAP filter that was used for the query.
- *
- * @return Builder
+ * Get the LDAP filter that was used for the query.
*/
- public function getQuery()
+ public function getQuery(): Builder
{
return $this->query;
}
/**
- * Returns the number of milliseconds it took to execute the query.
- *
- * @return float|null
+ * Get the number of milliseconds it took to execute the query.
*/
- public function getTime()
+ public function getTime(): ?float
{
return $this->time;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ConditionNode.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ConditionNode.php
index 6203360c5..4dfed722b 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ConditionNode.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ConditionNode.php
@@ -8,38 +8,28 @@ class ConditionNode extends Node
{
/**
* The condition's attribute.
- *
- * @var string
*/
- protected $attribute;
+ protected string $attribute;
/**
* The condition's operator.
- *
- * @var string
*/
- protected $operator;
+ protected string $operator;
/**
* The condition's value.
- *
- * @var string
*/
- protected $value;
+ protected string $value;
/**
* The available condition operators.
- *
- * @var array
*/
- protected $operators = ['>=', '<=', '~=', '='];
+ protected array $operators = ['>=', '<=', '~=', '='];
/**
* Constructor.
- *
- * @param string $filter
*/
- public function __construct($filter)
+ public function __construct(string $filter)
{
$this->raw = $filter;
@@ -48,51 +38,38 @@ class ConditionNode extends Node
/**
* Get the condition's attribute.
- *
- * @return string
*/
- public function getAttribute()
+ public function getAttribute(): string
{
return $this->attribute;
}
/**
* Get the condition's operator.
- *
- * @return string
*/
- public function getOperator()
+ public function getOperator(): string
{
return $this->operator;
}
/**
* Get the condition's value.
- *
- * @return string
*/
- public function getValue()
+ public function getValue(): string
{
return $this->value;
}
/**
* Extract the condition components from the filter.
- *
- * @param string $filter
- * @return array
*/
- protected function extractComponents($filter)
+ protected function extractComponents(string $filter): array
{
$components = Str::whenContains(
$filter,
$this->operators,
- function ($operator, $filter) {
- return explode($this->operator = $operator, $filter, 2);
- },
- function ($filter) {
- throw new ParserException("Invalid query condition. No operator found in [$filter]");
- },
+ fn ($operator, $filter) => explode($this->operator = $operator, $filter, 2),
+ fn ($filter) => throw new ParserException("Invalid query condition. No operator found in [$filter]"),
);
return $components;
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/GroupNode.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/GroupNode.php
index 1a3596f3e..1af71369e 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/GroupNode.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/GroupNode.php
@@ -6,24 +6,20 @@ class GroupNode extends Node
{
/**
* The group's operator.
- *
- * @var string
*/
- protected $operator;
+ protected string $operator;
/**
* The group's sub-nodes.
*
* @var Node[]
*/
- protected $nodes = [];
+ protected array $nodes = [];
/**
* Constructor.
- *
- * @param string $filter
*/
- public function __construct($filter)
+ public function __construct(string $filter)
{
$this->raw = $filter;
@@ -34,10 +30,8 @@ class GroupNode extends Node
/**
* Get the group's operator.
- *
- * @return string
*/
- public function getOperator()
+ public function getOperator(): string
{
return $this->operator;
}
@@ -47,7 +41,7 @@ class GroupNode extends Node
*
* @return Node[]
*/
- public function getNodes()
+ public function getNodes(): array
{
return $this->nodes;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Node.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Node.php
index faf88d41f..3e9c039f1 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Node.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Node.php
@@ -6,24 +6,18 @@ abstract class Node
{
/**
* The raw value of the node.
- *
- * @var string
*/
- protected $raw;
+ protected string $raw;
/**
* Create a new filter node.
- *
- * @param string $filter
*/
- abstract public function __construct($filter);
+ abstract public function __construct(string $filter);
/**
* Get the raw value of the node.
- *
- * @return string
*/
- public function getRaw()
+ public function getRaw(): string
{
return $this->raw;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Parser.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Parser.php
index 7717ac522..1fea1810d 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Parser.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/Parser.php
@@ -10,12 +10,11 @@ class Parser
/**
* Parse an LDAP filter into nodes.
*
- * @param string $string
* @return (ConditionNode|GroupNode)[]
*
* @throws ParserException
*/
- public static function parse($string)
+ public static function parse(string $string): array
{
[$open, $close] = static::countParenthesis($string);
@@ -34,11 +33,8 @@ class Parser
/**
* Perform a match for all filters in the string.
- *
- * @param string $string
- * @return array
*/
- protected static function match($string)
+ protected static function match(string $string): array
{
preg_match_all("/\((((?>[^()]+)|(?R))*)\)/", trim($string), $matches);
@@ -49,22 +45,18 @@ class Parser
* Assemble the parsed nodes into a single filter.
*
* @param Node|Node[] $nodes
- * @return string
*/
- public static function assemble($nodes = [])
+ public static function assemble(Node|array $nodes = []): string
{
- return array_reduce(Arr::wrap($nodes), function ($carry, Node $node) {
- return $carry .= static::compileNode($node);
- });
+ return array_reduce(Arr::wrap($nodes), fn ($carry, Node $node) => (
+ $carry .= static::compileNode($node)
+ ));
}
/**
* Assemble the node into its string based format.
- *
- * @param GroupNode|ConditionNode $node
- * @return string
*/
- protected static function compileNode(Node $node)
+ protected static function compileNode(Node $node): string
{
switch (true) {
case $node instanceof GroupNode:
@@ -84,7 +76,7 @@ class Parser
*
* @throws ParserException
*/
- protected static function buildNodes(array $filters = [])
+ protected static function buildNodes(array $filters = []): array
{
return array_map(function ($filter) {
if (static::isWrapped($filter)) {
@@ -103,33 +95,24 @@ class Parser
/**
* Count the open and close parenthesis of the sting.
- *
- * @param string $string
- * @return array
*/
- protected static function countParenthesis($string)
+ protected static function countParenthesis(string $string): array
{
return [Str::substrCount($string, '('), Str::substrCount($string, ')')];
}
/**
* Wrap the value in parentheses.
- *
- * @param string $value
- * @return string
*/
- protected static function wrap($value)
+ protected static function wrap(string $value): string
{
return "($value)";
}
/**
* Recursively unwrwap the value from its parentheses.
- *
- * @param string $value
- * @return string
*/
- protected static function unwrap($value)
+ protected static function unwrap(string $value): string
{
$nodes = static::parse($value);
@@ -140,22 +123,16 @@ class Parser
/**
* Determine if the filter is wrapped.
- *
- * @param string $filter
- * @return bool
*/
- protected static function isWrapped($filter)
+ protected static function isWrapped(string $filter): bool
{
return Str::startsWith($filter, '(') && Str::endsWith($filter, ')');
}
/**
* Determine if the filter is a group.
- *
- * @param string $filter
- * @return bool
*/
- protected static function isGroup($filter)
+ protected static function isGroup(string $filter): bool
{
return Str::startsWith($filter, ['&', '|', '!']);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ParserException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ParserException.php
index 68a4ca171..3c3d68e4f 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ParserException.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Filter/ParserException.php
@@ -4,6 +4,4 @@ namespace LdapRecord\Query\Filter;
use LdapRecord\LdapRecordException;
-class ParserException extends LdapRecordException
-{
-}
+class ParserException extends LdapRecordException {}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Grammar.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Grammar.php
index 84c4b8d0c..0506c983e 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Grammar.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Grammar.php
@@ -8,10 +8,8 @@ class Grammar
{
/**
* The query operators and their method names.
- *
- * @var array
*/
- public $operators = [
+ public array $operators = [
'*' => 'has',
'!*' => 'notHas',
'=' => 'equals',
@@ -30,17 +28,13 @@ class Grammar
/**
* The query wrapper.
- *
- * @var string|null
*/
- protected $wrapper;
+ protected ?string $wrapper = null;
/**
* Get all the available operators.
- *
- * @return array
*/
- public function getOperators()
+ public function getOperators(): array
{
return array_keys($this->operators);
}
@@ -49,24 +43,16 @@ class Grammar
* Wraps a query string in brackets.
*
* Produces: (query)
- *
- * @param string $query
- * @param string $prefix
- * @param string $suffix
- * @return string
*/
- public function wrap($query, $prefix = '(', $suffix = ')')
+ public function wrap(string $query, ?string $prefix = '(', ?string $suffix = ')'): string
{
return $prefix.$query.$suffix;
}
/**
* Compiles the Builder instance into an LDAP query string.
- *
- * @param Builder $query
- * @return string
*/
- public function compile(Builder $query)
+ public function compile(Builder $query): string
{
if ($this->queryMustBeWrapped($query)) {
$this->wrapper = 'and';
@@ -76,50 +62,37 @@ class Grammar
.$this->compileWheres($query)
.$this->compileOrWheres($query);
- switch ($this->wrapper) {
- case 'and':
- return $this->compileAnd($filter);
- case 'or':
- return $this->compileOr($filter);
- default:
- return $filter;
- }
+ return match ($this->wrapper) {
+ 'and' => $this->compileAnd($filter),
+ 'or' => $this->compileOr($filter),
+ default => $filter,
+ };
}
/**
* Determine if the query must be wrapped in an encapsulating statement.
- *
- * @param Builder $query
- * @return bool
*/
- protected function queryMustBeWrapped(Builder $query)
+ protected function queryMustBeWrapped(Builder $query): bool
{
return ! $query->isNested() && $this->hasMultipleFilters($query);
}
/**
- * Assembles all of the "raw" filters on the query.
- *
- * @param Builder $builder
- * @return string
+ * Assembles all the "raw" filters on the query.
*/
- protected function compileRaws(Builder $builder)
+ protected function compileRaws(Builder $builder): string
{
return $this->concatenate($builder->filters['raw']);
}
/**
* Assembles all where clauses in the current wheres property.
- *
- * @param Builder $builder
- * @param string $type
- * @return string
*/
- protected function compileWheres(Builder $builder, $type = 'and')
+ protected function compileWheres(Builder $builder, string $type = 'and'): string
{
$filter = '';
- foreach ($builder->filters[$type] as $where) {
+ foreach ($builder->filters[$type] ?? [] as $where) {
$filter .= $this->compileWhere($where);
}
@@ -128,11 +101,8 @@ class Grammar
/**
* Assembles all or where clauses in the current orWheres property.
- *
- * @param Builder $query
- * @return string
*/
- protected function compileOrWheres(Builder $query)
+ protected function compileOrWheres(Builder $query): string
{
$filter = $this->compileWheres($query, 'or');
@@ -154,24 +124,18 @@ class Grammar
/**
* Determine if the query can be wrapped in a single or statement.
- *
- * @param Builder $query
- * @return bool
*/
- protected function queryCanBeWrappedInSingleOrStatement(Builder $query)
+ protected function queryCanBeWrappedInSingleOrStatement(Builder $query): bool
{
- return $this->has($query, 'or', '>=', 1) &&
- $this->has($query, 'and', '<=', 1) &&
- $this->has($query, 'raw', '=', 0);
+ return $this->has($query, 'or', '>=', 1)
+ && $this->has($query, 'and', '<=', 1)
+ && $this->has($query, 'raw', '=', 0);
}
/**
* Concatenates filters into a single string.
- *
- * @param array $bindings
- * @return string
*/
- public function concatenate(array $bindings = [])
+ public function concatenate(array $bindings = []): string
{
// Filter out empty query segments.
return implode(
@@ -181,69 +145,48 @@ class Grammar
/**
* Determine if the binding value is not empty.
- *
- * @param string $value
- * @return bool
*/
- protected function bindingValueIsNotEmpty($value)
+ protected function bindingValueIsNotEmpty(string $value): bool
{
return ! empty($value);
}
/**
* Determine if the query is using multiple filters.
- *
- * @param Builder $query
- * @return bool
*/
- protected function hasMultipleFilters(Builder $query)
+ protected function hasMultipleFilters(Builder $query): bool
{
return $this->has($query, ['and', 'or', 'raw'], '>', 1);
}
/**
* Determine if the query contains the given filter statement type.
- *
- * @param Builder $query
- * @param string|array $type
- * @param string $operator
- * @param int $count
- * @return bool
*/
- protected function has(Builder $query, $type, $operator = '>=', $count = 1)
+ protected function has(Builder $query, array|string $type, string $operator = '>=', int $count = 1): bool
{
$types = (array) $type;
$filters = 0;
foreach ($types as $type) {
- $filters += count($query->filters[$type]);
+ $filters += count($query->filters[$type] ?? []);
}
- switch ($operator) {
- case '>':
- return $filters > $count;
- case '>=':
- return $filters >= $count;
- case '<':
- return $filters < $count;
- case '<=':
- return $filters <= $count;
- default:
- return $filters == $count;
- }
+ return match ($operator) {
+ '>' => $filters > $count,
+ '>=' => $filters >= $count,
+ '<' => $filters < $count,
+ '<=' => $filters <= $count,
+ default => $filters == $count,
+ };
}
/**
* Returns a query string for equals.
*
* Produces: (field=value)
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileEquals($field, $value)
+ public function compileEquals(string $field, string $value): string
{
return $this->wrap($field.'='.$value);
}
@@ -252,12 +195,8 @@ class Grammar
* Returns a query string for does not equal.
*
* Produces: (!(field=value))
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileDoesNotEqual($field, $value)
+ public function compileDoesNotEqual(string $field, string $value): string
{
return $this->compileNot(
$this->compileEquals($field, $value)
@@ -268,12 +207,8 @@ class Grammar
* Alias for does not equal operator (!=) operator.
*
* Produces: (!(field=value))
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileDoesNotEqualAlias($field, $value)
+ public function compileDoesNotEqualAlias(string $field, string $value): string
{
return $this->compileDoesNotEqual($field, $value);
}
@@ -282,12 +217,8 @@ class Grammar
* Returns a query string for greater than or equals.
*
* Produces: (field>=value)
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileGreaterThanOrEquals($field, $value)
+ public function compileGreaterThanOrEquals(string $field, string $value): string
{
return $this->wrap("$field>=$value");
}
@@ -296,12 +227,8 @@ class Grammar
* Returns a query string for less than or equals.
*
* Produces: (field<=value)
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileLessThanOrEquals($field, $value)
+ public function compileLessThanOrEquals(string $field, string $value): string
{
return $this->wrap("$field<=$value");
}
@@ -310,12 +237,8 @@ class Grammar
* Returns a query string for approximately equals.
*
* Produces: (field~=value)
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileApproximatelyEquals($field, $value)
+ public function compileApproximatelyEquals(string $field, string $value): string
{
return $this->wrap("$field~=$value");
}
@@ -324,12 +247,8 @@ class Grammar
* Returns a query string for starts with.
*
* Produces: (field=value*)
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileStartsWith($field, $value)
+ public function compileStartsWith(string $field, string $value): string
{
return $this->wrap("$field=$value*");
}
@@ -338,12 +257,8 @@ class Grammar
* Returns a query string for does not start with.
*
* Produces: (!(field=*value))
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileNotStartsWith($field, $value)
+ public function compileNotStartsWith(string $field, string $value): string
{
return $this->compileNot(
$this->compileStartsWith($field, $value)
@@ -354,12 +269,8 @@ class Grammar
* Returns a query string for ends with.
*
* Produces: (field=*value)
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileEndsWith($field, $value)
+ public function compileEndsWith(string $field, string $value): string
{
return $this->wrap("$field=*$value");
}
@@ -368,12 +279,8 @@ class Grammar
* Returns a query string for does not end with.
*
* Produces: (!(field=value*))
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileNotEndsWith($field, $value)
+ public function compileNotEndsWith(string $field, string $value): string
{
return $this->compileNot($this->compileEndsWith($field, $value));
}
@@ -382,12 +289,8 @@ class Grammar
* Returns a query string for contains.
*
* Produces: (field=*value*)
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileContains($field, $value)
+ public function compileContains(string $field, string $value): string
{
return $this->wrap("$field=*$value*");
}
@@ -396,12 +299,8 @@ class Grammar
* Returns a query string for does not contain.
*
* Produces: (!(field=*value*))
- *
- * @param string $field
- * @param string $value
- * @return string
*/
- public function compileNotContains($field, $value)
+ public function compileNotContains(string $field, string $value): string
{
return $this->compileNot(
$this->compileContains($field, $value)
@@ -412,11 +311,8 @@ class Grammar
* Returns a query string for a where has.
*
* Produces: (field=*)
- *
- * @param string $field
- * @return string
*/
- public function compileHas($field)
+ public function compileHas(string $field): string
{
return $this->wrap("$field=*");
}
@@ -425,11 +321,8 @@ class Grammar
* Returns a query string for a where does not have.
*
* Produces: (!(field=*))
- *
- * @param string $field
- * @return string
*/
- public function compileNotHas($field)
+ public function compileNotHas(string $field): string
{
return $this->compileNot(
$this->compileHas($field)
@@ -440,11 +333,8 @@ class Grammar
* Wraps the inserted query inside an AND operator.
*
* Produces: (&query)
- *
- * @param string $query
- * @return string
*/
- public function compileAnd($query)
+ public function compileAnd(string $query): string
{
return $query ? $this->wrap($query, '(&') : '';
}
@@ -453,22 +343,16 @@ class Grammar
* Wraps the inserted query inside an OR operator.
*
* Produces: (|query)
- *
- * @param string $query
- * @return string
*/
- public function compileOr($query)
+ public function compileOr(string $query): string
{
return $query ? $this->wrap($query, '(|') : '';
}
/**
* Wraps the inserted query inside an NOT operator.
- *
- * @param string $query
- * @return string
*/
- public function compileNot($query)
+ public function compileNot(string $query): string
{
return $query ? $this->wrap($query, '(!') : '';
}
@@ -476,12 +360,9 @@ class Grammar
/**
* Assembles a single where query.
*
- * @param array $where
- * @return string
- *
* @throws UnexpectedValueException
*/
- protected function compileWhere(array $where)
+ protected function compileWhere(array $where): string
{
$method = $this->makeCompileMethod($where['operator']);
@@ -491,12 +372,9 @@ class Grammar
/**
* Make the compile method name for the operator.
*
- * @param string $operator
- * @return string
- *
* @throws UnexpectedValueException
*/
- protected function makeCompileMethod($operator)
+ protected function makeCompileMethod(string $operator): string
{
if (! $this->operatorExists($operator)) {
throw new UnexpectedValueException("Invalid LDAP filter operator ['$operator']");
@@ -507,11 +385,8 @@ class Grammar
/**
* Determine if the operator exists.
- *
- * @param string $operator
- * @return bool
*/
- protected function operatorExists($operator)
+ protected function operatorExists(string $operator): bool
{
return array_key_exists($operator, $this->operators);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/InteractsWithTime.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/InteractsWithTime.php
index e8024c033..111c2c201 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/InteractsWithTime.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/InteractsWithTime.php
@@ -15,11 +15,8 @@ trait InteractsWithTime
{
/**
* Get the number of seconds until the given DateTime.
- *
- * @param DateTimeInterface|DateInterval|int $delay
- * @return int
*/
- protected function secondsUntil($delay)
+ protected function secondsUntil(DateTimeInterface|DateInterval|int|null $delay = null): int
{
$delay = $this->parseDateInterval($delay);
@@ -30,11 +27,8 @@ trait InteractsWithTime
/**
* Get the "available at" UNIX timestamp.
- *
- * @param DateTimeInterface|DateInterval|int $delay
- * @return int
*/
- protected function availableAt($delay = 0)
+ protected function availableAt(DateTimeInterface|DateInterval|int $delay = 0): int
{
$delay = $this->parseDateInterval($delay);
@@ -45,11 +39,8 @@ trait InteractsWithTime
/**
* If the given value is an interval, convert it to a DateTime instance.
- *
- * @param DateTimeInterface|DateInterval|int $delay
- * @return DateTimeInterface|int
*/
- protected function parseDateInterval($delay)
+ protected function parseDateInterval(DateTimeInterface|DateInterval|int|null $delay = null): DateTimeInterface|int|null
{
if ($delay instanceof DateInterval) {
$delay = Carbon::now()->add($delay);
@@ -60,10 +51,8 @@ trait InteractsWithTime
/**
* Get the current system time as a UNIX timestamp.
- *
- * @return int
*/
- protected function currentTime()
+ protected function currentTime(): int
{
return Carbon::now()->getTimestamp();
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/ActiveDirectoryBuilder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/ActiveDirectoryBuilder.php
index 3b0e96f79..7fb8ab682 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/ActiveDirectoryBuilder.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/ActiveDirectoryBuilder.php
@@ -5,23 +5,20 @@ namespace LdapRecord\Query\Model;
use Closure;
use LdapRecord\LdapInterface;
use LdapRecord\Models\Attributes\AccountControl;
+use LdapRecord\Models\Model;
use LdapRecord\Models\ModelNotFoundException;
class ActiveDirectoryBuilder extends Builder
{
/**
* Finds a record by its Object SID.
- *
- * @param string $sid
- * @param array|string $columns
- * @return \LdapRecord\Models\ActiveDirectory\Entry|static|null
*/
- public function findBySid($sid, $columns = [])
+ public function findBySid(string $sid, array|string $columns = ['*']): ?Model
{
try {
return $this->findBySidOrFail($sid, $columns);
- } catch (ModelNotFoundException $e) {
- return;
+ } catch (ModelNotFoundException) {
+ return null;
}
}
@@ -30,190 +27,157 @@ class ActiveDirectoryBuilder extends Builder
*
* Fails upon no records returned.
*
- * @param string $sid
- * @param array|string $columns
- * @return \LdapRecord\Models\ActiveDirectory\Entry|static
- *
* @throws ModelNotFoundException
*/
- public function findBySidOrFail($sid, $columns = [])
+ public function findBySidOrFail(string $sid, array $columns = ['*']): Model
{
return $this->findByOrFail('objectsid', $sid, $columns);
}
/**
* Adds a enabled filter to the current query.
- *
- * @return $this
*/
- public function whereEnabled()
+ public function whereEnabled(): static
{
- return $this->notFilter(function ($query) {
- return $query->whereDisabled();
- });
+ return $this->notFilter(
+ fn (self $query) => $query->whereDisabled()
+ );
}
/**
* Adds a disabled filter to the current query.
- *
- * @return $this
*/
- public function whereDisabled()
+ public function whereDisabled(): static
{
return $this->rawFilter(
- (new AccountControl())->accountIsDisabled()->filter()
+ (new AccountControl)->setAccountIsDisabled()->filter()
);
}
/**
* Adds a 'where member' filter to the current query.
- *
- * @param string $dn
- * @param bool $nested
- * @return $this
*/
- public function whereMember($dn, $nested = false)
+ public function whereMember(string $dn, bool $nested = false): static
{
- return $this->nestedMatchQuery(function ($attribute) use ($dn) {
- return $this->whereEquals($attribute, $dn);
- }, 'member', $nested);
+ return $this->nestedMatchQuery(
+ fn (string $attribute) => $this->whereEquals($attribute, $this->substituteBaseDn($dn)),
+ 'member',
+ $nested
+ );
}
/**
* Adds an 'or where member' filter to the current query.
- *
- * @param string $dn
- * @param bool $nested
- * @return $this
*/
- public function orWhereMember($dn, $nested = false)
+ public function orWhereMember(string $dn, bool $nested = false): static
{
- return $this->nestedMatchQuery(function ($attribute) use ($dn) {
- return $this->orWhereEquals($attribute, $dn);
- }, 'member', $nested);
+ return $this->nestedMatchQuery(
+ fn (string $attribute) => $this->orWhereEquals($attribute, $this->substituteBaseDn($dn)),
+ 'member',
+ $nested
+ );
}
/**
* Adds a 'where member of' filter to the current query.
- *
- * @param string $dn
- * @param bool $nested
- * @return $this
*/
- public function whereMemberOf($dn, $nested = false)
+ public function whereMemberOf(string $dn, bool $nested = false): static
{
- return $this->nestedMatchQuery(function ($attribute) use ($dn) {
- return $this->whereEquals($attribute, $dn);
- }, 'memberof', $nested);
+ return $this->nestedMatchQuery(
+ fn (string $attribute) => $this->whereEquals($attribute, $this->substituteBaseDn($dn)),
+ 'memberof',
+ $nested
+ );
}
/**
* Adds a 'where not member of' filter to the current query.
- *
- * @param string $dn
- * @param bool $nested
- * @return $this
*/
- public function whereNotMemberof($dn, $nested = false)
+ public function whereNotMemberof(string $dn, bool $nested = false): static
{
- return $this->nestedMatchQuery(function ($attribute) use ($dn) {
- return $this->whereNotEquals($attribute, $dn);
- }, 'memberof', $nested);
+ return $this->nestedMatchQuery(
+ fn (string $attribute) => $this->whereNotEquals($attribute, $this->substituteBaseDn($dn)),
+ 'memberof',
+ $nested
+ );
}
/**
* Adds an 'or where member of' filter to the current query.
- *
- * @param string $dn
- * @param bool $nested
- * @return $this
*/
- public function orWhereMemberOf($dn, $nested = false)
+ public function orWhereMemberOf(string $dn, bool $nested = false): static
{
- return $this->nestedMatchQuery(function ($attribute) use ($dn) {
- return $this->orWhereEquals($attribute, $dn);
- }, 'memberof', $nested);
+ return $this->nestedMatchQuery(
+ fn (string $attribute) => $this->orWhereEquals($attribute, $this->substituteBaseDn($dn)),
+ 'memberof',
+ $nested
+ );
}
/**
* Adds a 'or where not member of' filter to the current query.
- *
- * @param string $dn
- * @param bool $nested
- * @return $this
*/
- public function orWhereNotMemberof($dn, $nested = false)
+ public function orWhereNotMemberof(string $dn, bool $nested = false): static
{
- return $this->nestedMatchQuery(function ($attribute) use ($dn) {
- return $this->orWhereNotEquals($attribute, $dn);
- }, 'memberof', $nested);
+ return $this->nestedMatchQuery(
+ fn (string $attribute) => $this->orWhereNotEquals($attribute, $this->substituteBaseDn($dn)),
+ 'memberof',
+ $nested
+ );
}
/**
* Adds a 'where manager' filter to the current query.
- *
- * @param string $dn
- * @param bool $nested
- * @return $this
*/
- public function whereManager($dn, $nested = false)
+ public function whereManager(string $dn, bool $nested = false): static
{
- return $this->nestedMatchQuery(function ($attribute) use ($dn) {
- return $this->whereEquals($attribute, $dn);
- }, 'manager', $nested);
+ return $this->nestedMatchQuery(
+ fn (string $attribute) => $this->whereEquals($attribute, $this->substituteBaseDn($dn)),
+ 'manager',
+ $nested
+ );
}
/**
* Adds a 'where not manager' filter to the current query.
- *
- * @param string $dn
- * @param bool $nested
- * @return $this
*/
- public function whereNotManager($dn, $nested = false)
+ public function whereNotManager(string $dn, bool $nested = false): static
{
- return $this->nestedMatchQuery(function ($attribute) use ($dn) {
- return $this->whereNotEquals($attribute, $dn);
- }, 'manager', $nested);
+ return $this->nestedMatchQuery(
+ fn (string $attribute) => $this->whereNotEquals($attribute, $this->substituteBaseDn($dn)),
+ 'manager',
+ $nested
+ );
}
/**
* Adds an 'or where manager' filter to the current query.
- *
- * @param string $dn
- * @param bool $nested
- * @return $this
*/
- public function orWhereManager($dn, $nested = false)
+ public function orWhereManager(string $dn, bool $nested = false): static
{
- return $this->nestedMatchQuery(function ($attribute) use ($dn) {
- return $this->orWhereEquals($attribute, $dn);
- }, 'manager', $nested);
+ return $this->nestedMatchQuery(
+ fn (string $attribute) => $this->orWhereEquals($attribute, $this->substituteBaseDn($dn)),
+ 'manager',
+ $nested
+ );
}
/**
* Adds an 'or where not manager' filter to the current query.
- *
- * @param string $dn
- * @param bool $nested
- * @return $this
*/
- public function orWhereNotManager($dn, $nested = false)
+ public function orWhereNotManager(string $dn, bool $nested = false): static
{
- return $this->nestedMatchQuery(function ($attribute) use ($dn) {
- return $this->orWhereNotEquals($attribute, $dn);
- }, 'manager', $nested);
+ return $this->nestedMatchQuery(
+ fn (string $attribute) => $this->orWhereNotEquals($attribute, $this->substituteBaseDn($dn)),
+ 'manager',
+ $nested
+ );
}
/**
* Execute the callback with a nested match attribute.
- *
- * @param Closure $callback
- * @param string $attribute
- * @param bool $nested
- * @return $this
*/
- protected function nestedMatchQuery(Closure $callback, $attribute, $nested = false)
+ protected function nestedMatchQuery(Closure $callback, string $attribute, bool $nested = false): static
{
return $callback(
$nested ? $this->makeNestedMatchAttribute($attribute) : $attribute
@@ -222,11 +186,8 @@ class ActiveDirectoryBuilder extends Builder
/**
* Make a "nested match" filter attribute for querying descendants.
- *
- * @param string $attribute
- * @return string
*/
- protected function makeNestedMatchAttribute($attribute)
+ protected function makeNestedMatchAttribute(string $attribute): string
{
return sprintf('%s:%s:', $attribute, LdapInterface::OID_MATCHING_RULE_IN_CHAIN);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/Builder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/Builder.php
index a6886ea96..741646e7e 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/Builder.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/Builder.php
@@ -4,51 +4,41 @@ namespace LdapRecord\Query\Model;
use Closure;
use DateTime;
+use LdapRecord\Models\Attributes\Guid;
+use LdapRecord\Models\Collection;
use LdapRecord\Models\Model;
use LdapRecord\Models\ModelNotFoundException;
use LdapRecord\Models\Scope;
use LdapRecord\Models\Types\ActiveDirectory;
use LdapRecord\Query\Builder as BaseBuilder;
-use LdapRecord\Utilities;
+use UnexpectedValueException;
class Builder extends BaseBuilder
{
/**
* The model being queried.
- *
- * @var Model
*/
- protected $model;
+ protected Model $model;
/**
* The global scopes to be applied.
- *
- * @var array
*/
- protected $scopes = [];
+ protected array $scopes = [];
/**
* The removed global scopes.
- *
- * @var array
*/
- protected $removedScopes = [];
+ protected array $removedScopes = [];
/**
* The applied global scopes.
- *
- * @var array
*/
- protected $appliedScopes = [];
+ protected array $appliedScopes = [];
/**
* Dynamically handle calls into the query instance.
- *
- * @param string $method
- * @param array $parameters
- * @return mixed
*/
- public function __call($method, $parameters)
+ public function __call(string $method, array $parameters): static
{
if (method_exists($this->model, $scope = 'scope'.ucfirst($method))) {
return $this->callScope([$this->model, $scope], $parameters);
@@ -59,12 +49,8 @@ class Builder extends BaseBuilder
/**
* Apply the given scope on the current builder instance.
- *
- * @param callable $scope
- * @param array $parameters
- * @return mixed
*/
- protected function callScope(callable $scope, $parameters = [])
+ protected function callScope(callable $scope, array $parameters = []): static
{
array_unshift($parameters, $this);
@@ -73,10 +59,8 @@ class Builder extends BaseBuilder
/**
* Get the attributes to select on the search.
- *
- * @return array
*/
- public function getSelects()
+ public function getSelects(): array
{
// Here we will ensure the models GUID attribute is always
// selected. In some LDAP directories, the attribute is
@@ -88,11 +72,8 @@ class Builder extends BaseBuilder
/**
* Set the model instance for the model being queried.
- *
- * @param Model $model
- * @return $this
*/
- public function setModel(Model $model)
+ public function setModel(Model $model): static
{
$this->model = $model;
@@ -100,48 +81,97 @@ class Builder extends BaseBuilder
}
/**
- * Returns the model being queried for.
- *
- * @return Model
+ * Get the model being queried for.
*/
- public function getModel()
+ public function getModel(): Model
{
return $this->model;
}
/**
* Get a new model query builder instance.
- *
- * @param string|null $baseDn
- * @return static
*/
- public function newInstance($baseDn = null)
+ public function newInstance(?string $baseDn = null): BaseBuilder
{
return parent::newInstance($baseDn)->model($this->model);
}
/**
- * Finds a model by its distinguished name.
- *
- * @param array|string $dn
- * @param array|string|string[] $columns
- * @return Model|\LdapRecord\Query\Collection|static|null
+ * {@inheritDoc}
*/
- public function find($dn, $columns = ['*'])
+ public function first(array|string $columns = ['*']): ?Model
{
- return $this->afterScopes(function () use ($dn, $columns) {
- return parent::find($dn, $columns);
- });
+ return parent::first($columns);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function firstOrFail(array|string $columns = ['*']): Model
+ {
+ return parent::firstOrFail($columns);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function sole(array|string $columns = ['*']): Model
+ {
+ return parent::sole($columns);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function find(array|string $dn, array|string $columns = ['*']): Model|Collection|null
+ {
+ return $this->afterScopes(fn () => parent::find($dn, $columns));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function findOrFail(string $dn, array|string $columns = ['*']): Model
+ {
+ return parent::findOrFail($dn, $columns);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function findByOrFail(string $attribute, string $value, array|string $columns = ['*']): Model
+ {
+ return parent::findByOrFail($attribute, $value, $columns);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function findBy(string $attribute, string $value, array|string $columns = ['*']): ?Model
+ {
+ return parent::findBy($attribute, $value, $columns);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function findMany(array|string $dns, array|string $columns = ['*']): Collection
+ {
+ return parent::findMany($dns, $columns);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function findManyBy(string $attribute, array $values = [], array|string $columns = ['*']): Collection
+ {
+ return parent::findManyBy($attribute, $values, $columns);
}
/**
* Finds a record using ambiguous name resolution.
- *
- * @param string|array $value
- * @param array|string $columns
- * @return Model|\LdapRecord\Query\Collection|static|null
*/
- public function findByAnr($value, $columns = ['*'])
+ public function findByAnr(array|string $value, array|string $columns = ['*']): Model|Collection|null
{
if (is_array($value)) {
return $this->findManyByAnr($value, $columns);
@@ -159,10 +189,8 @@ class Builder extends BaseBuilder
/**
* Determine if the current model is compatible with ANR filters.
- *
- * @return bool
*/
- protected function modelIsCompatibleWithAnr()
+ protected function modelIsCompatibleWithAnr(): bool
{
return $this->model instanceof ActiveDirectory;
}
@@ -172,13 +200,9 @@ class Builder extends BaseBuilder
*
* If a record is not found, an exception is thrown.
*
- * @param string $value
- * @param array|string $columns
- * @return Model
- *
* @throws ModelNotFoundException
*/
- public function findByAnrOrFail($value, $columns = ['*'])
+ public function findByAnrOrFail(string $value, array|string $columns = ['*']): Model
{
if (! $entry = $this->findByAnr($value, $columns)) {
$this->throwNotFoundException($this->getUnescapedQuery(), $this->dn);
@@ -190,24 +214,17 @@ class Builder extends BaseBuilder
/**
* Throws a not found exception.
*
- * @param string $query
- * @param string $dn
- *
* @throws ModelNotFoundException
*/
- protected function throwNotFoundException($query, $dn)
+ protected function throwNotFoundException(string $query, ?string $dn = null): void
{
throw ModelNotFoundException::forQuery($query, $dn);
}
/**
* Finds multiple records using ambiguous name resolution.
- *
- * @param array $values
- * @param array $columns
- * @return \LdapRecord\Query\Collection
*/
- public function findManyByAnr(array $values = [], $columns = ['*'])
+ public function findManyByAnr(array $values = [], array|string $columns = ['*']): Collection
{
$this->select($columns);
@@ -224,13 +241,10 @@ class Builder extends BaseBuilder
/**
* Creates an ANR equivalent query for LDAP distributions that do not support ANR.
- *
- * @param string $value
- * @return $this
*/
- protected function prepareAnrEquivalentQuery($value)
+ protected function prepareAnrEquivalentQuery(string $value): static
{
- return $this->orFilter(function (self $query) use ($value) {
+ return $this->orFilter(function (BaseBuilder $query) use ($value) {
foreach ($this->model->getAnrAttributes() as $attribute) {
$query->whereEquals($attribute, $value);
}
@@ -239,35 +253,25 @@ class Builder extends BaseBuilder
/**
* Finds a record by its string GUID.
- *
- * @param string $guid
- * @param array|string $columns
- * @return Model|static|null
*/
- public function findByGuid($guid, $columns = ['*'])
+ public function findByGuid(string $guid, array|string $columns = ['*']): ?Model
{
try {
return $this->findByGuidOrFail($guid, $columns);
} catch (ModelNotFoundException $e) {
- return;
+ return null;
}
}
/**
- * Finds a record by its string GUID.
- *
- * Fails upon no records returned.
- *
- * @param string $guid
- * @param array|string $columns
- * @return Model|static
+ * Finds a record by its string GUID or throw an exception.
*
* @throws ModelNotFoundException
*/
- public function findByGuidOrFail($guid, $columns = ['*'])
+ public function findByGuidOrFail(string $guid, array|string $columns = ['*']): Model
{
if ($this->model instanceof ActiveDirectory) {
- $guid = Utilities::stringGuidToHex($guid);
+ $guid = (new Guid($guid))->getEncodedHex();
}
return $this->whereRaw([
@@ -276,22 +280,17 @@ class Builder extends BaseBuilder
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getQuery()
+ public function getQuery(): string
{
- return $this->afterScopes(function () {
- return parent::getQuery();
- });
+ return $this->afterScopes(fn () => parent::getQuery());
}
/**
* Apply the query scopes and execute the callback.
- *
- * @param Closure $callback
- * @return mixed
*/
- protected function afterScopes(Closure $callback)
+ protected function afterScopes(Closure $callback): mixed
{
$this->applyScopes();
@@ -300,10 +299,8 @@ class Builder extends BaseBuilder
/**
* Apply the global query scopes.
- *
- * @return $this
*/
- public function applyScopes()
+ public function applyScopes(): static
{
if (! $this->scopes) {
return $this;
@@ -326,12 +323,8 @@ class Builder extends BaseBuilder
/**
* Register a new global scope.
- *
- * @param string $identifier
- * @param Scope|\Closure $scope
- * @return $this
*/
- public function withGlobalScope($identifier, $scope)
+ public function withGlobalScope(string $identifier, Scope|Closure $scope): static
{
$this->scopes[$identifier] = $scope;
@@ -340,11 +333,8 @@ class Builder extends BaseBuilder
/**
* Remove a registered global scope.
- *
- * @param Scope|string $scope
- * @return $this
*/
- public function withoutGlobalScope($scope)
+ public function withoutGlobalScope(Scope|string $scope): static
{
if (! is_string($scope)) {
$scope = get_class($scope);
@@ -359,11 +349,8 @@ class Builder extends BaseBuilder
/**
* Remove all or passed registered global scopes.
- *
- * @param array|null $scopes
- * @return $this
*/
- public function withoutGlobalScopes(array $scopes = null)
+ public function withoutGlobalScopes(?array $scopes = null): static
{
if (! is_array($scopes)) {
$scopes = array_keys($this->scopes);
@@ -378,51 +365,44 @@ class Builder extends BaseBuilder
/**
* Get an array of global scopes that were removed from the query.
- *
- * @return array
*/
- public function removedScopes()
+ public function removedScopes(): array
{
return $this->removedScopes;
}
/**
* Get an array of the global scopes that were applied to the query.
- *
- * @return array
*/
- public function appliedScopes()
+ public function appliedScopes(): array
{
return $this->appliedScopes;
}
/**
* Processes and converts the given LDAP results into models.
- *
- * @param array $results
- * @return \LdapRecord\Query\Collection
*/
- protected function process(array $results)
+ protected function process(array $results): Collection
{
return $this->model->hydrate(parent::process($results));
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- protected function prepareWhereValue($field, $value, $raw = false)
+ protected function prepareWhereValue(string $field, mixed $value = null, $raw = false): string
{
if ($value instanceof DateTime) {
$field = $this->model->normalizeAttributeKey($field);
if (! $this->model->isDateAttribute($field)) {
- throw new \UnexpectedValueException(
+ throw new UnexpectedValueException(
"Cannot convert field [$field] to an LDAP timestamp. You must add this field as a model date."
- .' Refer to https://ldaprecord.com/docs/core/v2/model-mutators/#date-mutators'
+ .' Refer to https://ldaprecord.com/docs/core/v3/model-mutators/#date-mutators'
);
}
- $value = $this->model->fromDateTime($this->model->getDates()[$field], $value);
+ $value = $this->model->fromDateTime($value, $this->model->getDates()[$field]);
}
return parent::prepareWhereValue($field, $value, $raw);
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/FreeIpaBuilder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/FreeIpaBuilder.php
index 5e3d43fef..cac5ac30b 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/FreeIpaBuilder.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/FreeIpaBuilder.php
@@ -6,20 +6,16 @@ class FreeIpaBuilder extends Builder
{
/**
* Adds a enabled filter to the current query.
- *
- * @return $this
*/
- public function whereEnabled()
+ public function whereEnabled(): static
{
return $this->rawFilter('(!(pwdAccountLockedTime=*))');
}
/**
* Adds a disabled filter to the current query.
- *
- * @return $this
*/
- public function whereDisabled()
+ public function whereDisabled(): static
{
return $this->rawFilter('(pwdAccountLockedTime=*)');
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/OpenLdapBuilder.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/OpenLdapBuilder.php
index dd41344b7..e0a8d5ebc 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/OpenLdapBuilder.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Model/OpenLdapBuilder.php
@@ -6,20 +6,16 @@ class OpenLdapBuilder extends Builder
{
/**
* Adds a enabled filter to the current query.
- *
- * @return $this
*/
- public function whereEnabled()
+ public function whereEnabled(): static
{
return $this->rawFilter('(!(pwdAccountLockedTime=*))');
}
/**
* Adds a disabled filter to the current query.
- *
- * @return $this
*/
- public function whereDisabled()
+ public function whereDisabled(): static
{
return $this->rawFilter('(pwdAccountLockedTime=*)');
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/MultipleObjectsFoundException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/MultipleObjectsFoundException.php
index 0ece752cf..79ed1e3ef 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/MultipleObjectsFoundException.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/MultipleObjectsFoundException.php
@@ -4,6 +4,4 @@ namespace LdapRecord\Query;
use LdapRecord\LdapRecordException;
-class MultipleObjectsFoundException extends LdapRecordException
-{
-}
+class MultipleObjectsFoundException extends LdapRecordException {}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectNotFoundException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectNotFoundException.php
index 99c2e85e3..8fb22a218 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectNotFoundException.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectNotFoundException.php
@@ -8,38 +8,26 @@ class ObjectNotFoundException extends LdapRecordException
{
/**
* The query filter that was used.
- *
- * @var string
*/
- protected $query;
+ protected string $query;
/**
* The base DN of the query that was used.
- *
- * @var string
*/
- protected $baseDn;
+ protected ?string $baseDn;
/**
* Create a new exception for the executed filter.
- *
- * @param string $query
- * @param ?string $baseDn
- * @return static
*/
- public static function forQuery($query, $baseDn = null)
+ public static function forQuery(string $query, ?string $baseDn = null): static
{
- return (new static())->setQuery($query, $baseDn);
+ return (new static)->setQuery($query, $baseDn);
}
/**
* Set the query that was used.
- *
- * @param string $query
- * @param string|null $baseDn
- * @return $this
*/
- public function setQuery($query, $baseDn = null)
+ public function setQuery(string $query, ?string $baseDn = null): static
{
$this->query = $query;
$this->baseDn = $baseDn;
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectsNotFoundException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectsNotFoundException.php
index a9846005c..85edb7f00 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectsNotFoundException.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/ObjectsNotFoundException.php
@@ -4,6 +4,4 @@ namespace LdapRecord\Query;
use LdapRecord\LdapRecordException;
-class ObjectsNotFoundException extends LdapRecordException
-{
-}
+class ObjectsNotFoundException extends LdapRecordException {}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/AbstractPaginator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/AbstractPaginator.php
index 11e2dc547..c55677314 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/AbstractPaginator.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/AbstractPaginator.php
@@ -9,38 +9,28 @@ abstract class AbstractPaginator
{
/**
* The query builder instance.
- *
- * @var Builder
*/
- protected $query;
+ protected Builder $query;
/**
* The filter to execute.
- *
- * @var string
*/
- protected $filter;
+ protected string $filter;
/**
* The amount of objects to fetch per page.
- *
- * @var int
*/
- protected $perPage;
+ protected int $perPage;
/**
* Whether the operation is critical.
- *
- * @var bool
*/
- protected $isCritical;
+ protected bool $isCritical;
/**
* Constructor.
- *
- * @param Builder $query
*/
- public function __construct(Builder $query, $filter, $perPage, $isCritical)
+ public function __construct(Builder $query, string $filter, int $perPage, bool $isCritical = false)
{
$this->query = $query;
$this->filter = $filter;
@@ -50,11 +40,8 @@ abstract class AbstractPaginator
/**
* Execute the pagination request.
- *
- * @param LdapInterface $ldap
- * @return array
*/
- public function execute(LdapInterface $ldap)
+ public function execute(LdapInterface $ldap): mixed
{
$pages = [];
@@ -78,53 +65,37 @@ abstract class AbstractPaginator
}
/**
- * Whether the paginater should continue iterating.
- *
- * @return bool
+ * Whether the paginator should continue iterating.
*/
- protected function shouldContinue()
+ protected function shouldContinue(): bool
{
- $cookie = (string) $this->fetchCookie();
+ $cookie = $this->fetchCookie();
return $cookie !== '';
}
/**
* Fetch the pagination cookie.
- *
- * @return string
*/
- abstract protected function fetchCookie();
+ abstract protected function fetchCookie(): ?string;
/**
* Prepare the server controls before executing the pagination request.
- *
- * @return void
*/
- abstract protected function prepareServerControls();
+ abstract protected function prepareServerControls(): void;
/**
* Apply the server controls.
- *
- * @param LdapInterface $ldap
- * @return void
*/
- abstract protected function applyServerControls(LdapInterface $ldap);
+ abstract protected function applyServerControls(LdapInterface $ldap): void;
/**
* Reset the server controls.
- *
- * @param LdapInterface $ldap
- * @return void
*/
- abstract protected function resetServerControls(LdapInterface $ldap);
+ abstract protected function resetServerControls(LdapInterface $ldap): void;
/**
* Update the server controls.
- *
- * @param LdapInterface $ldap
- * @param resource $resource
- * @return void
*/
- abstract protected function updateServerControls(LdapInterface $ldap, $resource);
+ abstract protected function updateServerControls(LdapInterface $ldap, mixed $resource): void;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/DeprecatedPaginator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/DeprecatedPaginator.php
deleted file mode 100644
index b4a7f8db9..000000000
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/DeprecatedPaginator.php
+++ /dev/null
@@ -1,58 +0,0 @@
-cookie;
- }
-
- /**
- * @inheritdoc
- */
- protected function prepareServerControls()
- {
- $this->cookie = '';
- }
-
- /**
- * @inheritdoc
- */
- protected function applyServerControls(LdapInterface $ldap)
- {
- $ldap->controlPagedResult($this->perPage, $this->isCritical, $this->cookie);
- }
-
- /**
- * @inheritdoc
- */
- protected function updateServerControls(LdapInterface $ldap, $resource)
- {
- $ldap->controlPagedResultResponse($resource, $this->cookie);
- }
-
- /**
- * @inheritdoc
- */
- protected function resetServerControls(LdapInterface $ldap)
- {
- $ldap->controlPagedResult();
- }
-}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/LazyPaginator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/LazyPaginator.php
index 8b12d526c..d770259ed 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/LazyPaginator.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/LazyPaginator.php
@@ -2,17 +2,15 @@
namespace LdapRecord\Query\Pagination;
+use Generator;
use LdapRecord\LdapInterface;
class LazyPaginator extends Paginator
{
/**
* Execute the pagination request.
- *
- * @param LdapInterface $ldap
- * @return \Generator
*/
- public function execute(LdapInterface $ldap)
+ public function execute(LdapInterface $ldap): Generator
{
$this->prepareServerControls();
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/Paginator.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/Paginator.php
index c0a31afd9..50671a77a 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/Paginator.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Pagination/Paginator.php
@@ -7,17 +7,17 @@ use LdapRecord\LdapInterface;
class Paginator extends AbstractPaginator
{
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- protected function fetchCookie()
+ protected function fetchCookie(): ?string
{
return $this->query->controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? null;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- protected function prepareServerControls()
+ protected function prepareServerControls(): void
{
$this->query->addControl(LDAP_CONTROL_PAGEDRESULTS, $this->isCritical, [
'size' => $this->perPage, 'cookie' => '',
@@ -25,31 +25,27 @@ class Paginator extends AbstractPaginator
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- protected function applyServerControls(LdapInterface $ldap)
+ protected function applyServerControls(LdapInterface $ldap): void
{
$ldap->setOption(LDAP_OPT_SERVER_CONTROLS, $this->query->controls);
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- protected function updateServerControls(LdapInterface $ldap, $resource)
+ protected function updateServerControls(LdapInterface $ldap, mixed $resource): void
{
- $errorCode = 0;
- $dn = $errorMessage = $refs = null;
$controls = $this->query->controls;
- $ldap->parseResult(
- $resource,
- $errorCode,
- $dn,
- $errorMessage,
- $refs,
- $controls
+ $response = $ldap->parseResult(
+ result: $resource,
+ controls: $controls
);
+ $controls = array_merge($controls, $response->controls ?? []);
+
$cookie = $controls[LDAP_CONTROL_PAGEDRESULTS]['value']['cookie'] ?? '';
$this->query->controls[LDAP_CONTROL_PAGEDRESULTS]['value'] = [
@@ -59,9 +55,9 @@ class Paginator extends AbstractPaginator
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- protected function resetServerControls(LdapInterface $ldap)
+ protected function resetServerControls(LdapInterface $ldap): void
{
unset($this->query->controls[LDAP_CONTROL_PAGEDRESULTS]);
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Slice.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Slice.php
index 12faa5bd1..2921724ca 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Slice.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Query/Slice.php
@@ -10,49 +10,34 @@ use JsonSerializable;
class Slice implements ArrayAccess, IteratorAggregate, JsonSerializable
{
/**
- * All of the items being paginated.
- *
- * @var \LdapRecord\Query\Collection|array
+ * All the items in the slice.
*/
- protected $items;
+ protected Collection|array $items;
/**
* The number of items to be shown per page.
- *
- * @var int
*/
- protected $perPage;
+ protected int $perPage;
/**
* The total number of items before slicing.
- *
- * @var int
*/
- protected $total;
+ protected int $total;
/**
* The last available page.
- *
- * @var int
*/
- protected $lastPage;
+ protected int $lastPage;
/**
* The current page being "viewed".
- *
- * @var int
*/
- protected $currentPage;
+ protected int $currentPage;
/**
* Constructor.
- *
- * @param \LdapRecord\Query\Collection|array $items
- * @param int $total
- * @param int $perPage
- * @param int|null $currentPage
*/
- public function __construct($items, $total, $perPage, $currentPage = null)
+ public function __construct(Collection|array $items, int $total, int $perPage, ?int $currentPage = null)
{
$this->items = $items;
$this->total = $total;
@@ -63,202 +48,159 @@ class Slice implements ArrayAccess, IteratorAggregate, JsonSerializable
/**
* Get the slice of items being paginated.
- *
- * @return \LdapRecord\Query\Collection|array
*/
- public function items()
+ public function items(): Collection|array
{
return $this->items;
}
/**
* Get the total number of items being paginated.
- *
- * @return int
*/
- public function total()
+ public function total(): int
{
return $this->total;
}
/**
* Get the number of items shown per page.
- *
- * @return int
*/
- public function perPage()
+ public function perPage(): int
{
return $this->perPage;
}
/**
* Determine if there are more items in the data source.
- *
- * @return bool
*/
- public function hasMorePages()
+ public function hasMorePages(): bool
{
return $this->currentPage() < $this->lastPage();
}
/**
* Determine if there are enough items to split into multiple pages.
- *
- * @return bool
*/
- public function hasPages()
+ public function hasPages(): bool
{
return $this->currentPage() != 1 || $this->hasMorePages();
}
/**
* Determine if the paginator is on the first page.
- *
- * @return bool
*/
- public function onFirstPage()
+ public function onFirstPage(): bool
{
return $this->currentPage() <= 1;
}
/**
* Determine if the paginator is on the last page.
- *
- * @return bool
*/
- public function onLastPage()
+ public function onLastPage(): bool
{
return ! $this->hasMorePages();
}
/**
* Get the current page.
- *
- * @return int
*/
- public function currentPage()
+ public function currentPage(): int
{
return $this->currentPage;
}
/**
* Get the last page.
- *
- * @return int
*/
- public function lastPage()
+ public function lastPage(): int
{
return $this->lastPage;
}
/**
* Get an iterator for the items.
- *
- * @return \ArrayIterator
*/
#[\ReturnTypeWillChange]
- public function getIterator()
+ public function getIterator(): ArrayIterator
{
return new ArrayIterator($this->items);
}
/**
* Determine if the list of items is empty.
- *
- * @return bool
*/
- public function isEmpty()
+ public function isEmpty(): bool
{
return empty($this->items);
}
/**
* Determine if the list of items is not empty.
- *
- * @return bool
*/
- public function isNotEmpty()
+ public function isNotEmpty(): bool
{
return ! $this->isEmpty();
}
/**
* Get the number of items for the current page.
- *
- * @return int
*/
#[\ReturnTypeWillChange]
- public function count()
+ public function count(): int
{
return count($this->items);
}
/**
* Determine if the given item exists.
- *
- * @param mixed $key
- * @return bool
*/
#[\ReturnTypeWillChange]
- public function offsetExists($key)
+ public function offsetExists(mixed $offset): bool
{
- return array_key_exists($key, $this->items);
+ return array_key_exists($offset, $this->items);
}
/**
* Get the item at the given offset.
- *
- * @param mixed $key
- * @return mixed
*/
#[\ReturnTypeWillChange]
- public function offsetGet($key)
+ public function offsetGet(mixed $offset): mixed
{
- return $this->items[$key] ?? null;
+ return $this->items[$offset] ?? null;
}
/**
* Set the item at the given offset.
- *
- * @param mixed $key
- * @param mixed $value
- * @return void
*/
#[\ReturnTypeWillChange]
- public function offsetSet($key, $value)
+ public function offsetSet(mixed $offset, mixed $value): void
{
- $this->items[$key] = $value;
+ $this->items[$offset] = $value;
}
/**
* Unset the item at the given key.
- *
- * @param mixed $key
- * @return void
*/
#[\ReturnTypeWillChange]
- public function offsetUnset($key)
+ public function offsetUnset(mixed $offset): void
{
- unset($this->items[$key]);
+ unset($this->items[$offset]);
}
/**
* Convert the object into something JSON serializable.
- *
- * @return array
*/
#[\ReturnTypeWillChange]
- public function jsonSerialize()
+ public function jsonSerialize(): array
{
return $this->toArray();
}
/**
* Get the arrayable items.
- *
- * @return array
*/
- public function getArrayableItems()
+ public function getArrayableItems(): array
{
return $this->items instanceof Collection
? $this->items->all()
@@ -267,10 +209,8 @@ class Slice implements ArrayAccess, IteratorAggregate, JsonSerializable
/**
* Get the instance as an array.
- *
- * @return array
*/
- public function toArray()
+ public function toArray(): array
{
return [
'current_page' => $this->currentPage(),
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Arr.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Arr.php
index 7475859ae..6c3217a50 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Arr.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Arr.php
@@ -8,23 +8,16 @@ class Arr
{
/**
* Determine whether the given value is array accessible.
- *
- * @param mixed $value
- * @return bool
*/
- public static function accessible($value)
+ public static function accessible(mixed $value): bool
{
return is_array($value) || $value instanceof ArrayAccess;
}
/**
* Determine if the given key exists in the provided array.
- *
- * @param \ArrayAccess|array $array
- * @param string|int $key
- * @return bool
*/
- public static function exists($array, $key)
+ public static function exists(ArrayAccess|array $array, string|int $key): bool
{
if ($array instanceof ArrayAccess) {
return $array->offsetExists($key);
@@ -35,11 +28,8 @@ class Arr
/**
* If the given value is not an array and not null, wrap it in one.
- *
- * @param mixed $value
- * @return array
*/
- public static function wrap($value)
+ public static function wrap(mixed $value): array
{
if (is_null($value)) {
return [];
@@ -49,14 +39,9 @@ class Arr
}
/**
- * Return the first element in an array passing a given truth test.
- *
- * @param iterable $array
- * @param callable|null $callback
- * @param mixed $default
- * @return mixed
+ * Get the first element in an array passing a given truth test.
*/
- public static function first($array, callable $callback = null, $default = null)
+ public static function first(iterable $array, ?callable $callback = null, mixed $default = null): mixed
{
if (is_null($callback)) {
if (empty($array)) {
@@ -78,14 +63,11 @@ class Arr
}
/**
- * Return the last element in an array passing a given truth test.
+ * Get the last element in an array passing a given truth test.
*
* @param array $array
- * @param callable|null $callback
- * @param mixed $default
- * @return mixed
*/
- public static function last($array, callable $callback = null, $default = null)
+ public static function last(iterable $array, ?callable $callback = null, mixed $default = null): mixed
{
if (is_null($callback)) {
return empty($array) ? Helpers::value($default) : end($array);
@@ -96,13 +78,8 @@ class Arr
/**
* Get an item from an array using "dot" notation.
- *
- * @param ArrayAccess|array $array
- * @param string|int|null $key
- * @param mixed $default
- * @return mixed
*/
- public static function get($array, $key, $default = null)
+ public static function get(ArrayAccess|array $array, string|int|null $key, mixed $default = null): mixed
{
if (! static::accessible($array)) {
return Helpers::value($default);
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Helpers.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Helpers.php
index ab217d6ff..5b4bd46fb 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Helpers.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Helpers.php
@@ -7,13 +7,9 @@ use Closure;
class Helpers
{
/**
- * Return the default value of the given value.
- *
- * @param mixed $value
- * @param mixed $args
- * @return mixed
+ * Get the default value of the given value.
*/
- public static function value($value, ...$args)
+ public static function value(mixed $value, mixed ...$args): mixed
{
return $value instanceof Closure ? $value(...$args) : $value;
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Str.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Str.php
index 820834e21..ced2a5fd1 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Str.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Support/Str.php
@@ -5,19 +5,49 @@ namespace LdapRecord\Support;
class Str
{
/**
- * Return the remainder of a string after the last occurrence of a given value.
- *
- * @param string $subject
- * @param string $search
- * @return string
+ * Determine if a given string matches a given pattern.
*/
- public static function afterLast($subject, $search)
+ public static function is(string|iterable $pattern, string $value): bool
+ {
+ if (! is_iterable($pattern)) {
+ $pattern = [$pattern];
+ }
+
+ foreach ($pattern as $pattern) {
+ $pattern = (string) $pattern;
+
+ // If the given value is an exact match we can of course return true right
+ // from the beginning. Otherwise, we will translate asterisks and do an
+ // actual pattern match against the two strings to see if they match.
+ if ($pattern === $value) {
+ return true;
+ }
+
+ $pattern = preg_quote($pattern, '#');
+
+ // Asterisks are translated into zero-or-more regular expression wildcards
+ // to make it convenient to check if the strings starts with the given
+ // pattern such as "library/*", making any string check convenient.
+ $pattern = str_replace('\*', '.*', $pattern);
+
+ if (preg_match('#^'.$pattern.'\z#u', $value) === 1) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the remainder of a string after the last occurrence of a given value.
+ */
+ public static function afterLast(string $subject, string $search): string
{
if ($search === '') {
return $subject;
}
- $position = strrpos($subject, (string) $search);
+ $position = strrpos($subject, $search);
if ($position === false) {
return $subject;
@@ -28,12 +58,8 @@ class Str
/**
* Determine if a given string starts with a given substring.
- *
- * @param string $haystack
- * @param string|string[] $needles
- * @return bool
*/
- public static function startsWith($haystack, $needles)
+ public static function startsWith(string $haystack, array|string $needles): bool
{
foreach ((array) $needles as $needle) {
if ((string) $needle !== '' && str_starts_with($haystack, $needle)) {
@@ -46,12 +72,8 @@ class Str
/**
* Determine if a given string ends with a given substring.
- *
- * @param string $haystack
- * @param string|string[] $needles
- * @return bool
*/
- public static function endsWith($haystack, $needles)
+ public static function endsWith(string $haystack, array|string $needles): bool
{
foreach ((array) $needles as $needle) {
if (
@@ -67,14 +89,8 @@ class Str
/**
* Execute a callback when a needle is found in the haystack.
- *
- * @param string $haystack
- * @param string|string[] $needles
- * @param \Closure|mixed $callback
- * @param \Closure|mixed $default
- * @return mixed
*/
- public static function whenContains($haystack, $needles, $callback, $default = null)
+ public static function whenContains(string $haystack, array|string $needles, mixed $callback, mixed $default = null): mixed
{
foreach ((array) $needles as $needle) {
if (static::contains($haystack, $needle)) {
@@ -87,13 +103,8 @@ class Str
/**
* Determine if a given string contains a given substring.
- *
- * @param string $haystack
- * @param string|string[] $needles
- * @param bool $ignoreCase
- * @return bool
*/
- public static function contains($haystack, $needles, $ignoreCase = false)
+ public static function contains(string $haystack, array|string $needles, bool $ignoreCase = false): bool
{
if ($ignoreCase) {
$haystack = mb_strtolower($haystack);
@@ -110,15 +121,9 @@ class Str
}
/**
- * Returns the number of substring occurrences.
- *
- * @param string $haystack
- * @param string $needle
- * @param int $offset
- * @param int|null $length
- * @return int
+ * Get the number of substring occurrences.
*/
- public static function substrCount($haystack, $needle, $offset = 0, $length = null)
+ public static function substrCount(string $haystack, string $needle, int $offset = 0, ?int $length = null): int
{
if (! is_null($length)) {
return substr_count($haystack, $needle, $offset, $length);
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/AuthGuardFake.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/AuthGuardFake.php
index 4a691506d..36574c0d5 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/AuthGuardFake.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/AuthGuardFake.php
@@ -8,11 +8,6 @@ class AuthGuardFake extends Guard
{
/**
* Always allow binding as configured user.
- *
- * @return bool
*/
- public function bindAsConfiguredUser()
- {
- return true;
- }
+ public function bindAsConfiguredUser(): void {}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/ConnectionFake.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/ConnectionFake.php
index 09530f5c7..2c76a06d5 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/ConnectionFake.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/ConnectionFake.php
@@ -4,6 +4,7 @@ namespace LdapRecord\Testing;
use LdapRecord\Auth\Guard;
use LdapRecord\Connection;
+use LdapRecord\LdapInterface;
use LdapRecord\Models\Model;
class ConnectionFake extends Connection
@@ -13,25 +14,19 @@ class ConnectionFake extends Connection
*
* @var LdapFake
*/
- protected $ldap;
+ protected LdapInterface $ldap;
/**
* Whether the fake is connected.
- *
- * @var bool
*/
- protected $connected = false;
+ protected bool $connected = false;
/**
* Make a new fake LDAP connection instance.
- *
- * @param array $config
- * @param string $ldap
- * @return static
*/
- public static function make(array $config = [], $ldap = LdapFake::class)
+ public static function make(array $config = [], string $ldap = LdapFake::class): static
{
- $connection = new static($config, new $ldap());
+ $connection = new static($config, new $ldap);
$connection->configure();
@@ -40,13 +35,10 @@ class ConnectionFake extends Connection
/**
* Set the user to authenticate as.
- *
- * @param Model|string $user
- * @return $this
*/
- public function actingAs($user)
+ public function actingAs(Model|string $user): static
{
- $this->ldap->shouldAuthenticateWith(
+ $this->ldap->shouldAllowBindWith(
$user instanceof Model ? $user->getDn() : $user
);
@@ -55,10 +47,8 @@ class ConnectionFake extends Connection
/**
* Set the connection to bypass bind attempts as the configured user.
- *
- * @return $this
*/
- public function shouldBeConnected()
+ public function shouldBeConnected(): static
{
$this->connected = true;
@@ -71,10 +61,8 @@ class ConnectionFake extends Connection
/**
* Set the connection to attempt binding as the configured user.
- *
- * @return $this
*/
- public function shouldNotBeConnected()
+ public function shouldNotBeConnected(): static
{
$this->connected = false;
@@ -86,10 +74,20 @@ class ConnectionFake extends Connection
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function isConnected()
+ public function isConnected(): bool
{
return $this->connected ?: parent::isConnected();
}
+
+ /**
+ * Perform tear down tasks on the fake.
+ *
+ * @throws LdapExpectationException
+ */
+ public function tearDown(): void
+ {
+ $this->ldap->assertMinimumExpectationCounts();
+ }
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/DirectoryFake.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/DirectoryFake.php
index 72be02af3..90cbf7ae6 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/DirectoryFake.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/DirectoryFake.php
@@ -7,44 +7,50 @@ use LdapRecord\Container;
class DirectoryFake
{
/**
- * Setup the fake connection.
+ * The LDAP connections that were replaced with fakes.
*
- * @param string|null $name
- * @return ConnectionFake
+ * @var \LdapRecord\Connection[]
+ */
+ protected static array $replaced = [];
+
+ /**
+ * Replace a connection a fake.
*
* @throws \LdapRecord\ContainerException
*/
- public static function setup($name = null)
+ public static function setup(?string $name = null): ConnectionFake
{
- $connection = Container::getConnection($name);
+ $name = $name ?? Container::getDefaultConnectionName();
+
+ $connection = static::$replaced[$name] = Container::getConnection($name);
$fake = static::makeConnectionFake(
$connection->getConfiguration()->all()
);
- // Replace the connection with a fake.
Container::addConnection($fake, $name);
return $fake;
}
/**
- * Reset the container.
- *
- * @return void
+ * Replace all faked connections with their original.
*/
- public static function tearDown()
+ public static function tearDown(): void
{
- Container::reset();
+ foreach (static::$replaced as $name => $connection) {
+ Container::getConnection($name)->tearDown();
+ }
+
+ Container::flush();
+
+ static::$replaced = [];
}
/**
* Make a connection fake.
- *
- * @param array $config
- * @return ConnectionFake
*/
- public static function makeConnectionFake(array $config = [])
+ public static function makeConnectionFake(array $config = []): ConnectionFake
{
return ConnectionFake::make($config)->shouldBeConnected();
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectation.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectation.php
index 693459149..2e010d7d7 100644
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectation.php
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectation.php
@@ -3,7 +3,9 @@
namespace LdapRecord\Testing;
use Closure;
+use Exception;
use LdapRecord\LdapRecordException;
+use LdapRecord\LdapResultResponse;
use PHPUnit\Framework\Constraint\Callback;
use PHPUnit\Framework\Constraint\Constraint;
use PHPUnit\Framework\Constraint\IsEqual;
@@ -13,91 +15,76 @@ class LdapExpectation
{
/**
* The value to return from the expectation.
- *
- * @var mixed
*/
- protected $value;
+ protected mixed $value = null;
/**
* The exception to throw from the expectation.
- *
- * @var null|LdapRecordException|\Exception
*/
- protected $exception;
+ protected ?Exception $exception = null;
/**
- * The amount of times the expectation should be called.
- *
- * @var int
+ * The tracked number of times the expectation should be called.
*/
- protected $count = 1;
+ protected int $count = 1;
+
+ /**
+ * The original number of times the expectation should be called.
+ */
+ protected int $originalCount = 1;
+
+ /**
+ * The actual number of times the expectation was called.
+ */
+ protected int $called = 0;
/**
* The method that the expectation belongs to.
- *
- * @var string
*/
- protected $method;
+ protected ?string $method = null;
/**
* The methods argument's.
- *
- * @var array
*/
- protected $args = [];
+ protected array $args = [];
/**
* Whether the same expectation should be returned indefinitely.
- *
- * @var bool
*/
- protected $indefinitely = true;
+ protected bool $indefinitely = true;
/**
- * Whether the expectation should return errors.
- *
- * @var bool
+ * Whether the expectation should return an error.
*/
- protected $errors = false;
+ protected bool $errors = false;
/**
- * The error number to return.
- *
- * @var int
+ * The error code to return.
*/
- protected $errorCode = 1;
+ protected int $errorCode = 1;
/**
- * The last error string to return.
- *
- * @var string
+ * The error message to return.
*/
- protected $errorMessage = '';
+ protected string $errorMessage = 'Unknown error';
/**
* The diagnostic message string to return.
- *
- * @var string
*/
- protected $errorDiagnosticMessage = '';
+ protected ?string $errorDiagnosticMessage = null;
/**
* Constructor.
- *
- * @param string $method
*/
- public function __construct($method)
+ public function __construct(string $method)
{
$this->method = $method;
}
/**
* Set the arguments that the operation should receive.
- *
- * @param mixed $args
- * @return $this
*/
- public function with($args)
+ public function with(mixed $args): static
{
$this->args = array_map(function ($arg) {
if ($arg instanceof Closure) {
@@ -116,11 +103,8 @@ class LdapExpectation
/**
* Set the expected value to return.
- *
- * @param mixed $value
- * @return $this
*/
- public function andReturn($value)
+ public function andReturn(mixed $value): static
{
$this->value = $value;
@@ -128,31 +112,62 @@ class LdapExpectation
}
/**
- * The error message to return from the expectation.
- *
- * @param int $code
- * @param string $error
- * @param string $diagnosticMessage
- * @return $this
+ * Set the expected value to return true.
*/
- public function andReturnError($code = 1, $error = '', $diagnosticMessage = '')
+ public function andReturnTrue(): static
+ {
+ return $this->andReturn(true);
+ }
+
+ /**
+ * Set the expected value to return false.
+ */
+ public function andReturnFalse(): static
+ {
+ return $this->andReturn(false);
+ }
+
+ /**
+ * The error message to return from the expectation.
+ */
+ public function andReturnError(int $errorCode = 1, string $errorMessage = 'Unknown error', ?string $diagnosticMessage = null): static
{
$this->errors = true;
- $this->errorCode = $code;
- $this->errorMessage = $error;
+ $this->errorCode = $errorCode;
+ $this->errorMessage = $errorMessage;
$this->errorDiagnosticMessage = $diagnosticMessage;
return $this;
}
/**
- * Set the expected exception to throw.
- *
- * @param string|\Exception|LdapRecordException $exception
- * @return $this
+ * Return an error LDAP result response.
*/
- public function andThrow($exception)
+ public function andReturnErrorResponse(int $code = 1, ?string $errorMessage = null): static
+ {
+ return $this->andReturnResponse($code, $errorMessage);
+ }
+
+ /**
+ * Return an LDAP result response.
+ */
+ public function andReturnResponse(
+ int $errorCode = 0,
+ ?string $matchedDn = null,
+ ?string $errorMessage = null,
+ array $referrals = [],
+ array $controls = []
+ ): static {
+ return $this->andReturn(
+ new LdapResultResponse($errorCode, $matchedDn, $errorMessage, $referrals, $controls)
+ );
+ }
+
+ /**
+ * Set the expected exception to throw.
+ */
+ public function andThrow(string|Exception $exception): static
{
if (is_string($exception)) {
$exception = new LdapRecordException($exception);
@@ -165,45 +180,36 @@ class LdapExpectation
/**
* Set the expectation to be only called once.
- *
- * @return $this
*/
- public function once()
+ public function once(): static
{
- return $this->times(1);
+ return $this->times();
}
/**
* Set the expectation to be only called twice.
- *
- * @return $this
*/
- public function twice()
+ public function twice(): static
{
return $this->times(2);
}
/**
* Set the expectation to be called the given number of times.
- *
- * @param int $count
- * @return $this
*/
- public function times($count = 1)
+ public function times(int $count = 1): static
{
$this->indefinitely = false;
- $this->count = $count;
+ $this->originalCount = $this->count = $count;
return $this;
}
/**
* Get the method the expectation belongs to.
- *
- * @return string
*/
- public function getMethod()
+ public function getMethod(): string
{
if (is_null($this->method)) {
throw new UnexpectedValueException('An expectation must have a method.');
@@ -214,89 +220,105 @@ class LdapExpectation
/**
* Get the expected call count.
- *
- * @return int
*/
- public function getExpectedCount()
+ public function getExpectedCount(): int
{
return $this->count;
}
+ /**
+ * Get the original expected call count.
+ */
+ public function getOriginalExpectedCount(): int
+ {
+ return $this->originalCount;
+ }
+
+ /**
+ * Get the count that the expectation was called.
+ */
+ public function getCalledCount(): int
+ {
+ return $this->called;
+ }
+
/**
* Get the expected arguments.
*
* @return Constraint[]
*/
- public function getExpectedArgs()
+ public function getExpectedArgs(): array
{
return $this->args;
}
/**
* Get the expected exception.
- *
- * @return null|\Exception|LdapRecordException
*/
- public function getExpectedException()
+ public function getExpectedException(): ?Exception
{
return $this->exception;
}
/**
* Get the expected value.
- *
- * @return mixed
*/
- public function getExpectedValue()
+ public function getExpectedValue(): mixed
{
return $this->value;
}
/**
- * Determine whether the expectation is returning an error.
- *
- * @return bool
+ * Determine whether the expectation can be called indefinitely.
*/
- public function isReturningError()
+ public function isIndefinite(): bool
+ {
+ return $this->indefinitely;
+ }
+
+ /**
+ * Determine whether the expectation is returning an error.
+ */
+ public function isReturningError(): bool
{
return $this->errors;
}
/**
- * @return int
+ * Get the expected error code.
*/
- public function getExpectedErrorCode()
+ public function getExpectedErrorCode(): int
{
return $this->errorCode;
}
/**
- * @return string
+ * Get the expected error message.
*/
- public function getExpectedErrorMessage()
+ public function getExpectedErrorMessage(): ?string
{
return $this->errorMessage;
}
/**
- * @return string
+ * Get the expected diagnostic message.
*/
- public function getExpectedErrorDiagnosticMessage()
+ public function getExpectedErrorDiagnosticMessage(): ?string
{
return $this->errorDiagnosticMessage;
}
/**
- * Decrement the call count of the expectation.
- *
- * @return $this
+ * Decrement the expected count of the expectation.
*/
- public function decrementCallCount()
+ public function decrementExpectedCount(): static
{
if (! $this->indefinitely) {
$this->count -= 1;
}
+ $this->called++;
+
return $this;
}
}
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectationException.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectationException.php
new file mode 100644
index 000000000..74a3ebe33
--- /dev/null
+++ b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Testing/LdapExpectationException.php
@@ -0,0 +1,7 @@
+
*/
- protected $expectations = [];
+ protected array $expectations = [];
/**
* The default fake error number.
- *
- * @var int
*/
- protected $errNo = 1;
+ protected int $errNo = 1;
/**
* The default fake last error string.
- *
- * @var string
*/
- protected $lastError = '';
+ protected string $lastError = 'Unknown error';
/**
* The default fake diagnostic message string.
- *
- * @var string
*/
- protected $diagnosticMessage = '';
+ protected ?string $diagnosticMessage = null;
/**
* Create a new expected operation.
- *
- * @param string $method
- * @return LdapExpectation
*/
- public static function operation($method)
+ public static function operation(string $method): LdapExpectation
{
return new LdapExpectation($method);
}
/**
- * Set the user that will pass binding.
- *
- * @param string $dn
- * @return $this
+ * Set the fake LDAP host.
*/
- public function shouldAuthenticateWith($dn)
+ public function setHost(string $host): void
{
- return $this->expect(
- static::operation('bind')->with($dn, PHPUnit::anything())->andReturn(true)
- );
+ $this->host = $host;
}
/**
* Add an LDAP method expectation.
- *
- * @param LdapExpectation|array $expectations
- * @return $this
*/
- public function expect($expectations = [])
+ public function expect(LdapExpectation|array $expectations = []): static
{
$expectations = Arr::wrap($expectations);
@@ -101,11 +85,8 @@ class LdapFake implements LdapInterface
/**
* Determine if the method has any expectations.
- *
- * @param string $method
- * @return bool
*/
- public function hasExpectations($method)
+ public function hasExpectations(string $method): bool
{
return count($this->getExpectations($method)) > 0;
}
@@ -113,33 +94,55 @@ class LdapFake implements LdapInterface
/**
* Get expectations by method.
*
- * @param string $method
- * @return LdapExpectation[]|mixed
+ * @return LdapExpectation[]
*/
- public function getExpectations($method)
+ public function getExpectations(string $method): array
{
return $this->expectations[$method] ?? [];
}
/**
* Remove an expectation by method and key.
- *
- * @param string $method
- * @param int $key
- * @return void
*/
- public function removeExpectation($method, $key)
+ public function removeExpectation(string $method, int $key): void
{
unset($this->expectations[$method][$key]);
}
/**
- * Set the error number of a failed bind attempt.
- *
- * @param int $number
- * @return $this
+ * Set the fake to allow any bind attempt.
*/
- public function shouldReturnErrorNumber($number = 1)
+ public function shouldAllowAnyBind(): static
+ {
+ return $this->expect(
+ static::operation('bind')->andReturnResponse()
+ );
+ }
+
+ /**
+ * Set the fake to allow any bind attempt with the given DN.
+ */
+ public function shouldAllowBindWith(string $dn): static
+ {
+ return $this->expect(
+ static::operation('bind')->with($dn, PHPUnit::anything())->andReturnResponse()
+ );
+ }
+
+ /**
+ * Set the user that will pass binding.
+ *
+ * @deprecated Use shouldAllowBindWith instead.
+ */
+ public function shouldAuthenticateWith(string $dn): static
+ {
+ return $this->shouldAllowBindWith($dn);
+ }
+
+ /**
+ * Set the error number of a failed bind attempt.
+ */
+ public function shouldReturnErrorNumber(int $number = 1): static
{
$this->errNo = $number;
@@ -148,11 +151,8 @@ class LdapFake implements LdapInterface
/**
* Set the last error of a failed bind attempt.
- *
- * @param string $message
- * @return $this
*/
- public function shouldReturnError($message = '')
+ public function shouldReturnError(string $message): static
{
$this->lastError = $message;
@@ -161,11 +161,8 @@ class LdapFake implements LdapInterface
/**
* Set the diagnostic message of a failed bind attempt.
- *
- * @param string $message
- * @return $this
*/
- public function shouldReturnDiagnosticMessage($message = '')
+ public function shouldReturnDiagnosticMessage(?string $message): static
{
$this->diagnosticMessage = $message;
@@ -174,38 +171,32 @@ class LdapFake implements LdapInterface
/**
* Return a fake error number.
- *
- * @return int
*/
- public function errNo()
+ public function errNo(): int
{
return $this->errNo;
}
/**
* Return a fake error.
- *
- * @return string
*/
- public function getLastError()
+ public function getLastError(): string
{
return $this->lastError;
}
/**
- * @inheritdoc
+ * Return a fake diagnostic message.
*/
- public function getDiagnosticMessage()
+ public function getDiagnosticMessage(): ?string
{
return $this->diagnosticMessage;
}
/**
* Return a fake detailed error.
- *
- * @return DetailedError
*/
- public function getDetailedError()
+ public function getDetailedError(): DetailedError
{
return new DetailedError(
$this->errNo(),
@@ -215,258 +206,309 @@ class LdapFake implements LdapInterface
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getEntries($searchResults)
+ public function getEntries(mixed $result): array
{
- return $searchResults;
+ return $result;
}
/**
- * @inheritdoc
+ * {@inheritDoc}
*/
- public function isUsingSSL()
+ public function getValuesLen(mixed $entry, string $attribute): array|false
{
- return $this->hasExpectations('isUsingSSL')
- ? $this->resolveExpectation('isUsingSSL')
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function compare(string $dn, string $attribute, string $value, ?array $controls = null): bool|int
+ {
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function setRebindCallback(callable $callback): bool
+ {
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getFirstEntry(mixed $result): mixed
+ {
+ return $this->executeFailableOperation(function () use ($result) {
+ return ldap_first_entry($this->connection, $result);
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getNextEntry(mixed $entry): mixed
+ {
+ return $this->executeFailableOperation(function () use ($entry) {
+ return ldap_next_entry($this->connection, $entry);
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getAttributes(mixed $entry): array|false
+ {
+ return $this->executeFailableOperation(function () use ($entry) {
+ return ldap_get_attributes($this->connection, $entry);
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function countEntries(mixed $result): int
+ {
+ return $this->executeFailableOperation(function () use ($result) {
+ return ldap_count_entries($this->connection, $result);
+ });
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isUsingSSL(): bool
+ {
+ return $this->hasExpectations(__FUNCTION__)
+ ? $this->resolveExpectation(__FUNCTION__)
: $this->useSSL;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function isUsingTLS()
+ public function isUsingTLS(): bool
{
- return $this->hasExpectations('isUsingTLS')
- ? $this->resolveExpectation('isUsingTLS')
+ return $this->hasExpectations(__FUNCTION__)
+ ? $this->resolveExpectation(__FUNCTION__)
: $this->useTLS;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function isBound()
+ public function isBound(): bool
{
- return $this->hasExpectations('isBound')
- ? $this->resolveExpectation('isBound')
+ return $this->hasExpectations(__FUNCTION__)
+ ? $this->resolveExpectation(__FUNCTION__)
: $this->bound;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getHost()
+ public function setOption(int $option, mixed $value): bool
{
- return $this->hasExpectations('getHost')
- ? $this->resolveExpectation('getHost')
- : $this->host;
- }
-
- /**
- * @inheritdoc
- */
- public function setOption($option, $value)
- {
- return $this->hasExpectations('setOption')
- ? $this->resolveExpectation('setOption', func_get_args())
+ return $this->hasExpectations(__FUNCTION__)
+ ? $this->resolveExpectation(__FUNCTION__, func_get_args())
: true;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function getOption($option, &$value = null)
+ public function getOption(int $option, mixed &$value = null): mixed
{
- return $this->resolveExpectation('getOption', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function startTLS()
+ public function startTLS(): bool
{
- return $this->resolveExpectation('startTLS', func_get_args());
+ return $this->secure = $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function connect($hosts = [], $port = 389)
+ public function connect(string|array $hosts = [], int $port = 389, ?string $protocol = null): bool
{
$this->bound = false;
-
+ $this->protocol = $protocol;
$this->host = $this->makeConnectionUris($hosts, $port);
- return $this->connection = $this->hasExpectations('connect')
- ? $this->resolveExpectation('connect', func_get_args())
+ return $this->connection = $this->hasExpectations(__FUNCTION__)
+ ? $this->resolveExpectation(__FUNCTION__, func_get_args())
: true;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function close()
+ public function close(): bool
{
- $this->connection = null;
$this->bound = false;
- $this->host = null;
+ $this->secure = false;
- return $this->hasExpectations('close')
- ? $this->resolveExpectation('close')
+ $this->host = null;
+ $this->protocol = null;
+ $this->connection = null;
+
+ return $this->hasExpectations(__FUNCTION__)
+ ? $this->resolveExpectation(__FUNCTION__)
: true;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function bind($username, $password)
+ public function bind(?string $dn = null, ?string $password = null, ?array $controls = null): LdapResultResponse
{
- return $this->bound = $this->resolveExpectation('bind', func_get_args());
+ $result = $this->resolveExpectation(__FUNCTION__, func_get_args());
+
+ $this->handleBindResponse($result);
+
+ return $result;
}
/**
- * @inheritdoc
+ * {@inheritDoc}
*/
- public function search($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = [])
+ public function saslBind(?string $dn = null, ?string $password = null, ?array $options = null): bool
{
- return $this->resolveExpectation('search', func_get_args());
+ return $this->bound = $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function listing($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = [])
+ public function search(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed
{
- return $this->resolveExpectation('listing', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function read($dn, $filter, array $fields, $onlyAttributes = false, $size = 0, $time = 0, $deref = LDAP_DEREF_NEVER, $serverControls = [])
+ public function list(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed
{
- return $this->resolveExpectation('read', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function parseResult($result, &$errorCode, &$dn, &$errorMessage, &$referrals, &$serverControls = [])
+ public function read(string $dn, string $filter, array $fields, bool $onlyAttributes = false, int $size = 0, int $time = 0, int $deref = LDAP_DEREF_NEVER, ?array $controls = null): mixed
{
- return $this->resolveExpectation('parseResult', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function add($dn, array $entry)
+ public function parseResult(mixed $result, int &$errorCode = 0, ?string &$dn = null, ?string &$errorMessage = null, ?array &$referrals = null, ?array &$controls = null): LdapResultResponse|false
{
- return $this->resolveExpectation('add', func_get_args());
+ return $this->hasExpectations(__FUNCTION__)
+ ? $this->resolveExpectation(__FUNCTION__, func_get_args())
+ : new LdapResultResponse;
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function delete($dn)
+ public function add(string $dn, array $entry): bool
{
- return $this->resolveExpectation('delete', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false)
+ public function delete(string $dn): bool
{
- return $this->resolveExpectation('rename', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function modify($dn, array $entry)
+ public function rename(string $dn, string $newRdn, string $newParent, bool $deleteOldRdn = false): bool
{
- return $this->resolveExpectation('modify', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function modifyBatch($dn, array $values)
+ public function modify(string $dn, array $entry): bool
{
- return $this->resolveExpectation('modifyBatch', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function modAdd($dn, array $entry)
+ public function modifyBatch(string $dn, array $values): bool
{
- return $this->resolveExpectation('modAdd', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function modReplace($dn, array $entry)
+ public function modAdd(string $dn, array $entry): bool
{
- return $this->resolveExpectation('modReplace', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function modDelete($dn, array $entry)
+ public function modReplace(string $dn, array $entry): bool
{
- return $this->resolveExpectation('modDelete', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function controlPagedResult($pageSize = 1000, $isCritical = false, $cookie = '')
+ public function modDelete(string $dn, array $entry): bool
{
- return $this->resolveExpectation('controlPagedResult', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function controlPagedResultResponse($result, &$cookie)
+ public function freeResult(mixed $result): bool
{
- return $this->resolveExpectation('controlPagedResultResponse', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
- * @inheritdoc
+ * {@inheritdoc}
*/
- public function freeResult($result)
+ public function err2Str(int $number): string
{
- return $this->resolveExpectation('freeResult', func_get_args());
- }
-
- /**
- * @inheritdoc
- */
- public function err2Str($number)
- {
- return $this->resolveExpectation('err2Str', func_get_args());
+ return $this->resolveExpectation(__FUNCTION__, func_get_args());
}
/**
* Resolve the methods expectations.
*
- * @param string $method
- * @param array $args
- * @return mixed
- *
- * @throws Exception
+ * @throws LdapExpectationException
*/
- protected function resolveExpectation($method, array $args = [])
+ protected function resolveExpectation(string $method, array $args = []): mixed
{
foreach ($this->getExpectations($method) as $key => $expectation) {
$this->assertMethodArgumentsMatch($method, $expectation->getExpectedArgs(), $args);
- $expectation->decrementCallCount();
+ $expectation->decrementExpectedCount();
if ($expectation->getExpectedCount() === 0) {
$this->removeExpectation($method, $key);
@@ -483,31 +525,43 @@ class LdapFake implements LdapInterface
return $expectation->getExpectedValue();
}
- throw new Exception("LDAP method [$method] was unexpected.");
+ throw new LdapExpectationException("LDAP method [$method] was unexpected.");
}
/**
* Apply the expectation error to the fake.
- *
- * @param LdapExpectation $expectation
- * @return void
*/
- protected function applyExpectationError(LdapExpectation $expectation)
+ protected function applyExpectationError(LdapExpectation $expectation): void
{
$this->shouldReturnError($expectation->getExpectedErrorMessage());
$this->shouldReturnErrorNumber($expectation->getExpectedErrorCode());
$this->shouldReturnDiagnosticMessage($expectation->getExpectedErrorDiagnosticMessage());
}
+ /**
+ * Assert that the expectations have been called their minimum amount of times.
+ *
+ * @throws LdapExpectationException
+ */
+ public function assertMinimumExpectationCounts(): void
+ {
+ foreach ($this->expectations as $method => $expectations) {
+ foreach ($expectations as $expectation) {
+ if (! $expectation->isIndefinite() && $expectation->getExpectedCount()) {
+ $remaining = ($original = $expectation->getOriginalExpectedCount()) - $expectation->getExpectedCount();
+
+ throw new LdapExpectationException("Method [$method] should be called $original times but was called $remaining times.");
+ }
+ }
+ }
+ }
+
/**
* Assert that the expected arguments match the operations arguments.
*
- * @param string $method
* @param Constraint[] $expectedArgs
- * @param array $methodArgs
- * @return void
*/
- protected function assertMethodArgumentsMatch($method, array $expectedArgs = [], array $methodArgs = [])
+ protected function assertMethodArgumentsMatch(string $method, array $expectedArgs = [], array $methodArgs = []): void
{
foreach ($expectedArgs as $key => $constraint) {
$argNumber = $key + 1;
@@ -515,7 +569,7 @@ class LdapFake implements LdapInterface
PHPUnit::assertArrayHasKey(
$key,
$methodArgs,
- "LDAP method [$method] argument #{$argNumber} does not exist."
+ "LDAP method [$method] argument #$argNumber does not exist."
);
$constraint->evaluate(
diff --git a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Utilities.php b/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Utilities.php
deleted file mode 100644
index c4f5190d8..000000000
--- a/data/web/inc/lib/vendor/directorytree/ldaprecord/src/Utilities.php
+++ /dev/null
@@ -1,187 +0,0 @@
- $value) {
- $dn[$rdn] = static::unescape($value);
- }
-
- return $dn;
- }
-
- /**
- * Un-escapes a hexadecimal string into its original string representation.
- *
- * @param string $value
- * @return string
- */
- public static function unescape($value)
- {
- return preg_replace_callback('/\\\([0-9A-Fa-f]{2})/', function ($matches) {
- return chr(hexdec($matches[1]));
- }, $value);
- }
-
- /**
- * Convert a binary SID to a string SID.
- *
- * @author Chad Sikorra
- *
- * @see https://github.com/ChadSikorra
- * @see https://stackoverflow.com/questions/39533560/php-ldap-get-user-sid
- *
- * @param string $value The Binary SID
- * @return string|null
- */
- public static function binarySidToString($value)
- {
- // Revision - 8bit unsigned int (C1)
- // Count - 8bit unsigned int (C1)
- // 2 null bytes
- // ID - 32bit unsigned long, big-endian order
- $sid = @unpack('C1rev/C1count/x2/N1id', $value);
-
- if (! isset($sid['id']) || ! isset($sid['rev'])) {
- return;
- }
-
- $revisionLevel = $sid['rev'];
-
- $identifierAuthority = $sid['id'];
-
- $subs = isset($sid['count']) ? $sid['count'] : 0;
-
- $sidHex = $subs ? bin2hex($value) : '';
-
- $subAuthorities = [];
-
- // The sub-authorities depend on the count, so only get as
- // many as the count, regardless of data beyond it.
- for ($i = 0; $i < $subs; $i++) {
- $data = implode(array_reverse(
- str_split(
- substr($sidHex, 16 + ($i * 8), 8),
- 2
- )
- ));
-
- $subAuthorities[] = hexdec($data);
- }
-
- // Tack on the 'S-' and glue it all together...
- return 'S-'.$revisionLevel.'-'.$identifierAuthority.implode(
- preg_filter('/^/', '-', $subAuthorities)
- );
- }
-
- /**
- * Convert a binary GUID to a string GUID.
- *
- * @param string $binGuid
- * @return string|null
- */
- public static function binaryGuidToString($binGuid)
- {
- if (is_null($binGuid) || trim($binGuid) == '') {
- return;
- }
-
- $hex = unpack('H*hex', $binGuid)['hex'];
-
- $hex1 = substr($hex, -26, 2).substr($hex, -28, 2).substr($hex, -30, 2).substr($hex, -32, 2);
- $hex2 = substr($hex, -22, 2).substr($hex, -24, 2);
- $hex3 = substr($hex, -18, 2).substr($hex, -20, 2);
- $hex4 = substr($hex, -16, 4);
- $hex5 = substr($hex, -12, 12);
-
- return sprintf('%s-%s-%s-%s-%s', $hex1, $hex2, $hex3, $hex4, $hex5);
- }
-
- /**
- * Converts a string GUID to it's hex variant.
- *
- * @param string $string
- * @return string
- */
- public static function stringGuidToHex($string)
- {
- $hex = '\\'.substr($string, 6, 2).'\\'.substr($string, 4, 2).'\\'.substr($string, 2, 2).'\\'.substr($string, 0, 2);
- $hex = $hex.'\\'.substr($string, 11, 2).'\\'.substr($string, 9, 2);
- $hex = $hex.'\\'.substr($string, 16, 2).'\\'.substr($string, 14, 2);
- $hex = $hex.'\\'.substr($string, 19, 2).'\\'.substr($string, 21, 2);
- $hex = $hex.'\\'.substr($string, 24, 2).'\\'.substr($string, 26, 2).'\\'.substr($string, 28, 2).'\\'.substr($string, 30, 2).'\\'.substr($string, 32, 2).'\\'.substr($string, 34, 2);
-
- return $hex;
- }
-
- /**
- * Round a Windows timestamp down to seconds and remove
- * the seconds between 1601-01-01 and 1970-01-01.
- *
- * @param int $windowsTime
- * @return int
- */
- public static function convertWindowsTimeToUnixTime($windowsTime)
- {
- return (int) (round($windowsTime / 10000000) - 11644473600);
- }
-
- /**
- * Convert a Unix timestamp to Windows timestamp.
- *
- * @param int $unixTime
- * @return int
- */
- public static function convertUnixTimeToWindowsTime($unixTime)
- {
- return ($unixTime + 11644473600) * 10000000;
- }
-
- /**
- * Validates that the inserted string is an object SID.
- *
- * @param string $sid
- * @return bool
- */
- public static function isValidSid($sid)
- {
- return (bool) preg_match("/^S-\d(-\d{1,10}){1,16}$/i", (string) $sid);
- }
-
- /**
- * Validates that the inserted string is an object GUID.
- *
- * @param string $guid
- * @return bool
- */
- public static function isValidGuid($guid)
- {
- return (bool) preg_match('/^([0-9a-fA-F]){8}(-([0-9a-fA-F]){4}){3}-([0-9a-fA-F]){12}$/', (string) $guid);
- }
-}
diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Arr.php b/data/web/inc/lib/vendor/illuminate/collections/Arr.php
similarity index 88%
rename from data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Arr.php
rename to data/web/inc/lib/vendor/illuminate/collections/Arr.php
index f3a4b042e..d83cf5f73 100644
--- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Arr.php
+++ b/data/web/inc/lib/vendor/illuminate/collections/Arr.php
@@ -1,10 +1,10 @@
$value) {
@@ -214,7 +216,7 @@ class Arr
* @param mixed $default
* @return mixed
*/
- public static function last($array, callable $callback = null, $default = null)
+ public static function last($array, ?callable $callback = null, $default = null)
{
if (is_null($callback)) {
return empty($array) ? value($default) : end($array);
@@ -223,6 +225,22 @@ class Arr
return static::first(array_reverse($array, true), $callback, $default);
}
+ /**
+ * Take the first or last {$limit} items from an array.
+ *
+ * @param array $array
+ * @param int $limit
+ * @return array
+ */
+ public static function take($array, $limit)
+ {
+ if ($limit < 0) {
+ return array_slice($array, $limit, abs($limit));
+ }
+
+ return array_slice($array, 0, $limit);
+ }
+
/**
* Flatten a multi-dimensional array into a single level.
*
@@ -410,9 +428,7 @@ class Arr
*/
public static function isAssoc(array $array)
{
- $keys = array_keys($array);
-
- return array_keys($keys) !== $keys;
+ return ! array_is_list($array);
}
/**
@@ -425,7 +441,7 @@ class Arr
*/
public static function isList($array)
{
- return ! self::isAssoc($array);
+ return array_is_list($array);
}
/**
@@ -476,9 +492,7 @@ class Arr
*/
public static function prependKeysWith($array, $prependWith)
{
- return Collection::make($array)->mapWithKeys(function ($item, $key) use ($prependWith) {
- return [$prependWith.$key => $item];
- })->all();
+ return static::mapWithKeys($array, fn ($item, $key) => [$prependWith.$key => $item]);
}
/**
@@ -493,6 +507,32 @@ class Arr
return array_intersect_key($array, array_flip((array) $keys));
}
+ /**
+ * Select an array of values from an array.
+ *
+ * @param array $array
+ * @param array|string $keys
+ * @return array
+ */
+ public static function select($array, $keys)
+ {
+ $keys = static::wrap($keys);
+
+ return static::map($array, function ($item) use ($keys) {
+ $result = [];
+
+ foreach ($keys as $key) {
+ if (Arr::accessible($item) && Arr::exists($item, $key)) {
+ $result[$key] = $item[$key];
+ } elseif (is_object($item) && isset($item->{$key})) {
+ $result[$key] = $item->{$key};
+ }
+ }
+
+ return $result;
+ });
+ }
+
/**
* Pluck an array of values from an array.
*
@@ -565,6 +605,35 @@ class Arr
return array_combine($keys, $items);
}
+ /**
+ * Run an associative map over each of the items.
+ *
+ * The callback should return an associative array with a single key/value pair.
+ *
+ * @template TKey
+ * @template TValue
+ * @template TMapWithKeysKey of array-key
+ * @template TMapWithKeysValue
+ *
+ * @param array $array
+ * @param callable(TValue, TKey): array $callback
+ * @return array
+ */
+ public static function mapWithKeys(array $array, callable $callback)
+ {
+ $result = [];
+
+ foreach ($array as $key => $value) {
+ $assoc = $callback($value, $key);
+
+ foreach ($assoc as $mapKey => $mapValue) {
+ $result[$mapKey] = $mapValue;
+ }
+ }
+
+ return $result;
+ }
+
/**
* Push an item onto the beginning of an array.
*
@@ -759,7 +828,7 @@ class Arr
}
}
- if (static::isAssoc($array)) {
+ if (! array_is_list($array)) {
$descending
? krsort($array, $options)
: ksort($array, $options);
@@ -772,6 +841,18 @@ class Arr
return $array;
}
+ /**
+ * Recursively sort an array by keys and values in descending order.
+ *
+ * @param array $array
+ * @param int $options
+ * @return array
+ */
+ public static function sortRecursiveDesc($array, $options = SORT_REGULAR)
+ {
+ return static::sortRecursive($array, $options, true);
+ }
+
/**
* Conditionally compile classes from an array into a CSS class list.
*
diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Collection.php b/data/web/inc/lib/vendor/illuminate/collections/Collection.php
similarity index 86%
rename from data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Collection.php
rename to data/web/inc/lib/vendor/illuminate/collections/Collection.php
index e705ee0d0..2f0c768f1 100644
--- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Collection.php
+++ b/data/web/inc/lib/vendor/illuminate/collections/Collection.php
@@ -1,26 +1,28 @@
- * @implements \Tightenco\Collect\Support\Enumerable
+ * @implements \Illuminate\Support\Enumerable
*/
class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerable
{
/**
- * @use \Tightenco\Collect\Support\Traits\EnumeratesValues
+ * @use \Illuminate\Support\Traits\EnumeratesValues
*/
use EnumeratesValues, Macroable;
@@ -34,7 +36,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Create a new collection.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|null $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $items
* @return void
*/
public function __construct($items = [])
@@ -67,7 +69,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Get a lazy collection for the items in this collection.
*
- * @return \Tightenco\Collect\Support\LazyCollection
+ * @return \Illuminate\Support\LazyCollection
*/
public function lazy()
{
@@ -220,7 +222,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
* @template TCrossJoinKey
* @template TCrossJoinValue
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$lists
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$lists
* @return static>
*/
public function crossJoin(...$lists)
@@ -233,7 +235,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Get the items in the collection that are not present in the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function diff($items)
@@ -244,7 +246,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Get the items in the collection that are not present in the given items, using the callback.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @param callable(TValue, TValue): int $callback
* @return static
*/
@@ -256,7 +258,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Get the items in the collection whose keys and values are not present in the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function diffAssoc($items)
@@ -267,7 +269,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Get the items in the collection whose keys and values are not present in the given items, using the callback.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @param callable(TKey, TKey): int $callback
* @return static
*/
@@ -279,7 +281,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Get the items in the collection whose keys are not present in the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function diffKeys($items)
@@ -290,7 +292,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Get the items in the collection whose keys are not present in the given items, using the callback.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @param callable(TKey, TKey): int $callback
* @return static
*/
@@ -356,11 +358,15 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Get all items except for those with the specified keys.
*
- * @param \Tightenco\Collect\Support\Enumerable|array $keys
+ * @param \Illuminate\Support\Enumerable|array|string $keys
* @return static
*/
public function except($keys)
{
+ if (is_null($keys)) {
+ return new static($this->items);
+ }
+
if ($keys instanceof Enumerable) {
$keys = $keys->all();
} elseif (! is_array($keys)) {
@@ -373,10 +379,10 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Run a filter over each of the items.
*
- * @param (callable(TValue, TKey): bool)|null $callback
+ * @param (callable(TValue, TKey): bool)|null $callback
* @return static
*/
- public function filter(callable $callback = null)
+ public function filter(?callable $callback = null)
{
if ($callback) {
return new static(Arr::where($this->items, $callback));
@@ -394,7 +400,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
* @param TFirstDefault|(\Closure(): TFirstDefault) $default
* @return TValue|TFirstDefault
*/
- public function first(callable $callback = null, $default = null)
+ public function first(?callable $callback = null, $default = null)
{
return Arr::first($this->items, $callback, $default);
}
@@ -423,12 +429,13 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Remove an item from the collection by key.
*
- * @param TKey|array $keys
+ * \Illuminate\Contracts\Support\Arrayable|iterable|TKey $keys
+ *
* @return $this
*/
public function forget($keys)
{
- foreach ((array) $keys as $key) {
+ foreach ($this->getArrayableItems($keys) as $key) {
$this->offsetUnset($key);
}
@@ -456,9 +463,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Get an item from the collection by key or add it to collection if it does not exist.
*
+ * @template TGetOrPutValue
+ *
* @param mixed $key
- * @param mixed $value
- * @return mixed
+ * @param TGetOrPutValue|(\Closure(): TGetOrPutValue) $value
+ * @return TValue|TGetOrPutValue
*/
public function getOrPut($key, $value)
{
@@ -500,6 +509,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
foreach ($groupKeys as $groupKey) {
$groupKey = match (true) {
is_bool($groupKey) => (int) $groupKey,
+ $groupKey instanceof \BackedEnum => $groupKey->value,
$groupKey instanceof \Stringable => (string) $groupKey,
default => $groupKey,
};
@@ -603,7 +613,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
$first = $this->first();
- if (is_array($first) || (is_object($first) && ! $first instanceof \Illuminate\Support\Stringable)) {
+ if (is_array($first) || (is_object($first) && ! $first instanceof Stringable)) {
return implode($glue ?? '', $this->pluck($value)->all());
}
@@ -613,7 +623,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Intersect the collection with the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function intersect($items)
@@ -624,7 +634,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Intersect the collection with the given items, using the callback.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @param callable(TValue, TValue): int $callback
* @return static
*/
@@ -636,7 +646,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Intersect the collection with the given items with additional index check.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function intersectAssoc($items)
@@ -647,7 +657,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Intersect the collection with the given items with additional index check, using the callback.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @param callable(TValue, TValue): int $callback
* @return static
*/
@@ -659,7 +669,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Intersect the collection with the given items by key.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function intersectByKeys($items)
@@ -738,7 +748,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
* @param TLastDefault|(\Closure(): TLastDefault) $default
* @return TValue|TLastDefault
*/
- public function last(callable $callback = null, $default = null)
+ public function last(?callable $callback = null, $default = null)
{
return Arr::last($this->items, $callback, $default);
}
@@ -813,23 +823,13 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
*/
public function mapWithKeys(callable $callback)
{
- $result = [];
-
- foreach ($this->items as $key => $value) {
- $assoc = $callback($value, $key);
-
- foreach ($assoc as $mapKey => $mapValue) {
- $result[$mapKey] = $mapValue;
- }
- }
-
- return new static($result);
+ return new static(Arr::mapWithKeys($this->items, $callback));
}
/**
* Merge the collection with the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function merge($items)
@@ -842,7 +842,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
*
* @template TMergeRecursiveValue
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function mergeRecursive($items)
@@ -855,7 +855,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
*
* @template TCombineValue
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $values
* @return static
*/
public function combine($values)
@@ -866,7 +866,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Union the collection with the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function union($items)
@@ -901,7 +901,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Get the items with the specified keys.
*
- * @param \Tightenco\Collect\Support\Enumerable|array|string|null $keys
+ * @param \Illuminate\Support\Enumerable|array|string|null $keys
* @return static
*/
public function only($keys)
@@ -919,6 +919,27 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
return new static(Arr::only($this->items, $keys));
}
+ /**
+ * Select specific values from the items within the collection.
+ *
+ * @param \Illuminate\Support\Enumerable|array|string|null $keys
+ * @return static
+ */
+ public function select($keys)
+ {
+ if (is_null($keys)) {
+ return new static($this->items);
+ }
+
+ if ($keys instanceof Enumerable) {
+ $keys = $keys->all();
+ }
+
+ $keys = is_array($keys) ? $keys : func_get_args();
+
+ return new static(Arr::select($this->items, $keys));
+ }
+
/**
* Get and remove the last N items from the collection.
*
@@ -978,8 +999,11 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Push all of the given items onto the collection.
*
- * @param iterable $source
- * @return static
+ * @template TConcatKey of array-key
+ * @template TConcatValue
+ *
+ * @param iterable $source
+ * @return static
*/
public function concat($source)
{
@@ -1024,27 +1048,28 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
* Get one or a specified number of items randomly from the collection.
*
* @param (callable(self): int)|int|null $number
+ * @param bool $preserveKeys
* @return static|TValue
*
* @throws \InvalidArgumentException
*/
- public function random($number = null)
+ public function random($number = null, $preserveKeys = false)
{
if (is_null($number)) {
return Arr::random($this->items);
}
if (is_callable($number)) {
- return new static(Arr::random($this->items, $number($this)));
+ return new static(Arr::random($this->items, $number($this), $preserveKeys));
}
- return new static(Arr::random($this->items, $number));
+ return new static(Arr::random($this->items, $number, $preserveKeys));
}
/**
* Replace the collection items with the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function replace($items)
@@ -1055,7 +1080,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Recursively replace the collection items with the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function replaceRecursive($items)
@@ -1078,7 +1103,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
*
* @param TValue|(callable(TValue,TKey): bool) $value
* @param bool $strict
- * @return TKey|bool
+ * @return TKey|false
*/
public function search($value, $strict = false)
{
@@ -1100,17 +1125,27 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
*
* @param int $count
* @return static|TValue|null
+ *
+ * @throws \InvalidArgumentException
*/
public function shift($count = 1)
{
- if ($count === 1) {
- return array_shift($this->items);
+ if ($count < 0) {
+ throw new InvalidArgumentException('Number of shifted items may not be less than zero.');
}
if ($this->isEmpty()) {
+ return null;
+ }
+
+ if ($count === 0) {
return new static;
}
+ if ($count === 1) {
+ return array_shift($this->items);
+ }
+
$results = [];
$collectionCount = $this->count();
@@ -1144,9 +1179,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
{
$chunks = floor(($this->count() - $size) / $step) + 1;
- return static::times($chunks, function ($number) use ($size, $step) {
- return $this->slice(($number - 1) * $step, $size);
- });
+ return static::times($chunks, fn ($number) => $this->slice(($number - 1) * $step, $size));
}
/**
@@ -1250,8 +1283,8 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
* @param mixed $value
* @return TValue
*
- * @throws \Tightenco\Collect\Support\ItemNotFoundException
- * @throws \Tightenco\Collect\Support\MultipleItemsFoundException
+ * @throws \Illuminate\Support\ItemNotFoundException
+ * @throws \Illuminate\Support\MultipleItemsFoundException
*/
public function sole($key = null, $operator = null, $value = null)
{
@@ -1282,7 +1315,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
* @param mixed $value
* @return TValue
*
- * @throws \Tightenco\Collect\Support\ItemNotFoundException
+ * @throws \Illuminate\Support\ItemNotFoundException
*/
public function firstOrFail($key = null, $operator = null, $value = null)
{
@@ -1378,7 +1411,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
{
if (is_array($callback) && ! is_callable($callback)) {
- return $this->sortByMany($callback);
+ return $this->sortByMany($callback, $options);
}
$results = [];
@@ -1409,13 +1442,14 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
* Sort the collection using multiple comparisons.
*
* @param array $comparisons
+ * @param int $options
* @return static
*/
- protected function sortByMany(array $comparisons = [])
+ protected function sortByMany(array $comparisons = [], int $options = SORT_REGULAR)
{
$items = $this->items;
- uasort($items, function ($a, $b) use ($comparisons) {
+ uasort($items, function ($a, $b) use ($comparisons, $options) {
foreach ($comparisons as $comparison) {
$comparison = Arr::wrap($comparison);
@@ -1433,7 +1467,21 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
$values = array_reverse($values);
}
- $result = $values[0] <=> $values[1];
+ if (($options & SORT_FLAG_CASE) === SORT_FLAG_CASE) {
+ if (($options & SORT_NATURAL) === SORT_NATURAL) {
+ $result = strnatcasecmp($values[0], $values[1]);
+ } else {
+ $result = strcasecmp($values[0], $values[1]);
+ }
+ } else {
+ $result = match ($options) {
+ SORT_NUMERIC => intval($values[0]) <=> intval($values[1]),
+ SORT_STRING => strcmp($values[0], $values[1]),
+ SORT_NATURAL => strnatcmp($values[0], $values[1]),
+ SORT_LOCALE_STRING => strcoll($values[0], $values[1]),
+ default => $values[0] <=> $values[1],
+ };
+ }
}
if ($result === 0) {
@@ -1456,6 +1504,16 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
*/
public function sortByDesc($callback, $options = SORT_REGULAR)
{
+ if (is_array($callback) && ! is_callable($callback)) {
+ foreach ($callback as $index => $key) {
+ $comparison = Arr::wrap($key);
+
+ $comparison[1] = 'desc';
+
+ $callback[$index] = $comparison;
+ }
+ }
+
return $this->sortBy($callback, $options, true);
}
@@ -1568,6 +1626,16 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
return $this;
}
+ /**
+ * Flatten a multi-dimensional associative array with dots.
+ *
+ * @return static
+ */
+ public function dot()
+ {
+ return new static(Arr::dot($this->all()));
+ }
+
/**
* Convert a flatten "dot" notation array into an expanded array.
*
@@ -1622,7 +1690,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
*
* @template TZipValue
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items
* @return static>
*/
public function zip($items)
@@ -1695,7 +1763,7 @@ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerabl
/**
* Get a base Support collection instance from this collection.
*
- * @return \Tightenco\Collect\Support\Collection
+ * @return \Illuminate\Support\Collection
*/
public function toBase()
{
diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Enumerable.php b/data/web/inc/lib/vendor/illuminate/collections/Enumerable.php
similarity index 88%
rename from data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Enumerable.php
rename to data/web/inc/lib/vendor/illuminate/collections/Enumerable.php
index 1f0db03ae..806a6923f 100644
--- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/Enumerable.php
+++ b/data/web/inc/lib/vendor/illuminate/collections/Enumerable.php
@@ -1,20 +1,21 @@
+ * @template-covariant TValue
+ *
+ * @extends \Illuminate\Contracts\Support\Arrayable
* @extends \IteratorAggregate
*/
interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, JsonSerializable
@@ -25,7 +26,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @template TMakeKey of array-key
* @template TMakeValue
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|null $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $items
* @return static
*/
public static function make($items = []);
@@ -37,7 +38,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param callable|null $callback
* @return static
*/
- public static function times($number, callable $callback = null);
+ public static function times($number, ?callable $callback = null);
/**
* Create a collection with the given range.
@@ -167,7 +168,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @template TCrossJoinKey
* @template TCrossJoinValue
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$lists
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$lists
* @return static>
*/
public function crossJoin(...$lists);
@@ -190,7 +191,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Get the items that are not present in the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function diff($items);
@@ -198,7 +199,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Get the items that are not present in the given items, using the callback.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @param callable(TValue, TValue): int $callback
* @return static
*/
@@ -207,7 +208,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Get the items whose keys and values are not present in the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function diffAssoc($items);
@@ -215,7 +216,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Get the items whose keys and values are not present in the given items, using the callback.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @param callable(TKey, TKey): int $callback
* @return static
*/
@@ -224,7 +225,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Get the items whose keys are not present in the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function diffKeys($items);
@@ -232,7 +233,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Get the items whose keys are not present in the given items, using the callback.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @param callable(TKey, TKey): int $callback
* @return static
*/
@@ -284,7 +285,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Get all items except for those with the specified keys.
*
- * @param \Tightenco\Collect\Support\Enumerable|array $keys
+ * @param \Illuminate\Support\Enumerable|array $keys
* @return static
*/
public function except($keys);
@@ -295,7 +296,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param (callable(TValue): bool)|null $callback
* @return static
*/
- public function filter(callable $callback = null);
+ public function filter(?callable $callback = null);
/**
* Apply the callback if the given "value" is (or resolves to) truthy.
@@ -307,7 +308,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param (callable($this): TWhenReturnType)|null $default
* @return $this|TWhenReturnType
*/
- public function when($value, callable $callback = null, callable $default = null);
+ public function when($value, ?callable $callback = null, ?callable $default = null);
/**
* Apply the callback if the collection is empty.
@@ -318,7 +319,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param (callable($this): TWhenEmptyReturnType)|null $default
* @return $this|TWhenEmptyReturnType
*/
- public function whenEmpty(callable $callback, callable $default = null);
+ public function whenEmpty(callable $callback, ?callable $default = null);
/**
* Apply the callback if the collection is not empty.
@@ -329,7 +330,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param (callable($this): TWhenNotEmptyReturnType)|null $default
* @return $this|TWhenNotEmptyReturnType
*/
- public function whenNotEmpty(callable $callback, callable $default = null);
+ public function whenNotEmpty(callable $callback, ?callable $default = null);
/**
* Apply the callback if the given "value" is (or resolves to) truthy.
@@ -341,7 +342,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param (callable($this): TUnlessReturnType)|null $default
* @return $this|TUnlessReturnType
*/
- public function unless($value, callable $callback, callable $default = null);
+ public function unless($value, callable $callback, ?callable $default = null);
/**
* Apply the callback unless the collection is empty.
@@ -352,7 +353,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param (callable($this): TUnlessEmptyReturnType)|null $default
* @return $this|TUnlessEmptyReturnType
*/
- public function unlessEmpty(callable $callback, callable $default = null);
+ public function unlessEmpty(callable $callback, ?callable $default = null);
/**
* Apply the callback unless the collection is not empty.
@@ -363,7 +364,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param (callable($this): TUnlessNotEmptyReturnType)|null $default
* @return $this|TUnlessNotEmptyReturnType
*/
- public function unlessNotEmpty(callable $callback, callable $default = null);
+ public function unlessNotEmpty(callable $callback, ?callable $default = null);
/**
* Filter items by the given key value pair.
@@ -404,7 +405,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* Filter items by the given key value pair.
*
* @param string $key
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $values
* @param bool $strict
* @return static
*/
@@ -414,7 +415,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* Filter items by the given key value pair using strict comparison.
*
* @param string $key
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $values
* @return static
*/
public function whereInStrict($key, $values);
@@ -423,7 +424,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* Filter items such that the value of the given key is between the given values.
*
* @param string $key
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $values
* @return static
*/
public function whereBetween($key, $values);
@@ -432,7 +433,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* Filter items such that the value of the given key is not between the given values.
*
* @param string $key
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $values
* @return static
*/
public function whereNotBetween($key, $values);
@@ -441,7 +442,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* Filter items by the given key value pair.
*
* @param string $key
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $values
* @param bool $strict
* @return static
*/
@@ -451,7 +452,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* Filter items by the given key value pair using strict comparison.
*
* @param string $key
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $values
* @return static
*/
public function whereNotInStrict($key, $values);
@@ -475,7 +476,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param TFirstDefault|(\Closure(): TFirstDefault) $default
* @return TValue|TFirstDefault
*/
- public function first(callable $callback = null, $default = null);
+ public function first(?callable $callback = null, $default = null);
/**
* Get the first item by the given key value pair.
@@ -549,7 +550,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Concatenate values of a given key as a string.
*
- * @param string $value
+ * @param callable|string $value
* @param string|null $glue
* @return string
*/
@@ -558,7 +559,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Intersect the collection with the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function intersect($items);
@@ -566,7 +567,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Intersect the collection with the given items by key.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function intersectByKeys($items);
@@ -617,7 +618,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param TLastDefault|(\Closure(): TLastDefault) $default
* @return TValue|TLastDefault
*/
- public function last(callable $callback = null, $default = null);
+ public function last(?callable $callback = null, $default = null);
/**
* Run a map over each of the items.
@@ -682,7 +683,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @template TFlatMapKey of array-key
* @template TFlatMapValue
*
- * @param callable(TValue, TKey): (\Tightenco\Collect\Support\Collection|array) $callback
+ * @param callable(TValue, TKey): (\Illuminate\Support\Collection|array) $callback
* @return static
*/
public function flatMap(callable $callback);
@@ -700,7 +701,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Merge the collection with the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function merge($items);
@@ -710,7 +711,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
*
* @template TMergeRecursiveValue
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function mergeRecursive($items);
@@ -720,7 +721,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
*
* @template TCombineValue
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $values
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $values
* @return static
*/
public function combine($values);
@@ -728,7 +729,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Union the collection with the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function union($items);
@@ -761,7 +762,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Get the items with the specified keys.
*
- * @param \Tightenco\Collect\Support\Enumerable|array|string $keys
+ * @param \Illuminate\Support\Enumerable|array|string $keys
* @return static
*/
public function only($keys);
@@ -788,8 +789,11 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Push all of the given items onto the collection.
*
- * @param iterable $source
- * @return static
+ * @template TConcatKey of array-key
+ * @template TConcatValue
+ *
+ * @param iterable $source
+ * @return static
*/
public function concat($source);
@@ -829,7 +833,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Replace the collection items with the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function replace($items);
@@ -837,7 +841,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Recursively replace the collection items with the given items.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable $items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable $items
* @return static
*/
public function replaceRecursive($items);
@@ -924,8 +928,8 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param mixed $value
* @return TValue
*
- * @throws \Tightenco\Collect\Support\ItemNotFoundException
- * @throws \Tightenco\Collect\Support\MultipleItemsFoundException
+ * @throws \Illuminate\Support\ItemNotFoundException
+ * @throws \Illuminate\Support\MultipleItemsFoundException
*/
public function sole($key = null, $operator = null, $value = null);
@@ -937,7 +941,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
* @param mixed $value
* @return TValue
*
- * @throws \Tightenco\Collect\Support\ItemNotFoundException
+ * @throws \Illuminate\Support\ItemNotFoundException
*/
public function firstOrFail($key = null, $operator = null, $value = null);
@@ -1078,8 +1082,10 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Pass the collection into a new class.
*
- * @param class-string $class
- * @return mixed
+ * @template TPipeIntoValue
+ *
+ * @param class-string $class
+ * @return TPipeIntoValue
*/
public function pipeInto($class);
@@ -1180,7 +1186,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
*
* @template TZipValue
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable ...$items
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items
* @return static>
*/
public function zip($items);
@@ -1188,7 +1194,7 @@ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable,
/**
* Collect the values into a collection.
*
- * @return \Tightenco\Collect\Support\Collection
+ * @return \Illuminate\Support\Collection
*/
public function collect();
diff --git a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/HigherOrderCollectionProxy.php b/data/web/inc/lib/vendor/illuminate/collections/HigherOrderCollectionProxy.php
similarity index 86%
rename from data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/HigherOrderCollectionProxy.php
rename to data/web/inc/lib/vendor/illuminate/collections/HigherOrderCollectionProxy.php
index 01ac43f96..106356c3a 100644
--- a/data/web/inc/lib/vendor/tightenco/collect/src/Collect/Support/HigherOrderCollectionProxy.php
+++ b/data/web/inc/lib/vendor/illuminate/collections/HigherOrderCollectionProxy.php
@@ -1,16 +1,16 @@
+ * @template-covariant TValue
+ *
+ * @implements \Illuminate\Support\Enumerable
*/
class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
{
/**
- * @use \Tightenco\Collect\Support\Traits\EnumeratesValues
+ * @use \Illuminate\Support\Traits\EnumeratesValues
*/
use EnumeratesValues, Macroable;
@@ -37,7 +38,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
/**
* Create a new lazy collection instance.
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $source
+ * @param \Illuminate\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $source
* @return void
*/
public function __construct($source = null)
@@ -61,7 +62,7 @@ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable
* @template TMakeKey of array-key
* @template TMakeValue
*
- * @param \Tightenco\Collect\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array