blob: e4e5329c14e28a9de73f5078da7c0b8a18559d6c [file] [log] [blame]
<?php
namespace Adldap\Query;
use Adldap\Models\Entry;
use Adldap\Models\Model;
use InvalidArgumentException;
use Adldap\Schemas\SchemaInterface;
use Adldap\Connections\ConnectionInterface;
class Processor
{
/**
* @var Builder
*/
protected $builder;
/**
* @var ConnectionInterface
*/
protected $connection;
/**
* @var SchemaInterface
*/
protected $schema;
/**
* Constructor.
*
* @param Builder $builder
*/
public function __construct(Builder $builder)
{
$this->builder = $builder;
$this->schema = $builder->getSchema();
$this->connection = $builder->getConnection();
}
/**
* Processes LDAP search results and constructs their model instances.
*
* @param array $entries The LDAP entries to process.
*
* @return Collection|array
*/
public function process($entries)
{
if ($this->builder->isRaw()) {
// If the builder is asking for a raw
// LDAP result, we can return here.
return $entries;
}
$models = [];
if (array_key_exists('count', $entries)) {
for ($i = 0; $i < $entries['count']; $i++) {
// We'll go through each entry and construct a new
// model instance with the raw LDAP attributes.
$models[] = $this->newLdapEntry($entries[$i]);
}
}
// If the query contains paginated results, we'll return them here.
if ($this->builder->isPaginated()) {
return $models;
}
// If the query is requested to be sorted, we'll perform
// that here and return the resulting collection.
if ($this->builder->isSorted()) {
return $this->processSort($models);
}
// Otherwise, we'll return a regular unsorted collection.
return $this->newCollection($models);
}
/**
* Processes paginated LDAP results.
*
* @param array $pages
* @param int $perPage
* @param int $currentPage
*
* @return Paginator
*/
public function processPaginated(array $pages = [], $perPage = 50, $currentPage = 0)
{
$models = [];
foreach ($pages as $entries) {
// Go through each page and process the results into an objects array.
$models = array_merge($models, $this->process($entries));
}
$models = $this->processSort($models)->toArray();
return $this->newPaginator($models, $perPage, $currentPage, count($pages));
}
/**
* Returns a new LDAP Entry instance.
*
* @param array $attributes
*
* @return Entry
*/
public function newLdapEntry(array $attributes = [])
{
$objectClass = $this->schema->objectClass();
// We need to ensure the record contains an object class to be able to
// determine its type. Otherwise, we create a default Entry model.
if (array_key_exists($objectClass, $attributes) && array_key_exists(0, $attributes[$objectClass])) {
// Retrieve all of the object classes from the LDAP
// entry and lowercase them for comparisons.
$classes = array_map('strtolower', $attributes[$objectClass]);
// Retrieve the model mapping.
$models = $this->schema->objectClassModelMap();
// Retrieve the object class mappings (with strtolower keys).
$mappings = array_map('strtolower', array_keys($models));
// Retrieve the model from the map using the entry's object class.
$map = array_intersect($mappings, $classes);
if (count($map) > 0) {
// Retrieve the model using the object class.
$model = $models[current($map)];
// Construct and return a new model.
return $this->newModel([], $model)
->setRawAttributes($attributes);
}
}
// A default entry model if the object class isn't found.
return $this->newModel()->setRawAttributes($attributes);
}
/**
* Creates a new model instance.
*
* @param array $attributes
* @param string|null $model
*
* @throws InvalidArgumentException
*
* @return mixed|Entry
*/
public function newModel($attributes = [], $model = null)
{
$model = (class_exists($model) ? $model : $this->schema->entryModel());
if (!is_subclass_of($model, $base = Model::class)) {
throw new InvalidArgumentException("The given model class '{$model}' must extend the base model class '{$base}'");
}
return new $model($attributes, $this->builder->newInstance());
}
/**
* Returns a new Paginator object instance.
*
* @param array $models
* @param int $perPage
* @param int $currentPage
* @param int $pages
*
* @return Paginator
*/
public function newPaginator(array $models = [], $perPage = 25, $currentPage = 0, $pages = 1)
{
return new Paginator($models, $perPage, $currentPage, $pages);
}
/**
* Returns a new collection instance.
*
* @param array $items
*
* @return Collection
*/
public function newCollection(array $items = [])
{
return new Collection($items);
}
/**
* Sorts LDAP search results.
*
* @param array $models
*
* @return Collection
*/
protected function processSort(array $models = [])
{
$field = $this->builder->getSortByField();
$flags = $this->builder->getSortByFlags();
$direction = $this->builder->getSortByDirection();
$desc = ($direction === 'desc' ? true : false);
return $this->newCollection($models)->sortBy($field, $flags, $desc);
}
}