From 4d20cd50cc4604cb3a6a1a32fea8853faf4c849b Mon Sep 17 00:00:00 2001 From: Dave Mc Nicoll Date: Wed, 13 Apr 2022 03:30:50 +0000 Subject: [PATCH] - A lot of small bugfixes done on this version --- src/Adapter/Ldap.php | 17 +++++++++-- src/Common/LdapObject.php | 50 +++++++++++++++++++++++++-------- src/Entity/User.php | 14 ++++++++-- src/EntityTrait.php | 7 ++++- src/Query/Delete.php | 17 +++++++++++ src/Query/Insert.php | 24 ++++++++++++++++ src/Query/Select.php | 4 --- src/Query/Set.php | 2 -- src/QueryBuilder.php | 28 +++++++++++++++++-- src/Repository.php | 59 +++++++++++++++++++++++++++++++++++---- 10 files changed, 189 insertions(+), 33 deletions(-) create mode 100644 src/Query/Delete.php create mode 100644 src/Query/Insert.php diff --git a/src/Adapter/Ldap.php b/src/Adapter/Ldap.php index f9c50f6..7ea7ebb 100644 --- a/src/Adapter/Ldap.php +++ b/src/Adapter/Ldap.php @@ -2,7 +2,7 @@ namespace Ulmus\Ldap\Adapter; -use Ulmus\{Common\PdoObject, Exception\AdapterConfigurationException, Ldap\Entity\User}; +use Ulmus\{Common\PdoObject, Exception\AdapterConfigurationException, Ldap\Entity\User, Ulmus}; use Ulmus\Ldap\Common\LdapObject; @@ -37,14 +37,14 @@ class Ldap implements \Ulmus\Adapter\AdapterInterface { public LdapObject $ldapObject; public function __construct( - ? string $host = null, + ? string/*|array*/ $host = null, ? string $baseDn = null, ? string $username = null, ? string $password = null, ? string $accountSuffix = null ) { if ($host) { - $this->hosts = [ $host ]; + $this->hosts = is_array($host) ? $host : [ $host ]; } if ($baseDn) { @@ -146,6 +146,17 @@ class Ldap implements \Ulmus\Adapter\AdapterInterface { ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7); } } + + + public function writableValue(/* mixed */ $value) /*: mixed*/ + { + switch (true) { + case is_object($value): + return Ulmus::convertObject($value); + } + + return $value; + } public function escapeIdentifier(string $segment, int $type, string $ignore = "") : string { diff --git a/src/Common/LdapObject.php b/src/Common/LdapObject.php index ebf2294..813d260 100644 --- a/src/Common/LdapObject.php +++ b/src/Common/LdapObject.php @@ -16,6 +16,8 @@ class LdapObject { public int $bufferedRows = 0; + public int $lastInsertId = 0; + public string $dn; public bool $binded = false; @@ -135,10 +137,44 @@ class LdapObject { return $this->rowCount; } + /** + * @deprecated + */ public function runQuery(array $filter, array $dataset) + { + throw new \Exception("Method runQuery() cannot be run on this connector"); + } + + public function runInsertQuery(array $filter, array $dataset) { static::$dump && call_user_func_array(static::$dump, [ $filter, $dataset ]); + $dn = $filter['dn'] ?? $this->dn; + + $combine = array_combine($filter['fields'], $dataset); + + if ( $combine['cn'] ?? false ) { + $dn = "cn={$combine['cn']}," . $dn; + } + + try { + if (false === ($queryResult = ldap_add($this->connection, $dn, $combine))) { + $this->throwLdapException(); + } + } + catch(\Throwable $e) { + $this->throwLdapException(); + } + + $this->rowCount = 1; + + return $this; + } + + public function runUpdateQuery(array $filter, array $dataset) + { + static::$dump && call_user_func_array(static::$dump, [ $filter, $dataset ]); + if ( false === ( $queryResult = ldap_mod_replace($this->connection, $filter['dn'], $dataset) ) ) { $this->throwLdapException(); } @@ -148,21 +184,11 @@ class LdapObject { return $this; } - public function runInsertQuery(array $filter, array $dataset) - { - return $this->runQuery($filter, $dataset); - } - - public function runUpdateQuery(array $filter, array $dataset) - { - return $this->runQuery($filter, $dataset); - } - - public function runDeleteQuery(array $filter, array $dataset) + public function runDeleteQuery(array $filter, array $control) { static::$dump && call_user_func_array(static::$dump, [ $filter, $dataset ]); - if ( false === ( $queryResult = ldap_mod_del($this->connection, $filter['dn'], $dataset) ) ) { + if ( false === ( $queryResult = ldap_delete($this->connection, $filter['dn']) ) ) { $this->throwLdapException(); } diff --git a/src/Entity/User.php b/src/Entity/User.php index 74a3522..8866852 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -46,6 +46,11 @@ class User */ public string $name; + /** + * @Field + */ + public string $canonicalName; + /** * @Field */ @@ -82,14 +87,14 @@ class User public string $title; /** - * @Field('readonly' => true) + * @Virtual */ public ? array $memberOf; /** * @Field */ - public string $userAccountControl; + public int $userAccountControl; /** * @Field @@ -191,6 +196,11 @@ class User */ public string $sid; + /** + * @Field + */ + public string $targetAddress; + /** * @Field('name' => "lastLogon", 'readonly' => true) */ diff --git a/src/EntityTrait.php b/src/EntityTrait.php index 14f952d..81f4547 100644 --- a/src/EntityTrait.php +++ b/src/EntityTrait.php @@ -10,7 +10,7 @@ trait EntityTrait { use \Ulmus\EntityTrait; /** - * @Id + * @Id('readonly' => true) */ public string $dn; @@ -19,6 +19,11 @@ trait EntityTrait { */ public string $cn; + /** + * @Field + */ + public array $objectClass; + public static function resolveEntity() : EntityResolver { return Ulmus::resolveEntity(static::class); diff --git a/src/Query/Delete.php b/src/Query/Delete.php new file mode 100644 index 0000000..51ed29b --- /dev/null +++ b/src/Query/Delete.php @@ -0,0 +1,17 @@ + $this->dn, + ]; + } +} diff --git a/src/Query/Insert.php b/src/Query/Insert.php new file mode 100644 index 0000000..fb8d770 --- /dev/null +++ b/src/Query/Insert.php @@ -0,0 +1,24 @@ +fields = $dataset; + + return $this; + } + + public function render() : array + { + return [ + 'fields' => $this->fields + ]; + } +} diff --git a/src/Query/Select.php b/src/Query/Select.php index 9fab5f5..0e084ec 100644 --- a/src/Query/Select.php +++ b/src/Query/Select.php @@ -4,10 +4,6 @@ namespace Ulmus\Ldap\Query; class Select extends \Ulmus\Query\Fragment { - public bool $distinct = false; - - public bool $union = false; - public ? int $top = null; protected array $fields = []; diff --git a/src/Query/Set.php b/src/Query/Set.php index a6abebf..abe4c78 100644 --- a/src/Query/Set.php +++ b/src/Query/Set.php @@ -1,9 +1,7 @@ getFragment(Query\Insert::class) ) { + $insert = new Query\Insert(); + $this->push($insert); + } + + $insert->set($dataset); + + return $this; + } + + public function values(array $dataset) : self + { + $this->addValues(array_values($dataset)); + + return $this; + } + public function set(array $dataset, ? array $escapedFields = null) : self { if ( null === ( $set = $this->getFragment(Query\Set::class) ) ) { @@ -72,12 +91,15 @@ class QueryBuilder implements Ulmus\Query\QueryBuilderInterface return $this; } - public function delete() : self + public function delete(string $dn) : self { - if ( ! $this->getFragment(Ulmus\Query\Delete::class) ) { - $this->push(new Ulmus\Query\Delete()); + if ( null === ( $delete = $this->getFragment(Query\Delete::class) ) ) { + $delete = new Query\Delete($this); + $this->push($delete); } + $delete->dn = $dn; + return $this; } diff --git a/src/Repository.php b/src/Repository.php index 16f80bd..09be466 100644 --- a/src/Repository.php +++ b/src/Repository.php @@ -38,13 +38,26 @@ class Repository extends \Ulmus\Repository return $this; } + protected function insertSqlQuery(array $dataset, bool $replace = false) : self + { + if ( null === $insert = $this->queryBuilder->getFragment(Query\Insert::class) ) { + $fields = array_map([ $this, 'escapeField' ] , array_keys($dataset)); + + $this->insert($fields, "", "", null); + } + + $this->values($dataset); + + return $this; + } + protected function updateSqlQuery(array $dataset) : self { $condition = array_pop($this->queryBuilder->where->conditionList); if ($condition[0] === 'dn') { if ( null === $this->queryBuilder->getFragment(Query\Update::class) ) { - $this->update($condition[1], "", ""); + $this->update($condition[1], "", null); } } else { @@ -56,6 +69,33 @@ class Repository extends \Ulmus\Repository return $this; } + protected function deleteSqlQuery() : self + { + /*$condition = array_pop($this->queryBuilder->where->conditionList); + + if ($condition[0] === 'dn') { + if ( null === $this->queryBuilder->getFragment(Query\Delete::class) ) { + $this->delete($condition[1], "", null); + } + } + else { + array_push($this->queryBuilder->where->conditionList, $condition); + } +*/ + return $this; + } + + public function destroy(object $entity) : bool + { + if ( ! $this->matchEntity($entity) ) { + throw new \Exception("Your entity class `" . get_class($entity) . "` cannot match entity type of repository `{$this->entityClass}`"); + } + + $this->delete($entity->dn)->deleteAll()->rowCount(); + + return false; + } + public function loadAllFromOU(string $ou) : EntityCollection { $dn = $this->adapter->connector()->dn; @@ -69,18 +109,25 @@ class Repository extends \Ulmus\Repository return $collection; } - public function update(string $dn, string $alias, ? string $schema) : self + public function insert(array $dataset, string $table, string $alias, ? string $schema, bool $replace = false) : self { - $this->queryBuilder->update($dn, "", ""); + $this->queryBuilder->insert($dataset); return $this; } - public function runDeleteQuery() /* : mixed */ + public function update(string $dn, string $alias, ? string $schema) : self { - $this->finalizeQuery(); + $this->queryBuilder->update($dn); - return Ulmus::runQuery($this->queryBuilder, $this->adapter); + return $this; + } + + public function delete(...$args) : self + { + $this->queryBuilder->delete($args[0]); + + return $this; } public function escapeValue($identifier) : string