source: trunk/phpgwapi/inc/class.contacts_ldap.inc.php @ 7673

Revision 7673, 32.2 KB checked in by douglasz, 11 years ago (diff)

Ticket #3236 - Correcoes para Performance: Function Within Loop Declaration.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2  /**************************************************************************\
3  * eGroupWare API - Accounts manager for LDAP                               *
4  * This file written by Miles Lott <milosch@groupwhere.org>                 *
5  * View and manipulate contact records using LDAP                           *
6  * ------------------------------------------------------------------------ *
7  * This library is part of the eGroupWare API                               *
8  * http://www.egroupware.org/api                                            *
9  * ------------------------------------------------------------------------ *
10  * This library is free software; you can redistribute it and/or modify it  *
11  * under the terms of the GNU Lesser General Public License as published by *
12  * the Free Software Foundation; either version 2.1 of the License,         *
13  * or any later version.                                                    *
14  * This library is distributed in the hope that it will be useful, but      *
15  * WITHOUT ANY WARRANTY; without even the implied warranty of               *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                     *
17  * See the GNU Lesser General Public License for more details.              *
18  * You should have received a copy of the GNU Lesser General Public License *
19  * along with this library; if not, write to the Free Software Foundation,  *
20  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA            *
21  \**************************************************************************/
22
23
24        /*!
25         @class contacts
26         @abstract Contact List System
27         @discussion Author: jengo/Milosch <br>
28         This class provides a contact database scheme. <br>
29         It attempts to be based on the vcard 2.1 standard, with mods as needed to make for more reasonable sql storage. <br>
30         The LDAP schema used here may require installation of schema files available in the phpgwapi/doc/ldap dir.
31         Please see the README file there.
32         Syntax: CreateObject('phpgwapi.contacts'); <br>
33         Example1: $contacts = CreateObject('phpgwapi.contacts');
34        */
35        class contacts_
36        {
37                var $db = '';
38                var $ldap = '';
39                var $nextid = '';
40                var $std_table = '';
41                var $ext_table = 'phpgw_addressbook_extra';
42
43                var $account_id;
44                var $adr_types;
45                var $total_records;
46                var $grants;
47
48                /* The left side are the array elements used throughout phpgw, right side are the ldap attributes */
49                var $stock_contact_fields = array(
50                        'fn'                  => 'cn',
51                        'n_given'             => 'givenname',
52                        'n_family'            => 'sn',
53                        'n_middle'            => 'phpgwmiddlename',
54                        'n_prefix'            => 'phpgwprefix',
55                        'n_suffix'            => 'phpgwsuffix',
56                        'sound'               => 'phpgwaudio',
57                        'bday'                => 'phpgwbirthday',
58                        'note'                => 'description',
59                        'tz'                  => 'phpgwtz',
60                        'geo'                 => 'phpgwgeo',
61                        'url'                 => 'phpgwurl',
62                        'pubkey'              => 'phpgwpublickey',
63
64                        'org_name'            => 'o',
65                        'org_unit'            => 'ou',
66                        'title'               => 'title',
67
68                        'adr_one_street'      => 'street',
69                        'adr_one_locality'    => 'l',
70                        'adr_one_region'      => 'st',
71                        'adr_one_postalcode'  => 'postalcode',
72                        'adr_one_countryname' => 'co',
73                        'adr_one_type'        => 'phpgwadronetype',
74                        'label'               => 'phpgwaddresslabel',
75
76                        'adr_two_street'      => 'phpgwadrtwostreet',
77                        'adr_two_locality'    => 'phpgwadrtwolocality',
78                        'adr_two_region'      => 'phpgwadrtworegion',
79                        'adr_two_postalcode'  => 'phpgwadrtwopostalcode',
80                        'adr_two_countryname' => 'phpgwadrtwocountryname',
81                        'adr_two_type'        => 'phpgwadrtwotype',
82
83                        'tel_work'            => 'telephonenumber',
84                        'tel_home'            => 'homephone',
85                        'tel_voice'           => 'phpgwvoicetelephonenumber',
86                        'tel_fax'             => 'facsimiletelephonenumber',
87                        'tel_msg'             => 'phpgwmsgtelephonenumber',
88                        'tel_cell'            => 'phpgwcelltelephonenumber',
89                        'tel_pager'           => 'phpgwpagertelephonenumber',
90                        'tel_bbs'             => 'phpgwbbstelephonenumber',
91                        'tel_modem'           => 'phpgwmodemtelephonenumber',
92                        'tel_car'             => 'phpgwmobiletelephonenumber',
93                        'tel_isdn'            => 'phpgwisdnphonenumber',
94                        'tel_video'           => 'phpgwvideophonenumber',
95                        'tel_prefer'          => 'phpgwpreferphone',
96                        'email'               => 'mail',
97                        'email_type'          => 'phpgwmailtype',
98                        'email_home'          => 'phpgwmailhome',
99                        'email_home_type'     => 'phpgwmailhometype'
100                );
101
102                var $non_contact_fields = array(
103                        'id'     => 'uidnumber',
104                        'lid'    => 'uid',
105                        'tid'    => 'phpgwcontacttypeid',
106                        'cat_id' => 'phpgwcontactcatid',
107                        'access' => 'phpgwcontactaccess',
108                        'owner'  => 'phpgwcontactowner'
109                );
110
111                /* Used to set preferphone field */
112                var $tel_types = array(
113                        'work'  => 'work',
114                        'home'  => 'home',
115                        'voice' => 'voice',
116                        'fax'   => 'fax',
117                        'msg'   => 'msg',
118                        'cell'  => 'cell',
119                        'pager' => 'pager',
120                        'bbs'   => 'bbs',
121                        'modem' => 'modem',
122                        'car'   => 'car',
123                        'isdn'  => 'isdn',
124                        'video' => 'video'
125                );
126
127                /* Used to set mail_type fields */
128                var $email_types = array(
129                        'INTERNET'   => 'INTERNET',
130                        'CompuServe' => 'CompuServe',
131                        'AOL'        => 'AOL',
132                        'Prodigy'    => 'Prodigy',
133                        'eWorld'     => 'eWorld',
134                        'AppleLink'  => 'AppleLink',
135                        'AppleTalk'  => 'AppleTalk',
136                        'PowerShare' => 'PowerShare',
137                        'IBMMail'    => 'IBMMail',
138                        'ATTMail'    => 'ATTMail',
139                        'MCIMail'    => 'MCIMail',
140                        'X.400'      => 'X.400',
141                        'TLX'        => 'TLX'
142                );
143
144                function contacts_()
145                {
146                        $this->db = $GLOBALS['phpgw']->db;
147                        $this->ldap = $GLOBALS['phpgw']->common->ldapConnect(
148                                $GLOBALS['phpgw_info']['server']['ldap_contact_host'],
149                                $GLOBALS['phpgw_info']['server']['ldap_contact_dn'],
150                                $GLOBALS['phpgw_info']['server']['ldap_contact_pw']
151                        );
152                        $this->account_id = $GLOBALS['phpgw_info']['user']['account_id'];
153                        $this->grants     = $GLOBALS['phpgw']->acl->get_grants('addressbook');
154
155                        /* Used to flag an address as being:
156                           domestic OR  international(default)
157                           parcel(default)
158                           postal(default)
159                           work(default) OR home
160                        */
161                        $this->adr_types = array(
162                                'dom'    => lang('Domestic'),
163                                'intl'   => lang('International'),
164                                'parcel' => lang('Parcel'),
165                                'postal' => lang('Postal')
166                        );
167                }
168
169                /* send this the id and whatever fields you want to see */
170                function read_single_entry($id,$fields='')
171                {
172                        if(!$fields || empty($fields))
173                        {
174                                $fields = $this->stock_contact_fields;
175                        }
176                        list($stock_fields,$stock_fieldnames,$extra_fields) = $this->split_stock_and_extras($fields);
177
178                        if(count($stock_fieldnames))
179                        {
180                                $t_fields = ',' . implode(',',$stock_fieldnames);
181                                if($t_fields == ',')
182                                {
183                                        unset($t_fields);
184                                }
185                        }
186
187                        $sri = ldap_search($this->ldap, $GLOBALS['phpgw_info']['server']['ldap_contact_context'], 'uidnumber=' . (int)$id);
188                        $ldap_fields = ldap_get_entries($this->ldap, $sri);
189
190                        $return_fields[0]['id']     = $ldap_fields[0]['uidnumber'][0];
191                        $return_fields[0]['lid']    = $ldap_fields[0]['uid'][0];
192                        $return_fields[0]['tid']    = $ldap_fields[0]['phpgwcontacttypeid'][0];
193                        $return_fields[0]['owner']  = $ldap_fields[0]['phpgwcontactowner'][0];
194                        $return_fields[0]['access'] = $ldap_fields[0]['phpgwcontactaccess'][0];
195                        $return_fields[0]['cat_id'] = $ldap_fields[0]['phpgwcontactcatid'][0];
196                        $return_fields[0]['rights'] = (int)$this->grants[$return_fields[0]['owner']];
197                        if(@is_array($stock_fieldnames))
198                        {
199                                foreach($stock_fieldnames as $name => $value)
200                                {
201                                        $return_fields[0][$name] = utf8_decode($ldap_fields[0][$value][0]);
202                                }
203                        }
204
205                        /* Setup address type fields */
206                        if($return_fields[0]['adr_one_type'])
207                        {
208                                $one_type = $return_fields[0]['adr_one_type'];
209                                foreach($this->adr_types as $name => $val)
210                                {
211                                        eval("if(strstr(\$one_type,\$name)) { \$return_fields[0][\"one_\$name\"] = \"on\"; }");
212                                }
213                        }
214                        if($return_fields[0]['adr_two_type'])
215                        {
216                                $two_type = $return_fields[0]['adr_two_type'];
217                                foreach($this->adr_types as $name => $val)
218                                {
219                                        eval("if(strstr(\$two_type,\$name)) { \$return_fields[0][\"two_\$name\"] = \"on\"; }");
220                                }
221                        }
222
223                        $this->db->query("SELECT contact_name,contact_value FROM $this->ext_table WHERE contact_id='"
224                                . (int)$id . "'",__LINE__,__FILE__);
225                        while($this->db->next_record())
226                        {
227                                if($extra_fields[$this->db->f('contact_name')])
228                                {
229                                        $return_fields[0][$this->db->f('contact_name')] = $this->db->f('contact_value');
230                                }
231                        }
232                        return $return_fields;
233                }
234
235                function read_last_entry($fields = '')
236                {
237                        if(!$fields || empty($fields))
238                        {
239                                $fields = $this->stock_contact_fields;
240                        }
241                        list($stock_fields,$stock_fieldnames,$extra_fields) = $this->split_stock_and_extras($fields);
242
243                        if(count($stock_fieldnames))
244                        {
245                                $t_fields = ',' . implode(',',$stock_fieldnames);
246                                if($t_fields == ',')
247                                {
248                                        unset($t_fields);
249                                }
250                        }
251
252                        $id = $this->nextid;
253                        if($id == -1)
254                        {
255                                $id = 1;
256                        }
257
258                        $sri = ldap_search($this->ldap, $GLOBALS['phpgw_info']['server']['ldap_contact_context'], 'uidnumber=' . (int)$id);
259                        $ldap_fields = ldap_get_entries($this->ldap, $sri);
260
261                        $return_fields[0]['id']     = $ldap_fields[0]['uidnumber'][0];
262                        $return_fields[0]['lid']    = $ldap_fields[0]['uid'][0];
263                        $return_fields[0]['tid']    = $ldap_fields[0]['phpgwcontacttypeid'][0];
264                        $return_fields[0]['owner']  = $ldap_fields[0]['phpgwcontactowner'][0];
265                        $return_fields[0]['access'] = $ldap_fields[0]['phpgwcontactaccess'][0];
266                        $return_fields[0]['cat_id'] = $ldap_fields[0]['phpgwcontactcatid'][0];
267                        $return_fields[0]['rights'] = (int)$this->grants[$return_fields[0]['owner']];
268
269                        if(@is_array($stock_fieldnames))
270                        {
271                                foreach($stock_fieldnames as $name => $value)
272                                {
273                                        $return_fields[0][$name] = utf8_decode($ldap_fields[0][$value][0]);
274                                }
275                        }
276
277                        /* Setup address type fields */
278                        if($return_fields[0]['adr_one_type'])
279                        {
280                                $one_type = $return_fields[0]['adr_one_type'];
281                                foreach($this->adr_types as $name => $val)
282                                {
283                                        eval("if(strstr(\$one_type,\$name)) { \$return_fields[0][\"one_\$name\"] = \"on\"; }");
284                                }
285                        }
286                        if($return_fields[0]['adr_two_type'])
287                        {
288                                $two_type = $return_fields[0]['adr_two_type'];
289                                foreach($this->adr_types as $name => $val)
290                                {
291                                        eval("if(strstr(\$two_type,\$name)) { \$return_fields[0][\"two_\$name\"] = \"on\"; }");
292                                }
293                        }
294
295                        $this->db->query("SELECT contact_name,contact_value FROM $this->ext_table WHERE contact_id='" . (int)$id . "'",__LINE__,__FILE__);
296                        while($this->db->next_record())
297                        {
298                                if($extra_fields[$this->db->f('contact_name')])
299                                {
300                                        $return_fields[0][$this->db->f('contact_name')] = $this->db->f('contact_value');
301                                }
302                        }
303                        return $return_fields;
304                }
305
306                /* send this the range, query, sort, order and whatever fields you want to see */
307                function read($start=0,$limit=0,$fields='',$query='',$filter='',$sort='',$order='', $lastmod=-1,$cquery='')
308                {
309                        if(!$start)  { $start  = 0; }
310                        if(!$limit)  { $limit  = 0; }
311                        if(!$filter) { $filter = 'tid=n'; }
312
313                        if(!$fields || empty($fields))
314                        {
315                                $fields = $this->stock_contact_fields;
316                        }
317                        $DEBUG = 0;
318
319                        list($stock_fields,$stock_fieldnames,$extra_fields) = $this->split_stock_and_extras($fields);
320
321                        $filterfields = array();
322                        /* turn filter's a=b,c=d OR a=b into an array */
323                        if($filter)
324                        {
325                                if($DEBUG) { echo 'DEBUG - Inbound filter is: #'.$filter.'#'; }
326                                $filterarray = preg_split('/,/',$filter);
327                                if($filterarray[1])
328                                {
329                                        $i=0;
330                    $filterarray_count = count($filterarray);
331                                        for($i=0;$i<$filterarray_count;++$i)
332                                        {
333                                                list($name,$value) = preg_split('/=/',$filterarray[$i]);
334                                                if($name)
335                                                {
336                                                        if($DEBUG) { echo '<br>DEBUG - Filter strings: #'.$this->non_contact_fields[$name].'# => #'.$value.'#'; }
337                                                        $filterfields[$this->non_contact_fields[$name]] = $value;
338                                                }
339                                        }
340                                }
341                                else
342                                {
343                                        list($name,$value) = preg_split('/=/',$filter);
344                                        if($DEBUG)
345                                        {
346                                                echo '<br>DEBUG - Filter strings: #'.$this->non_contact_fields[$name].'# => #'.$value.'#';
347                                        }
348                                        $filterfields = array($this->non_contact_fields[$name] => $value);
349                                }
350                        }
351                        else
352                        {
353                                $filterfields += array('phpgwcontacttypeid' => 'n');
354                                if($DEBUG) { echo "<br>DEBUG - Filter strings: #phpgwcontacttypeid=n#"; }
355                        }
356
357                        /*
358                        need some way of using the lastmod arg in the filter like this:
359                        if($lastmod >= 0)
360                        {
361                                $filterfields += array('last_mod' => (int)$lastmod;
362                        }
363                        or maybe not like this - i am not sure what i am doing :)
364                        */
365
366                        if(@is_array($this->grants))
367                        {
368                                $filterfields['phpgwcontactowner'] = array();
369                                /* this was not listing private entries when show all was selected */
370                                /* $filterfields += array('phpgwcontactaccess' => 'public'); */
371                                if($DEBUG) { echo '<br>DEBUG - My user id is: ' . $this->account_id; }
372                                foreach($this->grants as $user => $right)
373                                {
374                                        if($DEBUG) { echo '<br>DEBUG - Grant from owner: ' . $user; }
375                                        $filterfields['phpgwcontactowner'][] = array('phpgwcontactowner' => $user);
376                                }
377                        }
378                        /*
379                        if($DEBUG)
380                        {
381                                while(list($name,$value) = each($filterfields))
382                                {
383                                        echo '<br>DEBUG - Filter strings: #' . $name . ',' . $value . '#';
384                                }
385                        }
386                        */
387
388                        $sort  = $sort  ? $sort  : 'ASC';
389                        $order = $order ? $order : 'n_family';
390
391                        if($DEBUG && $order)
392                        {
393                                echo "<br>DEBUG - ORDER by $order";
394                        }
395
396                        $ldap_fields = array();
397                        $myfilter = '';
398
399                        if($cquery)
400                        {
401                                $search_filter = array(
402                                        'fn'       => 'cn',
403                                        'n_family' => 'sn',
404                                        'org_name' => 'o'
405                                );
406                                $myfilter = $this->makefilter($filterfields,$search_filter,"$cquery*",$DEBUG);
407                        }
408                        elseif($query)
409                        {
410                                // the old code was searching about all fields
411                                // this was very slow
412                                #reset($this->stock_contact_fields);
413                                #$myfilter = $this->makefilter($filterfields,$this->stock_contact_fields,$query,$DEBUG);
414
415                                if(is_array($query))
416                                {
417                                        // must be fixed somehow Milosch????
418                                        $myfilter = $this->makefilter($filterfields,$query,'',$DEBUG);
419                                }
420                                else
421                                {
422                                        // don't search about any fields any more
423                                        $search_filter = array(
424                                                'fn'            => 'cn',
425                                                'n_given'       => 'givenname',
426                                                'n_family'      => 'sn',
427                                                'email'         => 'mail',
428                                                'org_name'      => 'o',
429                                                'org_unit'      => 'ou'
430                                        );
431                                        $myfilter = $this->makefilter($filterfields,$search_filter,$query,$DEBUG);
432                                }
433                        }
434                        else
435                        {
436                                $myfilter = $this->makefilter($filterfields,'','',$DEBUG);
437                        }
438
439                        $sri = ldap_search($this->ldap, $GLOBALS['phpgw_info']['server']['ldap_contact_context'], $myfilter);
440
441                        $ldap_fields = ldap_get_entries($this->ldap, $sri);
442                        /* _debug_array($ldap_fields);exit; */
443
444                        $this->total_records = ldap_count_entries($this->ldap, $sri);
445                        /* echo '<br>total="'.$this->total_records.'"'; */
446                        if($DEBUG) { echo '<br>Query returned "'.$this->total_records.'" records.'; }
447
448                        /* Use shared sorting routines, based on sort and order */
449                        @set_time_limit(0); /* Try not to die, this can take some time on slow machines... */
450                        if($sort == 'ASC')
451                        {
452                                $ldap_fields = $this->asortbyindex($ldap_fields, $this->stock_contact_fields[$order]);
453                        }
454                        else
455                        {
456                                $ldap_fields = $this->arsortbyindex($ldap_fields, $this->stock_contact_fields[$order]);
457                        }
458
459                        /*
460                        This logic allows you to limit rows, or not.
461                        The export feature, for example, does not limit rows.
462                        This way, it can retrieve all rows at once.
463                        */
464                        if($start && $limit)
465                        {
466                                $limit = $start + $limit;
467                        }
468                        elseif($start && !$limit)
469                        {
470                                $limit = $start;
471                        }
472                        elseif(!$start && !$limit)
473                        {
474                                $limit = $this->total_records;
475                        }
476                        else
477                        {
478                                $start = 0;
479                                $limit = $limit;
480                        }
481                        /* echo '('.$start.','.$limit.')'; */
482
483                        @reset($ldap_fields);
484                        $j = 0;
485                        for($i=$start;$i<$limit;++$i)
486                        {
487                                if($i<$this->total_records && $ldap_fields[$i]['uid'][0])
488                                {
489                                        $return_fields[$j]['id']     = $ldap_fields[$i]['uidnumber'][0];
490                                        $return_fields[$j]['lid']    = $ldap_fields[$i]['uid'][0];
491                                        $return_fields[$j]['tid']    = $ldap_fields[$i]['phpgwcontacttypeid'][0];
492                                        $return_fields[$j]['owner']  = $ldap_fields[$i]['phpgwcontactowner'][0];
493                                        $return_fields[$j]['access'] = $ldap_fields[$i]['phpgwcontactaccess'][0];
494                                        $return_fields[$j]['cat_id'] = $ldap_fields[$i]['phpgwcontactcatid'][0];
495                                        $return_fields[$j]['rights'] = (int)$this->grants[$return_fields[$j]['owner']];
496
497                                        if(@is_array($stock_fieldnames))
498                                        {
499                                                foreach($stock_fieldnames as $f_name => $f_value)
500                                                {
501                                                        $return_fields[$j][$f_name] = utf8_decode($ldap_fields[$i][$f_value][0]);
502                                                }
503                                        }
504                                        $this->db->query("SELECT contact_name,contact_value FROM $this->ext_table WHERE contact_id='"
505                                                . (int)$ldap_fields[$i]['uidnumber'] . "'",__LINE__,__FILE__);
506                                        while($this->db->next_record())
507                                        {
508                                                if($extra_fields[$this->db->f('contact_name')])
509                                                {
510                                                        $return_fields[$j][$this->db->f('contact_name')] = $this->db->f('contact_value');
511                                                }
512                                        }
513                                        ++$j;
514                                }
515                        }
516                        return $return_fields;
517                }
518
519                /* Used by read() above to build the ldap filter string */
520                function makefilter($qarray,$extra='',$query='', $DEBUG=False)
521                {
522                        if(!@is_array($qarray))
523                        {
524                                return $qarray;
525                        }
526
527                        $first = $last = "*";
528                        if(strstr($query,"*"))
529                        {
530                                if(substr($query,-1) == "*")
531                                {
532                                        $last = '';
533                                }
534                                if(substr($query,1) == "*")
535                                {
536                                        $first = '';
537                                }
538                        }
539
540                        if(@is_array($extra))
541                        {
542                                if($DEBUG) { echo '<br>Searching...'; }
543                                foreach($extra as $name => $value)
544                                {
545                                        $qarray[] = array($value => $query);
546                                }
547                        }
548                        elseif($extra)
549                        {
550                                $tmp = preg_split('/=/',$extra);
551                                $qarray[] = array($tmp[0] => $tmp[1]);
552                        }
553
554                        @ksort($qarray);
555
556                        $aquery = '(&';
557                        $oquery = '(|';
558                        $hasor = False;
559
560                        foreach($qarray as $name => $value)
561                        {
562                                if(@is_array($value))
563                                {
564                                        foreach($value as $x => $y)
565                                        {
566                                                if($y == '*')
567                                                {
568                                                        $oquery .= '(' . $x . '=*)';
569                                                        $hasor = True;
570                                                }
571                                                elseif(@is_array($y))
572                                                {
573                                                        /* This was most likely created from acl grants in read() above */
574                                                        foreach($y as $a => $b)
575                                                        {
576                                                                $tmp .= '(' . $a . '=' . $b . ')';
577                                                        }
578                                                }
579                                                else
580                                                {
581                                                        $oquery .= '(' . $x . '=' . $first . $y . $last . ')';
582                                                        $hasor = True;
583                                                }
584                                        }
585                                }
586                                elseif($value == $query)
587                                {
588                                        /* searching */
589                                        $oquery .= '(' . $name . '=' . $first . $value . $last . ')';
590                                        $hasor = True;
591                                }
592                                else
593                                {
594                                        /* exact value (filtering based on tid, etc...) */
595                                        if($name == 'phpgwcontactcatid')
596                                        {
597                                                if (!is_object($GLOBALS['phpgw']->categories))
598                                                {
599                                                        $GLOBALS['phpgw']->categories = CreateObject('phpgwapi.categories');
600                                                }
601                                                $cats = $GLOBALS['phpgw']->categories->return_all_children((int)$value);
602
603                                                $aquery .= '(|';
604                                                foreach($cats as $cat)
605                                                {
606                                                        $aquery .= '(' . $name . '=*,' . $cat . ',*)(' . $name . '=' . $cat . ')';
607                                                }
608                                                $aquery .= ')';
609                                        }
610                                        else
611                                        {
612                                                $aquery .= '(' . $name . '=' . $value . ')';
613                                        }
614                                }
615
616                                if($tmp)
617                                {
618                                        if(strstr($tmp,')('))
619                                        {
620                                                $aquery .= '(|' . $tmp . ')';
621                                        }
622                                        else
623                                        {
624                                                $aquery .= $tmp;
625                                        }
626                                        unset($tmp);
627                                }
628                        }
629                        $aquery .= ')';
630                        $oquery .= ')';
631                        if(!$hasor)
632                        {
633                                $oquery = '';
634                                $fquery = $aquery;
635                        }
636                        else
637                        {
638                                $fquery = '(&' . $aquery . $oquery . ')';
639                        }
640
641                        if($DEBUG)
642                        {
643                                echo '<br>AND query:  "' . $aquery . '"';
644                                echo '<br>OR query:   "' . $oquery . '"';
645                                echo '<br>Full query: "' . $fquery . '"';
646                                echo '<br>Will search in "' . $GLOBALS['phpgw_info']['server']['ldap_contact_context'] . '"';
647                        }
648
649//                      echo $fquery;
650                        return $fquery;
651                }
652
653                function add($owner,$fields,$access=NULL,$cat_id=NULL,$tid=NULL)
654                {
655                        // access, cat_id and tid can be in $fields now or as extra params
656                        foreach(array('access','cat_id','tid') as $extra)
657                        {
658                                if(!is_null($$extra))
659                                {
660                                        $fields[$extra] = $$extra;
661                                }
662                        }
663                        if(empty($fields['tid']))
664                        {
665                                $fields['tid'] = 'n';
666                        }
667
668                        if(!$GLOBALS['phpgw_info']['server']['ldap_contact_context'])
669                        {
670                                return False;
671                        }
672
673                        list($stock_fields,$stock_fieldnames,$extra_fields) = $this->split_stock_and_extras($fields);
674
675                        $free = 0;
676                        $this->nextid = $GLOBALS['phpgw']->common->last_id('contacts');
677                        /* Loop until we find a free id */
678                        while(!$free)
679                        {
680                                $ldap_fields = '';
681                                $sri = ldap_search($this->ldap, $GLOBALS['phpgw_info']['server']['ldap_contact_context'], 'uidnumber='.$this->nextid);
682                                $ldap_fields = ldap_get_entries($this->ldap, $sri);
683                                if($ldap_fields[0]['dn'][0])
684                                {
685                                        $this->nextid = $GLOBALS['phpgw']->common->next_id('contacts');
686                                }
687                                else
688                                {
689                                        $free = True;
690                                }
691                        }
692
693                        $ldap_fields = '';
694                        if(@is_array($stock_fieldnames))
695                        {
696                                foreach($stock_fieldnames as $name => $value)
697                                {
698                                        if($stock_fields[$name] != '')
699                                        {
700                                                $ldap_fields[$value] = utf8_encode($stock_fields[$name]);
701                                        }
702                                }
703                        }
704
705                        $time = gettimeofday();
706                        $ldap_fields['uid'] = time().$time['usec'].':'.$ldap_fields['givenname'];
707
708                        $dn = 'uid=' . $ldap_fields['uid'].',' . $GLOBALS['phpgw_info']['server']['ldap_contact_context'];
709                        $ldap_fields['phpgwcontacttypeid']    = $fields['tid'];
710                        $ldap_fields['phpgwcontactowner']     = $owner;
711                        if(!isset($fields['access']))
712                        {
713                                $fields['access'] = 'private';
714                        }
715                        $ldap_fields['phpgwcontactaccess'] = $fields['access'];
716                        $ldap_fields['phpgwcontactcatid']  = $fields['cat_id'] ? $fields['cat_id'] : '0';
717                        $ldap_fields['uidnumber']      = $this->nextid;
718                        /* $ldap_fields['objectclass'][0] = 'person'; */
719                        $ldap_fields['objectclass'][0] = 'organizationalPerson';
720                        $ldap_fields['objectclass'][1] = 'inetOrgPerson';
721                        $ldap_fields['objectclass'][2] = 'phpgwContact';
722                        //$ldap_fields['last_mod'] = $GLOBALS['phpgw']->datetime->gmtnow;
723
724                        $err = $this->validate($ldap_fields);
725                        if(@is_array($err) && @isset($err[0]))
726                        {
727                                return $err;
728                        }
729                        // _debug_array($ldap_fields); exit;
730                        $err = ldap_add($this->ldap, $dn, $ldap_fields);
731                        if(!$err)
732                        {
733                                return False;
734                        }
735
736                        if(count($extra_fields))
737                        {
738                                foreach($extra_fields as $name => $value)
739                                {
740                                        $this->db->query("INSERT INTO $this->ext_table VALUES ('".$this->nextid."','" . $this->account_id . "','"
741                                                . addslashes($name) . "','" . addslashes($value) . "')",__LINE__,__FILE__);
742                                }
743                        }
744                        return $this->nextid;
745                }
746
747                /* LDAP syntaxes require some testing prior to add */
748                function validate(&$entry)
749                {
750                        $errors = array();
751                        foreach($entry as $field => $value)
752                        {
753                                if(strstr($field,'phone'))
754                                {
755                                        /* Regex for testing valid international phone number entries.
756                                         * LDAP may reject bad values here, such as an email address in a phone number.
757                                         * This format is somewhat loose, allowing for optional parenthesis, + sign,
758                                         * and 0-7 numbers between separators.
759                                         */
760                                        $regex = "/^[-0-9\+\(\)\/]/";
761                                        if(!preg_match($regex,$value))
762                                        {
763                                                $errors[] = array($field => $value);
764                                        }
765                                }
766                                elseif(strstr($field,'mailtype') || strstr($field,'mailhometype'))
767                                {
768                                        /* Check for valid mail type */
769                                        if(!@isset($this->email_types[$value]))
770                                        {
771                                                $errors[] = array($field => $value);
772                                        }
773                                }
774                                elseif(strstr($field,'mail'))
775                                {
776                                        /* Check for valid email address - TODO - should depend on mail type */
777                                        $regex = "/[ |\t|\r|\n]*\"?([^\"]+\"?@[^ <>\t]+\.[^ <>\t][^ <>\t]+)[ |\t|\r|\n]*/x";
778                                        if(!preg_match($regex,$value))
779                                        {
780                                                $errors[] = array($field => $value);
781                                        }
782                                }
783                        }
784                        /* Verify sn/cn attrs set */
785                        if(empty($entry['sn']) && !empty($entry['cn']))
786                        {
787                                $entry['sn'] = $entry['cn'];
788                        }
789                        if(empty($entry['cn']) && !empty($entry['sn']))
790                        {
791                                $entry['cn'] = $entry['sn'];
792                        }
793                        $entry['cn'] = $entry['cn'] ? $entry['cn'] : '-';
794                        $entry['sn'] = $entry['sn'] ? $entry['sn'] : '-';
795
796                        return $errors;
797                }
798
799                function field_exists($id,$field_name)
800                {
801                        $this->db->query("SELECT COUNT(*) FROM $this->ext_table where contact_id='" . (int)$id . "' AND contact_name='"
802                        . addslashes($field_name) . "'",__LINE__,__FILE__);
803                        $this->db->next_record();
804                        return $this->db->f(0);
805                }
806
807                function add_single_extra_field($id,$owner,$field_name,$field_value)
808                {
809                        $this->db->query("INSERT INTO $this->ext_table VALUES (" . (int)$id . ",'$owner','" . addslashes($field_name)
810                                . "','" . addslashes($field_value) . "')",__LINE__,__FILE__);
811                }
812
813                function delete_single_extra_field($id,$field_name)
814                {
815                        $this->db->query("DELETE FROM $this->ext_table WHERE contact_id='" . (int)$id . "' AND contact_name='"
816                                . addslashes($field_name) . "'",__LINE__,__FILE__);
817                }
818
819                function update($id,$owner,$fields,$access=NULL,$cat_id=NULL,$tid=NULL)
820                {
821                        // access, cat_id and tid can be in $fields now or as extra params
822                        foreach(array('access','cat_id','tid') as $extra)
823                        {
824                                if(!is_null($$extra))
825                                {
826                                        $fields[$extra] = $$extra;
827                                }
828                                if(isset($fields[$extra]))
829                                {
830                                        $stock_fields[$extra] = $fields[$extra];
831                                }
832                        }
833                        $nonfields = $this->non_contact_fields;
834
835                        if(!$GLOBALS['phpgw_info']['server']['ldap_contact_context'])
836                        {
837                                return False;
838                        }
839
840                        /* First make sure that id number exists */
841                        $sri = ldap_search($this->ldap, $GLOBALS['phpgw_info']['server']['ldap_contact_context'], 'uidnumber=' . (int)$id);
842                        $ldap_fields = ldap_get_entries($this->ldap, $sri);
843
844                        if($ldap_fields[0]['dn'])
845                        {
846                                $dn = $ldap_fields[0]['dn'];
847                                list($stock_fields,$stock_fieldnames,$extra_fields) = $this->split_stock_and_extras($fields);
848                                if(@is_array($stock_fieldnames))
849                                {
850                                        /*
851                                        Check each value, add our extra attributes if they are missing, and
852                                        otherwise fix the entry while we can.
853                                        */
854                                        /* Verify uidnumber */
855                                        $stock_fields['id']   = $id;
856                                        if(empty($ldap_fields[0]['uidnumber']))
857                                        {
858                                                $err = ldap_modify($this->ldap,$dn,array('uidnumber'  => $stock_fields['uidnumber']));
859                                        }
860                                        elseif(!$ldap_fields[0]['uidnumber'])
861                                        {
862                                                $err = ldap_mod_add($this->ldap,$dn,array('uidnumber' => $stock_fields['uidnumber']));
863                                        }
864
865                                        /* Verify uid */
866                                        $uids = preg_split('/,/',$dn);
867                                        $stock_fields['lid'] = $uids[0];
868                                        if(empty($ldap_fields[0]['uid']))
869                                        {
870                                                $err = ldap_modify($this->ldap,$dn,array('uid'  => $stock_fields['lid']));
871                                        }
872                                        elseif(!$ldap_fields[0]['uid'])
873                                        {
874                                                $err = ldap_mod_add($this->ldap,$dn,array('uid' => $stock_fields['lid']));
875                                        }
876
877                                        /* Verify objectclasses are there */
878                                        if(empty($ldap_fields[0]['objectclass']))
879                                        {
880                                                /* $stock_fields['objectclass'][0] = 'person'; */
881                                                $stock_fields['objectclass'][0] = 'organizationalPerson';
882                                                $stock_fields['objectclass'][1] = 'inetOrgPerson';
883                                                $stock_fields['objectclass'][2] = 'phpgwContact';
884                                                $err = ldap_modify($this->ldap,$dn,array('objectclass'  => $stock_fields['objectclass']));
885                                        }
886                                        elseif(!$ldap_fields[0]['objectclass'])
887                                        {
888                                                /* $stock_fields['objectclass'][0] = 'person'; */
889                                                $stock_fields['objectclass'][0] = 'organizationalPerson';
890                                                $stock_fields['objectclass'][1] = 'inetOrgPerson';
891                                                $stock_fields['objectclass'][2] = 'phpgwContact';
892                                                $err = ldap_mod_add($this->ldap,$dn,array('objectclass'  => $stock_fields['objectclass']));
893                                        }
894
895                                        /* Verify owner */
896                                        $stock_fields['owner']  = $owner;
897                                        if(empty($ldap_fields[0]['phpgwcontactowner']))
898                                        {
899                                                $err = ldap_modify($this->ldap,$dn,array('phpgwcontactowner'  => $stock_fields['owner']));
900                                        }
901                                        elseif(!$ldap_fields[0]['phpgwcontactowner'])
902                                        {
903                                                $err = ldap_mod_add($this->ldap,$dn,array('phpgwcontactowner' => $stock_fields['owner']));
904                                        }
905
906                                        /* Verify access */
907                                        $stock_fields['access'] = $fields['access'];
908                                        if(empty($ldap_fields[0]['phpgwcontactaccess']))
909                                        {
910                                                $err = ldap_modify($this->ldap,$dn,array('phpgwcontactaccess'  => $stock_fields['access']));
911                                        }
912                                        elseif(!$ldap_fields[0]['phpgwcontactaccess'])
913                                        {
914                                                $err = ldap_mod_add($this->ldap,$dn,array('phpgwcontactaccess' => $stock_fields['access']));
915                                        }
916
917                                        /* Verify cat_id */
918                                        $stock_fields['cat_id']  = $fields['cat_id'] ? $fields['cat_id'] : ' ';
919                                        if(empty($ldap_fields[0]['phpgwcontactcatid']))
920                                        {
921                                                $err = ldap_modify($this->ldap,$dn,array('phpgwcontactcatid'  => $stock_fields['cat_id']));
922                                        }
923                                        elseif(!$ldap_fields[0]['phpgwcontactcatid'])
924                                        {
925                                                $err = ldap_mod_add($this->ldap,$dn,array('phpgwcontactcatid' => $stock_fields['cat_id']));
926                                        }
927
928                                        /* Verify tid */
929                                        $stock_fields['tid'] = $fields['tid'];
930                                        if(empty($ldap_fields[0]['phpgwcontacttypeid']))
931                                        {
932                                                $err = ldap_modify($this->ldap,$dn,array('phpgwcontacttypeid'  => $stock_fields['tid']));
933                                        }
934                                        elseif(!$ldap_fields[0]['phpgwcontacttypeid'])
935                                        {
936                                                $err = ldap_mod_add($this->ldap,$dn,array('phpgwcontacttypeid' => $stock_fields['tid']));
937                                        }
938
939                                        /* OK, just mod the data already */
940                                        $allfields = $stock_fieldnames + $nonfields;
941                                        /* Don't try to modify the uid, since this affects the dn */
942                                        unset($allfields['lid']);
943                                        foreach($allfields as $fname => $fvalue)
944                                        {
945                                                if($ldap_fields[0][$fvalue] && $stock_fields[$fname] && $ldap_fields[0][$fvalue][0] != $stock_fields[$fname] )
946                                                {
947                                                        //echo "<br>".$fname." => ".$fvalue." was there";
948                                                        $err = ldap_modify($this->ldap,$dn,array($fvalue => utf8_encode($stock_fields[$fname])));
949                                                }
950                                                elseif(!$ldap_fields[0][$fvalue] && $stock_fields[$fname])
951                                                {
952                                                        //echo "<br>".$fname." not there - '".$fvalue."'";
953                                                        $err = ldap_mod_add($this->ldap,$dn,array($fvalue => utf8_encode($stock_fields[$fname])));
954                                                }
955                                                elseif($ldap_fields[0][$fvalue] && !$stock_fields[$fname])
956                                                {
957                                                        //echo "<br>".$fname." gone...  deleting - '".$fvalue."'";
958                                                        /*
959                                                        NOTE: we use the ldap_fields because we need to send the
960                                                        _ORIGINAL_ contents as the value. see:
961                                                        http://www.php.net/manual/en/function.ldap-mod-del.php
962                                                        */
963                                                        $err = ldap_mod_del($this->ldap,$dn,array($fvalue => $ldap_fields[0][$fvalue][0]));
964                                                }
965                                                /* Else we have nothing to do. */
966                                        }
967                                }
968
969                                //something here to update the last_mod from $GLOBALS['phpgw']->datetime->gmtnow
970
971                                foreach($extra_fields as $x_name => $x_value)
972                                {
973                                        if($this->field_exists($id,$x_name))
974                                        {
975                                                if(!$x_value)
976                                                {
977                                                        $this->delete_single_extra_field($id,$x_name);
978                                                }
979                                                else
980                                                {
981                                                        $this->db->query("UPDATE $this->ext_table SET contact_value='" . addslashes($x_value)
982                                                                . "',contact_owner='$owner' WHERE contact_name='" . addslashes($x_name)
983                                                                . "' AND contact_id='" . (int)$id . "'",__LINE__,__FILE__);
984                                                }
985                                        }
986                                        else
987                                        {
988                                                $this->add_single_extra_field($id,$owner,$x_name,$x_value);
989                                        }
990                                }
991                        }
992                        else
993                        {
994                                return False;
995                        }
996                }
997
998                /* Used by admin to change ownership on account delete */
999                function change_owner($old_owner='',$new_owner='')
1000                {
1001                        if(!($new_owner && $old_owner))
1002                        {
1003                                return False;
1004                        }
1005
1006                        $sri = ldap_search($this->ldap, $GLOBALS['phpgw_info']['server']['ldap_contact_context'], 'phpgwcontactowner='.$old_owner);
1007                        $ldap_fields = ldap_get_entries($this->ldap, $sri);
1008
1009                        $entry = '';
1010                        foreach($ldap_fields as $nul => $entry)
1011                        {
1012                                $err = ldap_modify($this->ldap,$entry['dn'],array('phpgwcontactowner' => $new_owner));
1013                        }
1014
1015                        $this->db->query("UPDATE $this->ext_table SET contact_owner='$new_owner' WHERE contact_owner=$owner",__LINE__,__FILE__);
1016                        return;
1017                }
1018
1019                /* This is where the real work of delete() is done, shared class file contains calling function */
1020                function delete_($id)
1021                {
1022                        if(!$GLOBALS['phpgw_info']['server']['ldap_contact_context'])
1023                        {
1024                                return False;
1025                        }
1026
1027                        $sri = ldap_search($this->ldap, $GLOBALS['phpgw_info']['server']['ldap_contact_context'], 'uidnumber='.$id);
1028                        $ldap_fields = ldap_get_entries($this->ldap, $sri);
1029
1030                        if($ldap_fields[0]['dn'])
1031                        {
1032                                $err = ldap_delete($this->ldap,$ldap_fields[0]['dn']);
1033
1034                                $this->db->query("DELETE FROM $this->ext_table WHERE contact_id='" . (int)$id . "' AND contact_owner='"
1035                                        . $this->account_id . "'",__LINE__,__FILE__);
1036                        }
1037                        else
1038                        {
1039                                return False;
1040                        }
1041                }
1042
1043                // This is for the admin script deleteaccount.php
1044                function delete_all($owner=0)
1045                {
1046                        if(!$GLOBALS['phpgw_info']['server']['ldap_contact_context'])
1047                        {
1048                                return False;
1049                        }
1050
1051                        if($owner)
1052                        {
1053                                $sri = ldap_search($this->ldap, $GLOBALS['phpgw_info']['server']['ldap_contact_context'], 'phpgwcontactowner='.$owner);
1054                                $ldap_fields = ldap_get_entries($this->ldap, $sri);
1055
1056                                $entry = '';
1057                                foreach($ldap_fields as $nul => $entry)
1058                                {
1059                                        $err = ldap_delete($this->ldap,$entry['dn']);
1060                                }
1061
1062                                $this->db->query("DELETE FROM $this->ext_table WHERE contact_owner=$owner",__LINE__,__FILE__);
1063                        }
1064                        return;
1065                }
1066        }
1067?>
Note: See TracBrowser for help on using the repository browser.