worse hack to get sql->ldap export working with strict ldap acl applied

Ralf needs to review this, because it's a hack
This commit is contained in:
Lars Kneschke 2006-11-23 06:46:51 +00:00
parent 939b038f46
commit d0e5d6a188

View File

@ -458,6 +458,7 @@ class socontacts
{ {
$customfields = $this->soextra->search(array( $customfields = $this->soextra->search(array(
$this->extra_id => $contact['id'], $this->extra_id => $contact['id'],
$this->extra_owner => $contact['owner'],
),false); ),false);
foreach ((array)$customfields as $field) foreach ((array)$customfields as $field)
{ {
@ -467,6 +468,203 @@ class socontacts
return $this->db2data($contact); return $this->db2data($contact);
} }
/**
* searches db for rows matching searchcriteria
*
* '*' and '?' are replaced with sql-wildcards '%' and '_'
*
* @param array/string $criteria array of key and data cols, OR a SQL query (content for WHERE), fully quoted (!)
* @param boolean/string $only_keys=true True returns only keys, False returns all cols. comma seperated list of keys to return
* @param string $order_by='' fieldnames + {ASC|DESC} separated by colons ',', can also contain a GROUP BY (if it contains ORDER BY)
* @param string/array $extra_cols='' string or array of strings to be added to the SELECT, eg. "count(*) as num"
* @param string $wildcard='' appended befor and after each criteria
* @param boolean $empty=false False=empty criteria are ignored in query, True=empty have to be empty in row
* @param string $op='AND' defaults to 'AND', can be set to 'OR' too, then criteria's are OR'ed together
* @param mixed $start=false if != false, return only maxmatch rows begining with start, or array($start,$num)
* @param array $filter=null if set (!=null) col-data pairs, to be and-ed (!) into the query without wildcards
* @param string $join='' sql to do a join, added as is after the table-name, eg. ", table2 WHERE x=y" or
* "LEFT JOIN table2 ON (x=y)", Note: there's no quoting done on $join!
* @param boolean $need_full_no_count=false If true an unlimited query is run to determine the total number of rows, default false
* @return array of matching rows (the row is an array of the cols) or False
*/
function ex_search($criteria,$only_keys=True,$order_by='',$extra_cols='',$wildcard='',$empty=False,$op='AND',$start=false,$filter=null,$join='',$need_full_no_count=false)
{
//echo 'socontacts::search->criteria:'; _debug_array($criteria);
// we can only deal with one category atm.
$criteria['cat_id'] = $criteria['cat_id'][0];
if (empty($criteria['cat_id'])) unset($criteria['cat_id']);
// We just want to deal with generalized vars, to simpyfie porting of this code to so_sql later...
$this->main_id = $this->somain->contacts_id;
// seperate custom fields from main fields
foreach ($criteria as $crit_key => $crit_val)
{
if(!(isset($this->somain->db_data_cols [$crit_key]) || isset($this->somain->db_key_cols [$crit_key])))
{
if(strpos($crit_key,'#') !== false && $crit_key{0} != '!' )
{
$extra_crit_key = substr($crit_key,1);
$criteria_extra[$extra_crit_key][$this->extra_key] = $extra_crit_key;
$criteria_extra[$extra_crit_key][$this->extra_value] = $crit_val;
}
unset($criteria[$crit_key]);
}
}
//_debug_array($criteria);
//_debug_array($criteria_extra);
// search in custom fields
$resultextra = array();
if (count($criteria_extra) >= 1)
{
$firstrun = true;
foreach ((array)$criteria_extra as $extra_crit)
{
if($extra_crit[$this->extra_value]{0} == '!')
{
if(!isset($all_main_ids)) $all_main_ids = $this->somain->search(array($this->main_id => '*'));
$extra_crit[$this->extra_value] = substr($extra_crit[$this->extra_value],1);
$not_result = $this->soextra->search($extra_crit,true,'','',$wildcard);
if(is_array($not_result))
{
$expr = '$not_result[0]';
for($i=1; $i<count($not_result); $i++)
{
$expr .= ',$not_result['.$i.']';
}
@eval('$not_result = array_merge_recursive('.$expr.');');
}
foreach($all_main_ids as $entry)
{
if(array_search($entry[$this->main_id],(array)$not_result[$this->extra_id]) === false)
{
$result[] = array(
$this->extra_id => $entry[$this->main_id],
$this->extra_key => $extra_crit[$this->extra_key],
);
}
}
}
else
{
$result = $this->soextra->search($extra_crit,true,'','',$wildcard);
}
if ($op == 'OR' && $result)
{
$resultextra = array_merge_recursive((array)$result,(array)$resultextra);
}
elseif ($op == 'AND')
{
if (!$result)
{
return false;
//$resultextra = array();
//break;
}
$expr = '$result[0]';
for($i=1; $i<count($result); $i++)
{
$expr .= ',$result['.$i.']';
}
@eval('$merge = array_merge_recursive('.$expr.');');
if(!is_array($merge[$this->extra_id]))
{
$merge[$this->extra_id] = (array)$merge[$this->extra_id];
}
if($firstrun)
{
$resultextra = $merge[$this->extra_id];
$firstrun = false;
}
else
{
$resultextra = array_intersect((array)$resultextra,$merge[$this->extra_id]);
}
}
}
if($op == 'OR' && $resultextra)
{
$expr = '$resultextra[0]';
for($i=1; $i<count($resultextra); $i++)
{
$expr .= ',$resultextra['.$i.']';
}
@eval('$merge = array_merge_recursive('.$expr.');');
$resultextra = array_unique((array)$merge[$this->extra_id]);
}
}
//echo 'socontacts::search->resultextra:'; _debug_array($resultextra);
// search in main fields
$result = array();
// include results from extrafieldsearch
if(!empty($resultextra))
{
$criteria[$this->main_id] = $resultextra;
}
if (count($criteria) >= 0) // RB-CHANGED was 1
{
// We do have to apply wildcard by hand, as the result-ids of extrasearch are included in this search
if($wildcard)
{
foreach ($criteria as $field => $value)
{
if ($field == $this->main_id) continue;
$criteria[$field] = '*'.$value.'*';
}
}
$result = $this->somain->search($criteria,true,$order_by,$extra_cols,false,$empty,$op,false,$filter);
if(!is_array($result)) return false;
$expr = '$result[0]';
for($i=1; $i<count($result); $i++)
{
$expr .= ',$result['.$i.']';
}
@eval('$merge = array_merge_recursive('.$expr.');');
$result = ($merge[$this->main_id]);
}
//echo 'socontacts::search->result:'; _debug_array($result);
if(count($result) == 0) return false;
if(!is_bool($only_keys_main = $only_keys))
{
$keys_wanted = explode(',',$only_keys);
foreach ($keys_wanted as $num => $key_wanted)
{
if(!(isset($this->somain->db_data_cols [$key_wanted]) || isset($this->somain->db_key_cols [$key_wanted])))
{
unset($keys_wanted[$num]);
$keys_wanted_custom[] = $key_wanted;
}
}
$only_keys_main = implode(',',$keys_wanted);
}
$result = $this->somain->search(array($this->main_id => $result),$only_keys_main,$order_by,$extra_cols,'','','OR',$start,$filter,$join,$need_full_no_count);
// append custom fields for each row
if($only_keys === false || is_array($keys_wanted_custom))
{
foreach ($result as $num => $contact)
{
$extras = $this->soextra->search(array($this->extra_id => $contact[$this->main_id]),false);
foreach ((array)$extras as $extra)
{
if ($only_keys === false || in_array($extra[$this->extra_key],$keys_wanted_custom))
{
$result[$num][$extra[$this->extra_key]] = $extra[$this->extra_value];
}
}
}
}
foreach($result as $num => $contact)
{
$result[$num] = $this->db2data($contact);
}
return $need_full_no_count ? count($result) : $result;
}
/** /**
* searches db for rows matching searchcriteria * searches db for rows matching searchcriteria
* *
@ -716,6 +914,10 @@ class socontacts
while (($contacts = $sql_contacts->search(false,false,'n_family,n_given','','',false,'AND', while (($contacts = $sql_contacts->search(false,false,'n_family,n_given','','',false,'AND',
array($start,$num),$type != 'contacts,accounts' ? array('contact_owner != 0') : false))) array($start,$num),$type != 'contacts,accounts' ? array('contact_owner != 0') : false)))
{ {
// very worse hack, until Ralf finds a better solution
// when migrating data, we need to bind as global ldap admin account
// and not as currently logged in user
$ldap_contacts->ds = $GLOBALS['egw']->ldap->ldapConnect();
foreach($contacts as $contact) foreach($contacts as $contact)
{ {
if ($contact['account_id']) $contact['id'] = $GLOBALS['egw']->accounts->id2name($contact['account_id']); if ($contact['account_id']) $contact['id'] = $GLOBALS['egw']->accounts->id2name($contact['account_id']);
@ -737,6 +939,10 @@ class socontacts
} }
if ($type == 'contacts,accounts-back') // migrate the accounts to sql if ($type == 'contacts,accounts-back') // migrate the accounts to sql
{ {
// very worse hack, until Ralf finds a better solution
// when migrating data, we need to bind as global ldap admin account
// and not as currently logged in user
$ldap_contacts->ds = $GLOBALS['egw']->ldap->ldapConnect();
foreach($ldap_contacts->search(false,false,'n_family,n_given','','',false,'AND', foreach($ldap_contacts->search(false,false,'n_family,n_given','','',false,'AND',
false,array('owner' => 0)) as $contact) false,array('owner' => 0)) as $contact)
{ {