2019-02-08 13:44:52 -05:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Classes and functions for the query engine.
|
|
|
|
*
|
|
|
|
* @author The phpLDAPadmin development team
|
|
|
|
* @package phpLDAPadmin
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Query Class
|
|
|
|
*
|
|
|
|
* @package phpLDAPadmin
|
|
|
|
* @subpackage Queries
|
|
|
|
*/
|
|
|
|
class Query extends xmlTemplate {
|
|
|
|
protected $description = '';
|
|
|
|
public $results = array();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Main processing to store the template.
|
|
|
|
*
|
|
|
|
* @param xmldata Parsed xmldata from xml2array object
|
|
|
|
*/
|
|
|
|
protected function storeTemplate($xmldata) {
|
|
|
|
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
$server = $this->getServer();
|
|
|
|
|
|
|
|
foreach ($xmldata['query'] as $xml_key => $xml_value) {
|
|
|
|
if (DEBUG_ENABLED)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Foreach loop Key [%s] Value [%s]', 4, 0, __FILE__, __LINE__, __METHOD__, $xml_key, is_array($xml_value));
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
switch ($xml_key) {
|
|
|
|
|
|
|
|
# Build our attribute list from the DN and Template.
|
|
|
|
case ('attributes'):
|
|
|
|
if (DEBUG_ENABLED)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Case [%s]', 4, 0, __FILE__, __LINE__, __METHOD__, $xml_key);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
if (is_array($xmldata['query'][$xml_key])) {
|
|
|
|
foreach ($xmldata['query'][$xml_key] as $tattrs) {
|
|
|
|
foreach ($tattrs as $index => $details) {
|
|
|
|
|
|
|
|
if (DEBUG_ENABLED)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Foreach tattrs Key [%s] Value [%s]', 4, 0, __FILE__, __LINE__, __METHOD__,
|
|
|
|
$index, $details);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
# If there is no schema definition for the attribute, it will be ignored.
|
|
|
|
if ($sattr = $server->getSchemaAttribute($index)) {
|
|
|
|
if (is_null($attribute = $this->getAttribute($sattr->getName())))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
$attribute = $this->addAttribute($sattr->getName(FALSE), array('values' => array()));
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
$attribute->show();
|
|
|
|
$attribute->setXML($details);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
# Build our bases list from the DN and Template.
|
|
|
|
case ('bases'):
|
|
|
|
if (isset($xmldata['query'][$xml_key]['base']))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
if (is_array($xmldata['query'][$xml_key]['base']))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
$this->base = $xmldata['query'][$xml_key]['base'];
|
2019-02-12 14:57:50 -05:00
|
|
|
} else
|
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
$this->base = array($xmldata['query'][$xml_key]['base']);
|
2019-02-12 14:57:50 -05:00
|
|
|
}
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
else
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
error(sprintf(_('In the XML file (%s), [%s] contains an unknown key.'),
|
2019-02-12 14:57:50 -05:00
|
|
|
$this->filename, $xml_key), 'error', 'index.php');
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
$this->base = array_unique($this->base);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
if (DEBUG_ENABLED)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Case [%s]', 4, 0, __FILE__, __LINE__, __METHOD__, $xml_key);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
# Some key definitions need to be an array, some must not be:
|
|
|
|
$allowed_arrays = array('');
|
|
|
|
$storelower = array('');
|
|
|
|
$storearray = array('');
|
|
|
|
|
|
|
|
# Items that must be stored lowercase
|
|
|
|
if (in_array($xml_key,$storelower))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
if (is_array($xml_value))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
foreach ($xml_value as $index => $value)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
$xml_value[$index] = strtolower($value);
|
2019-02-12 14:57:50 -05:00
|
|
|
}
|
|
|
|
} else
|
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
$xml_value = strtolower($xml_value);
|
2019-02-12 14:57:50 -05:00
|
|
|
}
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
# Items that must be stored as arrays
|
|
|
|
if (in_array($xml_key,$storearray) && ! is_array($xml_value))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
$xml_value = array($xml_value);
|
2019-02-12 14:57:50 -05:00
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
# Items that should not be an array
|
|
|
|
if (! in_array($xml_key,$allowed_arrays) && is_array($xml_value)) {
|
|
|
|
debug_dump(array(__METHOD__,'key'=>$xml_key,'value'=>$xml_value));
|
|
|
|
error(sprintf(_('In the XML file (%s), [%s] is an array, it must be a string.'),
|
|
|
|
$this->filename,$xml_key),'error');
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->$xml_key = $xml_value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Check we have some manditory items.
|
|
|
|
foreach (array() as $key) {
|
|
|
|
if (! isset($this->$key)
|
|
|
|
|| (! is_array($this->$key) && ! trim($this->$key))) {
|
|
|
|
|
|
|
|
$this->setInvalid(sprintf(_('Missing %s in the XML file.'),$key));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Accept will run the query and store the results in results()
|
|
|
|
*/
|
|
|
|
public function accept() {
|
|
|
|
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
$server = $this->getServer();
|
|
|
|
|
|
|
|
$query = array();
|
|
|
|
$query['size_limit'] = get_request('size_limit','REQUEST',false,$_SESSION[APPCONFIG]->getValue('search','size_limit'));
|
|
|
|
$query['format'] = get_request('format','REQUEST',false,$_SESSION[APPCONFIG]->getValue('search','display'));
|
|
|
|
$query['orderby'] = get_request('orderby','REQUEST',false,'dn');
|
|
|
|
|
|
|
|
# If this is a custom search, we need to populate are paramters
|
|
|
|
if ($this->getID() == 'none') {
|
|
|
|
$bases = get_request('base','REQUEST',false,null);
|
|
|
|
$query['filter'] = get_request('filter','REQUEST',false,'objectClass=*');
|
|
|
|
$query['scope'] = get_request('scope','REQUEST',false,'sub');
|
|
|
|
$attrs = get_request('display_attrs','REQUEST');
|
|
|
|
|
|
|
|
$attrs = preg_replace('/\s+/','',$attrs);
|
|
|
|
if ($attrs)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
$query['attrs'] = explode(',', $attrs);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
else
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
$query['attrs'] = array('*');
|
2019-02-12 14:57:50 -05:00
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
} else {
|
|
|
|
$bases = $this->base;
|
|
|
|
$query['filter'] = $this->filter;
|
|
|
|
$query['scope'] = $this->scope;
|
|
|
|
$query['attrs'] = $this->getAttributeNames();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! $bases)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
$bases = $server->getBaseDN();
|
2019-02-12 14:57:50 -05:00
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
elseif (! is_array($bases))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
$bases = explode('|', $bases);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
foreach ($bases as $base) {
|
|
|
|
$query['base'] = $base;
|
|
|
|
|
|
|
|
$time_start = utime();
|
|
|
|
$this->results[$base] = $server->query($query,null);
|
|
|
|
$time_end = utime();
|
|
|
|
|
|
|
|
$this->resultsdata[$base]['time'] = round($time_end-$time_start,2);
|
|
|
|
$this->resultsdata[$base]['scope'] = $query['scope'];
|
|
|
|
$this->resultsdata[$base]['filter'] = $query['filter'];
|
|
|
|
$this->resultsdata[$base]['attrs'] = $query['attrs'];
|
|
|
|
|
|
|
|
if ($this->getAttrSortOrder() == 'dn')
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
usort($this->results[$base], 'pla_compare_dns');
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
elseif ($this->getAttrSortOrder())
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
masort($this->results[$base], $this->getAttrSortOrder());
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is temporary to get around objects that use a DN for rendering, for example jpegPhoto
|
2019-02-12 14:52:01 -05:00
|
|
|
* @param $dn
|
2019-02-08 13:44:52 -05:00
|
|
|
*/
|
|
|
|
public function setDN($dn) {
|
|
|
|
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Entered (%%)', 5, 1, __FILE__, __LINE__, __METHOD__, $fargs);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
$this->dn = $dn;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is temporary to get around objects that use a DN for rendering, for example jpegPhoto
|
|
|
|
*/
|
|
|
|
public function getDN() {
|
|
|
|
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Entered (%%)', 5, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->dn);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
return $this->dn;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDNEncode($url=true) {
|
|
|
|
// @todo Be nice to do all this in 1 location
|
|
|
|
if ($url)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
return urlencode(preg_replace('/%([0-9a-fA-F]+)/', "%25\\1", $this->dn));
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
else
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
return preg_replace('/%([0-9a-fA-F]+)/', "%25\\1", $this->dn);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getAttrSortOrder() {
|
|
|
|
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
$result = array();
|
|
|
|
|
|
|
|
if (count($this->attributes)) {
|
|
|
|
masort($this->attributes,'ordersort');
|
|
|
|
|
|
|
|
foreach ($this->attributes as $attribute)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-12 15:23:38 -05:00
|
|
|
$result[] = $attribute->getName();
|
2019-02-12 14:57:50 -05:00
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
} else {
|
|
|
|
$display = preg_replace('/,\s+/',',',get_request('orderby','REQUEST',false,'dn'));
|
|
|
|
|
|
|
|
if (trim($display))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
$result = explode(',', $display);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return implode(',',$result);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getAttrDisplayOrder() {
|
|
|
|
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
$result = array();
|
|
|
|
|
|
|
|
if (count($this->attributes)) {
|
|
|
|
masort($this->attributes,'order');
|
|
|
|
|
|
|
|
foreach ($this->attributes as $attribute)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-12 15:23:38 -05:00
|
|
|
$result[] = $attribute->getName();
|
2019-02-12 14:57:50 -05:00
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
} else {
|
|
|
|
$display = preg_replace('/,\s+/',',',get_request('display_attrs','REQUEST',false,''));
|
|
|
|
|
|
|
|
if (trim($display))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
$result = explode(',', $display);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
# If our display order is empty, then dynamically build it
|
|
|
|
if (! count($result)) {
|
|
|
|
foreach ($this->results as $details)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
2019-02-08 13:44:52 -05:00
|
|
|
foreach ($details as $attrs)
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
$result = array_merge($result, array_keys(array_change_key_case($attrs)));
|
|
|
|
}
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
$result = array_unique($result);
|
|
|
|
sort($result);
|
|
|
|
}
|
|
|
|
|
|
|
|
# Put the DN first
|
|
|
|
array_unshift($result,'dn');
|
|
|
|
$result = array_unique($result);
|
|
|
|
|
|
|
|
return implode(',',$result);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test if the template is visible
|
|
|
|
*
|
|
|
|
* @return boolean
|
|
|
|
*/
|
|
|
|
public function isVisible() {
|
|
|
|
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Entered (%%)', 5, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->visible);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
return $this->visible;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDescription() {
|
|
|
|
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
2019-02-12 14:57:50 -05:00
|
|
|
{
|
|
|
|
debug_log('Entered (%%)', 5, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->description);
|
|
|
|
}
|
2019-02-08 13:44:52 -05:00
|
|
|
|
|
|
|
return $this->description;
|
|
|
|
}
|
|
|
|
}
|
2019-02-12 14:52:01 -05:00
|
|
|
|