- Some more bugfixes and added the OrganizationalUnit entity

This commit is contained in:
Dave M. 2021-03-09 15:26:15 +00:00
parent 8d1a310921
commit fa806e8e0d
11 changed files with 173 additions and 158 deletions

View File

@ -149,8 +149,8 @@ class Ldap implements \Ulmus\Adapter\AdapterInterface {
case static::IDENTIFIER_DN:
return ldap_escape($segment, $ignore, LDAP_ESCAPE_DN);
case static::IDENTIFIER_FIELD:
case static::IDENTIFIER_FILTER:
case static::IDENTIFIER_FIELD:
return ldap_escape($segment, $ignore, LDAP_ESCAPE_FILTER);
default:

View File

@ -0,0 +1,15 @@
<?php
namespace Ulmus\Ldap\Annotation\Classes;
class ObjectClass implements \Ulmus\Annotation\Annotation {
public string $type;
public function __construct($type = null)
{
if ( $type !== null ) {
$this->type = $type;
}
}
}

View File

@ -64,9 +64,9 @@ class LdapObject {
public function select(array $filter, array $fields = [])
{
static::$dump && call_user_func_array(static::$dump, [ $sql, $parameters ]);
static::$dump && call_user_func_array(static::$dump, [ $filter, $fields ]);
$this->search = ldap_search($this->connection, $this->dn, $filter['filters'], $filter['fields'], 0, $filter['limit'] ?? -1);
$this->search = ldap_search($this->connection, $this->dn, $filter['filters'], $filter['fields'], 0, 0);
$this->rowCount = $this->bufferedRows = ldap_count_entries($this->connection, $this->search);
@ -75,18 +75,20 @@ class LdapObject {
public function fetch() /* : bool|array */
{
static $result;
if (! $this->search ) {
throw new \Exception('Impossible to fetch from LdapObject from which select() was not called first.');
}
if ( ! $this->bufferedRows ) {
return false;
return $result = false;
}
if ( $this->rowCount === $this->bufferedRows ) {
$result = ldap_first_entry($this->connection, $this->search);
}
else {
$result = ldap_next_entry($this->connection, $this->search);
$result = ldap_next_entry($this->connection, $result);
}
if ($result) {
@ -119,56 +121,4 @@ class LdapObject {
}
public function closeCursor() : void {}
public function runQuery(string $sql, array $parameters = [])
{
static::$dump && call_user_func_array(static::$dump, [ $sql, $parameters ]);
try {
if (false !== ( $statement = $this->prepare($sql) )) {
return $this->execute($statement, $parameters, true);
}
}
catch (\PDOException $e) {
throw new \PdoException($e->getMessage() . " `$sql` with data:" . json_encode($parameters));
}
return null;
}
public function execute(PDOStatement $statement, array $parameters = [], bool $commit = true)
{
try {
if ( ! $this->inTransaction() ) {
$this->beginTransaction();
}
if (empty($parameters) ? $statement->execute() : $statement->execute($parameters)) {
$statement->lastInsertId = $this->lastInsertId();
if ( $commit ) {
$this->commit();
}
return $statement;
}
else {
throw new \PDOException($statement->errorCode() . " - " . json_encode($statement->errorInfo()));
}
}
catch (\PDOException $e) {
$this->rollback();
throw $e;
}
catch (\Throwable $e) {
if ( function_exists("debogueur") ) {
debogueur($statement, $parameters, $commit);
}
throw $e;
}
return null;
}
}

View File

@ -14,7 +14,7 @@ class ConnectionAdapter extends \Ulmus\ConnectionAdapter
protected AdapterInterface $adapter;
public $connection;
private $connection;
public function resolveConfiguration() : void
{

View File

@ -1,10 +0,0 @@
<?php
namespace Ulmus\Ldap\Entity;
class Container
{
}

View File

@ -0,0 +1,53 @@
<?php
namespace Ulmus\Ldap\Entity;
use Ulmus\Ldap\Entity\Field\{ Datetime };
/**
* @ObjectClass('organizationalUnit')
*/
class OrganizationalUnit
{
use \Ulmus\Ldap\EntityTrait;
/**
* @Id
*/
public string $ou;
/**
* @Field
*/
public string $description;
/**
* @Field('name' => "st")
*/
public string $state;
/**
* @Field('name' => 'physicalDeliveryOfficeName')
*/
public string $officeName;
/**
* @Field('name' => 'postalAddress')
*/
public string $address;
/**
* @Field
*/
public string $postalCode;
/**
* @Field
*/
public string $telephoneNumber;
public function __toString() : string
{
return $this->ou;
}
}

View File

@ -4,6 +4,9 @@ namespace Ulmus\Ldap\Entity;
use Ulmus\Ldap\Entity\Field\{ Datetime };
/**
* @ObjectClass('user')
*/
class User
{
use \Ulmus\Ldap\EntityTrait;
@ -125,6 +128,6 @@ class User
public function __toString() : string
{
return $this->displayName;
return implode(' ', array_filter([ $this->firstname ?? "", $this->lastname ?? "" ])) ?: $this->displayName;
}
}

View File

@ -4,41 +4,26 @@ namespace Ulmus\Ldap;
use Ulmus\{ Ulmus, EventTrait, Query, Common\EntityResolver, Common\EntityField };
use Ulmus\Annotation\Classes\{ Method, Table, Collation, };
use Ulmus\Annotation\Property\{ Field, Filter, Relation, OrderBy, Where, Join, Virtual, On, WithJoin, };
use Ulmus\Annotation\Property\Field\{ Id, ForeignKey, CreatedAt, UpdatedAt, Datetime as DateTime, Date, Time, Bigint, Tinyint, Text, Mediumtext, Longtext, };
use Ulmus\Annotation\Property\Relation\{ Ignore as RelationIgnore };
use Ulmus\Ldap\Annotation\Classes\{ ObjectClass, };
trait EntityTrait {
use \Ulmus\EntityTrait;
/**
* @Ignore
*/
public static function resolveEntity() : EntityResolver
{
return Ulmus::resolveEntity(static::class);
}
/**
* @Ignore
*/
public static function repository(string $alias = Repository::DEFAULT_ALIAS) : Repository
{
return new Repository(static::class, $alias);
}
/**
* @Ignore
*/
public static function field($name, ? string $alias = null) : EntityField
{
return new EntityField(static::class, $name, $alias ?: Repository::DEFAULT_ALIAS, Ulmus::resolveEntity(static::class));
}
/**
* @Ignore
*/
public static function fields(array $fields, ? string $alias = null) : string
{
return implode(', ', array_map(function($item) use ($alias){

View File

@ -61,8 +61,10 @@ class Filter extends Fragment {
}
}
$render = implode('', $stack);
return [
'filters' => implode('', $stack)
'filters' => count($stack) > 1 ? $latest->applyOperator($render) : $render
];
}
@ -91,24 +93,22 @@ class Filter extends Fragment {
{
$value = $this->value();
return $this->content ?: $this->content = implode("", array_filter([
"(",
$this->condition,
$this->not ? Filter::CONDITION_NOT : "",
$return = $this->content ?: $this->content = implode("", array_filter([
$this->field,
$this->operator(),
$value,
")",
$this->operator === Filter::OPERATOR_LIKE ? "*{$this->value}*" : $value,
]));
return $this->applyOperator($return, "");
}
protected function operator() : string
{
if ( is_array($this->value) ) {
return (in_array($this->operator, [ '!=', '<>' ]) ? Filter::CONDITION_NOT . " " : "") . Filter::COMPARISON_IN;
}
return $this->operator === Filter::OPERATOR_LIKE ? "=" : $this->operator;
}
return $this->operator;
public function applyOperator(string $content, string $operator = Filter::CONDITION_AND) {
return "($operator$content)";
}
protected function value()

View File

@ -2,12 +2,15 @@
namespace Ulmus\Ldap;
use Ulmus\Ulmus;
use Ulmus\Ldap\Annotation\Classes\ObjectClass;
use Ulmus\{EntityCollection, Ulmus, SearchRequest, Query};
use Ulmus\Annotation\Property\{ Where, Having, Relation, Join, WithJoin, Relation\Ignore as RelationIgnore };
use Ulmus\Common\EntityResolver;
class Repository extends \Ulmus\Repository
{
use Repository\ConditionTrait;
const DEFAULT_ALIAS = "";
public array $events = [];
@ -24,7 +27,38 @@ class Repository extends \Ulmus\Repository
$this->select(array_keys($this->entityResolver->fieldList(EntityResolver::KEY_COLUMN_NAME)));
}
if ( null !== $objectClass = $this->entityResolver->getAnnotationFromClassname( ObjectClass::class ) ) {
$this->where('objectclass', $objectClass->type);
}
return $this;
}
public function escapeValue(string $identifier) : string
{
return $this->adapter->adapter()->escapeIdentifier($identifier, Adapter\Ldap::IDENTIFIER_FILTER);
}
public function filterServerRequest(SearchRequest\SearchRequestInterface $searchRequest, bool $count = true) : self
{
if ($count) {
$this->eventRegister(new class($searchRequest) implements \Ulmus\Event\Repository\CollectionFromQueryInterface {
protected SearchRequest\SearchRequestInterface $searchRequest;
public function __construct(SearchRequest\SearchRequestInterface $searchRequest) {
$this->searchRequest = $searchRequest;
}
public function execute(EntityCollection $collection) : EntityCollection
{
$this->searchRequest->count = $collection->count();
return $collection;
}
});
}
return parent::filterServerRequest($searchRequest, false);
}
}

View File

@ -4,35 +4,20 @@ namespace Ulmus\Ldap\Repository;
use Ulmus\Query;
use Ulmus\Repository;
use Ulmus\Ldap\Query\Filter;
trait ConditionTrait
{
public function open(string $condition = Query\Where::CONDITION_AND) : self
public function where($field, $value, string $operator = Query\Where::OPERATOR_EQUAL, $condition = Query\Where::CONDITION_AND) : Repository
{
$this->queryBuilder->open($condition);
$this->queryBuilder->where($this->escapeField($field), $this->escapeValue($value), $operator, $condition);
return $this;
}
public function orOpen() : self
{
return $this->open(Query\Where::CONDITION_OR);
}
public function close() : self
{
$this->queryBuilder->close();
return $this;
}
public function where($field, $value, string $operator = Query\Where::OPERATOR_EQUAL, $condition = Query\Where::CONDITION_AND) : self
{
$this->queryBuilder->where($field, $value, $operator, $condition);
return $this;
}
public function wheres(array $fieldValues, string $operator = Query\Where::OPERATOR_EQUAL) : self
public function wheres(array $fieldValues, string $operator = Query\Where::OPERATOR_EQUAL) : Repository
{
foreach($fieldValues as $field => $value) {
$this->where($field, $value, $operator);
@ -41,108 +26,108 @@ trait ConditionTrait
return $this;
}
public function and($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
public function and($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : Repository
{
return $this->where($field, $value, $operator);
}
public function or($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
public function or($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : Repository
{
$this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_OR);
$this->queryBuilder->where($this->escapeField($field), $this->escapeValue($value), $operator, Query\Where::CONDITION_OR);
return $this;
}
public function notWhere($field, $value, string $operator = Query\Where::OPERATOR_NOT_EQUAL) : self
public function notWhere($field, $value, string $operator = Query\Where::OPERATOR_NOT_EQUAL) : Repository
{
$this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_AND, true);
$this->queryBuilder->where($this->escapeField($field), $this->escapeValue($value), $operator, Query\Where::CONDITION_AND, true);
return $this;
}
public function orNot($field, $value, string $operator = Query\Where::OPERATOR_NOT_EQUAL) : self
public function orNot($field, $value, string $operator = Query\Where::OPERATOR_NOT_EQUAL) : Repository
{
$this->queryBuilder->notWhere($field, $value, $operator, Query\Where::CONDITION_OR, true);
$this->queryBuilder->notWhere($this->escapeField($field), $this->escapeValue($value), $operator, Query\Where::CONDITION_OR, true);
return $this;
}
public function having($field, $value, string $operator = Query\Where::OPERATOR_EQUAL, $condition = Query\Where::CONDITION_AND) : self
public function having($field, $value, string $operator = Query\Where::OPERATOR_EQUAL, $condition = Query\Where::CONDITION_AND) : Repository
{
$this->queryBuilder->having($field, $value, $operator, $condition);
$this->where($field, $value, $operator, $condition);
return $this;
}
public function orHaving($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
public function orHaving($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : Repository
{
$this->queryBuilder->having($field, $value, $operator, Query\Where::CONDITION_OR);
$this->orWhere($field, $value, $operator, Query\Where::CONDITION_OR);
return $this;
}
public function notHaving($field, $value, string $operator = Query\Where::OPERATOR_NOT_EQUAL) : self
public function notHaving($field, $value, string $operator = Query\Where::OPERATOR_NOT_EQUAL) : Repository
{
$this->queryBuilder->having($field, $value, $operator, Query\Where::CONDITION_AND, true);
$this->queryBuilder->where($this->escapeField($field), $this->escapeValue($value), $operator, Query\Where::CONDITION_AND, true);
return $this;
}
public function orNotHaving($field, $value) : self
public function orNotHaving($field, $value) : Repository
{
$this->queryBuilder->having($field, $value, Query\Where::OPERATOR_NOT_EQUAL, Query\Where::CONDITION_OR, true);
$this->queryBuilder->where($this->escapeField($field), $this->escapeValue($value), Query\Where::OPERATOR_NOT_EQUAL, Query\Where::CONDITION_OR, true);
return $this;
}
public function in($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
public function in($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : Repository
{
$this->queryBuilder->where($field, $value, $operator);
// $this->queryBuilder->where($field, $value, $operator);
return $this;
}
public function orIn($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : self
public function orIn($field, $value, string $operator = Query\Where::OPERATOR_EQUAL) : Repository
{
$this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_OR);
// $this->queryBuilder->where($field, $value, $operator, Query\Where::CONDITION_OR);
return $this;
}
public function notIn($field, $value) : self
public function notIn($field, $value) : Repository
{
$this->queryBuilder->where($field, $value, Query\Where::OPERATOR_NOT_EQUAL);
// $this->queryBuilder->where($field, $value, Query\Where::OPERATOR_NOT_EQUAL);
return $this;
}
public function orNotIn($field, $value) : self
public function orNotIn($field, $value) : Repository
{
return $this->orNot($field, $value, Query\Where::OPERATOR_NOT_EQUAL, Query\Where::CONDITION_OR, true);
// return $this->orNot($field, $value, Query\Where::OPERATOR_NOT_EQUAL, Query\Where::CONDITION_OR, true);
}
public function like($field, $value) : self
public function like($field, $value) : Repository
{
$this->where($field, $value, Query\Where::OPERATOR_LIKE);
$this->where($field, $value, Filter::OPERATOR_LIKE);
return $this;
}
public function orLike($field, $value) : self
public function orLike($field, $value) : Repository
{
$this->or($field, $value, Query\Where::OPERATOR_LIKE);
$this->or($field, $value, Filter::OPERATOR_LIKE);
return $this;
}
public function notLike($field, $value) : self
public function notLike($field, $value) : Repository
{
$this->notWhere($field, $value, Query\Where::OPERATOR_LIKE);
$this->notWhere($field, $value, Filter::OPERATOR_LIKE);
return $this;
}
public function likes(array $fieldValues, string $condition = Query\Where::CONDITION_AND) : self
public function likes(array $fieldValues, string $condition = Query\Where::CONDITION_AND) : Repository
{
foreach($fieldValues as $field => $value) {
$this->like($field, $value);