- QueryFragmentInterface fixes

This commit is contained in:
Dave M. 2024-04-24 11:25:48 -04:00
parent ccd1eaef2b
commit 4b9a162696
5 changed files with 86 additions and 19 deletions

View File

@ -2,6 +2,7 @@
namespace Ulmus\Ldap\Common;
use http\Exception\InvalidArgumentException;
use function ldap_set_option, ldap_start_tls, ldap_bind, ldap_unbind, ldap_connect, ldap_close, ldap_get_entries, ldap_mod_replace, ldap_count_entries, ldap_errno, ldap_error;
class LdapObject {
@ -12,6 +13,8 @@ class LdapObject {
public $search;
protected string $host;
public int $rowCount = 0;
public int $bufferedRows = 0;
@ -22,6 +25,8 @@ class LdapObject {
public bool $binded = false;
public bool $deleteRecursively = true;
public function __destruct()
{
isset($this->connection) and ldap_close($this->connection);
@ -29,6 +34,8 @@ class LdapObject {
public function connect(string $host, string $baseDn) : bool
{
$this->host = $host;
$this->connection = ldap_connect("ldap://$host");
$this->dn = $baseDn;
@ -54,7 +61,12 @@ class LdapObject {
throw new \Exception("LdapObject is already binded with a user. Use the unbind() method to release it.");
}
$this->binded = ldap_bind($this->connection, $dn, $password);
try {
$this->binded = ldap_bind($this->connection, $dn, $password);
}
catch(\Throwable $ex) {
throw new \ErrorException(sprintf("%s [ using: %s on %s ]", $ex->getMessage(), $dn, $this->host ));
}
return $this->binded;
}
@ -82,7 +94,9 @@ class LdapObject {
{
static::$dump && call_user_func_array(static::$dump, [ $filter, $fields ]);
$this->search = ldap_search($this->connection, $this->dn, $filter['filters'], $filter['fields'] ?? [], 0, 0);
$this->search = @ldap_search($this->connection, $this->dn, $filter['filters'], $filter['fields'] ?? [], 0, $filter['limit'] ?? 0);
$this->throwLdapException();
$this->rowCount = $this->bufferedRows = ldap_count_entries($this->connection, $this->search);
@ -127,10 +141,10 @@ class LdapObject {
return false;
}
public function fetchAll()
{
return ldap_get_entries($this->connection, $result);
}
#public function fetchAll()
#{
# return ldap_get_entries($this->connection, $result);
#}
public function rowCount() : int
{
@ -187,9 +201,22 @@ class LdapObject {
return $this;
}
public function runDeleteQuery(array $filter, array $control)
public function runDeleteQuery(array $filter)
{
static::$dump && call_user_func_array(static::$dump, [ $filter, $dataset ]);
static::$dump && call_user_func_array(static::$dump, [ $filter ]);
if ( empty($filter['dn']) ) {
throw new InvalidArgumentException("A valid DN must be provided to run a 'delete' query on LDAP connector");
}
if ($this->deleteRecursively) {
$list = ldap_list($this->connection, $filter['dn'], "ObjectClass=*", [""]);
$info = ldap_get_entries($this->connection, $list);
for($i=0; $i < $info['count']; $i++){
$this->runDeleteQuery($info[$i]);
}
}
if ( false === ( $queryResult = ldap_delete($this->connection, $filter['dn']) ) ) {
$this->throwLdapException();
@ -202,7 +229,15 @@ class LdapObject {
protected function throwLdapException() : void
{
throw new \Exception(sprintf('LDAP error #%s `%s`', ldap_errno($this->connection), ldap_error($this->connection)));
$no = ldap_errno($this->connection);
switch($no) {
case 0: # Success
case 4: # Skipping 'Size limit exceeded' error
return;
}
throw new \Exception(sprintf('LDAP error #%s `%s`', $no, ldap_error($this->connection)));
}
public function closeCursor() : void {}

View File

@ -61,9 +61,12 @@ class User
#[Field]
public string $title;
##[Virtual]
##[Field(readonly:true)]
# public ? array $memberOf;
##[Field(readonly:true)]
#public ? array $proxyAddresses;
#[Field]
public int $userAccountControl;
@ -133,6 +136,12 @@ class User
#[Field(name: "lastLogon", readonly: true)]
public LdapDatetime $lastLogon;
#[Field(name: "whenCreated", readonly: true)]
public LdapDatetime $whenCreated;
#[Field(name: "whenChanged", readonly: true)]
public LdapDatetime $whenChanged;
public function __toString() : string
{
return implode(' ', array_filter([ $this->firstname ?? "", $this->lastname ?? "" ])) ?: ( $this->displayName ?? "" );
@ -145,4 +154,27 @@ class User
return $arr;
}
public function brokenMigration() : bool
{
if ( empty($this->targetAddress) ) {
foreach($this->proxyAddresses ?? [] as $proxy) {
if ( str_contains(strtolower($proxy), 'x500') ) {
return true;
}
}
}
return false;
}
public function migrated() : bool
{
return ! empty($this->targetAddress);
}
public function unmigrated() : bool
{
return empty($this->targetAddress) && empty($this->proxyAddresses);
}
}

View File

@ -4,7 +4,7 @@ namespace Ulmus\Ldap\Query;
class Set extends \Ulmus\Query\Set
{
public function render() /* : mixed */
public function render() : mixed
{
foreach($this->dataset as $key => $value) {
$this->queryBuilder->addParameter($value, $key);

View File

@ -4,7 +4,7 @@ namespace Ulmus\Ldap;
use Ulmus;
class QueryBuilder implements Ulmus\Query\QueryBuilderInterface
class QueryBuilder implements Ulmus\QueryBuilder\QueryBuilderInterface
{
public Query\Filter $where;
@ -195,14 +195,14 @@ class QueryBuilder implements Ulmus\Query\QueryBuilderInterface
return $this;
}
public function push(Ulmus\Query\Fragment $queryFragment) : self
public function push(Ulmus\Query\QueryFragmentInterface $queryFragment) : self
{
$this->queryStack[] = $queryFragment;
return $this;
}
public function pull(Ulmus\Query\Fragment $queryFragment) : self
public function pull(Ulmus\Query\QueryFragmentInterface $queryFragment) : self
{
return array_shift($this->queryStack);
}
@ -241,7 +241,7 @@ class QueryBuilder implements Ulmus\Query\QueryBuilderInterface
return null;
}
public function removeFragment(array|string|Ulmus\Query\Fragment|\Stringable $fragment) : void
public function removeFragment(array|string|Ulmus\Query\QueryFragmentInterface|\Stringable $fragment) : void
{
foreach($this->queryStack as $key => $item) {
if ( $item === $fragment ) {

View File

@ -91,9 +91,9 @@ class Repository extends \Ulmus\Repository
throw new \Exception("Your entity class `" . get_class($entity) . "` cannot match entity type of repository `{$this->entityClass}`");
}
$this->delete($entity->dn)->deleteAll()->rowCount();
$deleted = $this->delete($entity->dn)->deleteAll()->rowCount();
return false;
return $deleted > 0;
}
public function loadAllFromOU(string $ou) : EntityCollection