blob: 83dfe7160da13bd2ad461aea537970436869cd5c [file] [log] [blame]
<?php
namespace LdapRecord\Models\Attributes;
use LdapRecord\EscapesValues;
use LdapRecord\Support\Arr;
class DistinguishedNameBuilder
{
use EscapesValues;
/**
* The components of the DN.
*
* @var array
*/
protected $components = [];
/**
* Whether to output the DN in reverse.
*
* @var bool
*/
protected $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());
}
/**
* Forward missing method calls onto the Distinguished Name object.
*
* @param string $method
* @param array $args
*
* @return mixed
*/
public function __call($method, $args)
{
return $this->get()->{$method}(...$args);
}
/**
* Get the distinguished name value.
*
* @return string
*/
public function __toString()
{
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)
{
array_unshift(
$this->components,
...$this->componentize($attribute, $value)
);
return $this;
}
/**
* Append an RDN onto the DN.
*
* @param string|array $attribute
* @param string|null $value
*
* @return $this
*/
public function append($attribute, $value = null)
{
array_push(
$this->components,
...$this->componentize($attribute, $value)
);
return $this;
}
/**
* Componentize the attribute and value.
*
* @param string|array $attribute
* @param string|null $value
*
* @return array
*/
protected function componentize($attribute, $value = null)
{
// Here we will make the assumption that an array of
// RDN's have been given if the value is null, and
// attempt to break them into their components.
if (is_null($value)) {
$attributes = Arr::wrap($attribute);
$components = array_map([$this, 'makeComponentizedArray'], $attributes);
} else {
$components = [[$attribute, $value]];
}
return array_map(function ($component) {
[$attribute, $value] = $component;
return $this->makeAppendableComponent($attribute, $value);
}, $components);
}
/**
* Make a componentized array by exploding the value if it's a string.
*
* @param string $value
*
* @return array
*/
protected function makeComponentizedArray($value)
{
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)
{
return [trim($attribute), $this->escape(trim($value))->dn()];
}
/**
* Pop an RDN off of the end of the DN.
*
* @param int $amount
* @param array $removed
*
* @return $this
*/
public function pop($amount = 1, &$removed = [])
{
$removed = array_map(function ($component) {
return 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 = [])
{
$removed = array_map(function ($component) {
return DistinguishedName::makeRdn($component);
}, array_splice($this->components, 0, $amount));
return $this;
}
/**
* Whether to output the DN in reverse.
*
* @return $this
*/
public function reverse()
{
$this->reverse = true;
return $this;
}
/**
* Get the components of the DN.
*
* @param null|string $type
*
* @return array
*/
public function components($type = null)
{
return is_null($type)
? $this->components
: $this->componentsOfType($type);
}
/**
* Get the components of a particular type.
*
* @param string $type
*
* @return array
*/
protected function componentsOfType($type)
{
$components = array_filter($this->components, function ($component) use ($type) {
return ([$name] = $component) && strtolower($name) === strtolower($type);
});
return array_values($components);
}
/**
* Get the fully qualified DN.
*
* @return DistinguishedName
*/
public function get()
{
return new DistinguishedName($this->build());
}
/**
* Build the distinguished name from the components.
*
* @return $this
*/
protected function build()
{
$components = $this->reverse
? array_reverse($this->components)
: $this->components;
return implode(',', array_map(function ($component) {
return DistinguishedName::makeRdn($component);
}, $components));
}
}