~ubuntu-branches/debian/sid/php-horde-turba/sid

« back to all changes in this revision

Viewing changes to turba-4.1.0/lib/Driver/Imsp.php

  • Committer: Package Import Robot
  • Author(s): Mathieu Parent
  • Date: 2013-08-11 13:16:25 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20130811131625-z91stjvq51jr9onv
Tags: 4.1.1-1
New upstream version 4.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
/**
3
 
 * Turba directory driver implementation for an IMSP server.
4
 
 *
5
 
 * Copyright 2010-2013 Horde LLC (http://www.horde.org/)
6
 
 *
7
 
 * See the enclosed file LICENSE for license information (ASL).  If you did
8
 
 * did not receive this file, see http://www.horde.org/licenses/apache.
9
 
 *
10
 
 * @author   Michael Rubinsky <mrubinsk@horde.org>
11
 
 * @category Horde
12
 
 * @license  http://www.horde.org/licenses/apache ASL
13
 
 * @package  Turba
14
 
 */
15
 
class Turba_Driver_Imsp extends Turba_Driver
16
 
{
17
 
    /**
18
 
     * Horde_Imsp object
19
 
     *
20
 
     * @var Horde_Imsp
21
 
     */
22
 
    protected $_imsp;
23
 
 
24
 
    /**
25
 
     * The name of the addressbook.
26
 
     *
27
 
     * @var string
28
 
     */
29
 
    protected $_bookName  = '';
30
 
 
31
 
    /**
32
 
     * Holds if we are authenticated.
33
 
     *
34
 
     * @var boolean
35
 
     */
36
 
    protected $_authenticated = '';
37
 
 
38
 
    /**
39
 
     * Holds name of the field indicating an IMSP group.
40
 
     *
41
 
     * @var string
42
 
     */
43
 
    protected $_groupField = '';
44
 
 
45
 
    /**
46
 
     * Holds value that $_groupField will have if entry is an IMSP group.
47
 
     *
48
 
     * @var string
49
 
     */
50
 
    protected $_groupValue = '';
51
 
 
52
 
    /**
53
 
     * Used to set if the current search is for contacts only.
54
 
     *
55
 
     * @var boolean
56
 
     */
57
 
    protected $_noGroups = '';
58
 
 
59
 
    /**
60
 
     * Driver capabilities.
61
 
     *
62
 
     * @var array
63
 
     */
64
 
    protected $_capabilities = array(
65
 
        'delete_all' => true,
66
 
        'delete_addressbook' => true
67
 
    );
68
 
 
69
 
    /**
70
 
     * Constructs a new Turba imsp driver object.
71
 
     *
72
 
     * @param array $params  Hash containing additional configuration
73
 
     *                       parameters.
74
 
     */
75
 
    public function __construct($name = '', $params)
76
 
    {
77
 
        parent::__construct($name, $params);
78
 
 
79
 
        $this->params       = $params;
80
 
        $this->_groupField  = $params['group_id_field'];
81
 
        $this->_groupValue  = $params['group_id_value'];
82
 
        $this->_myRights    = $params['my_rights'];
83
 
        $this->_perms       = $this->_aclToHordePerms($params['my_rights']);
84
 
        $this->_bookName = $this->getContactOwner();
85
 
 
86
 
        try {
87
 
            $this->_imsp = $GLOBALS['injector']
88
 
                ->getInstance('Horde_Core_Factory_Imsp')
89
 
                ->create('Book', $this->params);
90
 
        } catch (Horde_Exception $e) {
91
 
            $this->_authenticated = false;
92
 
            throw new Turba_Exception($e);
93
 
        }
94
 
        $this->_authenticated = true;
95
 
    }
96
 
 
97
 
    /**
98
 
     * Returns all entries matching $critera.
99
 
     *
100
 
     * @param array $criteria  Array containing the search criteria.
101
 
     * @param array $fields    List of fields to return.
102
 
     *
103
 
     * @return array  Hash containing the search results.
104
 
     */
105
 
    protected function _search(array $criteria, array $fields, array $blobFields = array(), $count_only)
106
 
    {
107
 
        $query = $results = array();
108
 
 
109
 
        if (!$this->_authenticated) {
110
 
            return $query;
111
 
        }
112
 
 
113
 
        /* Get the search criteria. */
114
 
        if (count($criteria)) {
115
 
            foreach ($criteria as $key => $vals) {
116
 
                $names = (strval($key) == 'OR')
117
 
                    ? $this->_doSearch($vals, 'OR')
118
 
                    : $this->_doSearch($vals, 'AND');
119
 
            }
120
 
        }
121
 
 
122
 
        /* Now we have a list of names, get the rest. */
123
 
        $result = $this->_read('name', $names, null, $fields);
124
 
        if (is_array($result)) {
125
 
            $results = $result;
126
 
        }
127
 
 
128
 
        Horde::logMessage(sprintf('IMSP returned %s results', count($results)), 'DEBUG');
129
 
 
130
 
        return $count_only ? count($results) : array_values($results);
131
 
    }
132
 
 
133
 
    /**
134
 
     * Reads the given data from the address book and returns the results.
135
 
     *
136
 
     * @param string $key        The primary key field to use (always 'name'
137
 
     *                           for IMSP).
138
 
     * @param mixed $ids         The ids of the contacts to load.
139
 
     * @param string $owner      Only return contacts owned by this user.
140
 
     * @param array $fields      List of fields to return.
141
 
     * @param array $blobFields  Array of fields containing binary data.
142
 
     *
143
 
     * @return array  Hash containing the search results.
144
 
     * @throws Turba_Exception
145
 
     */
146
 
    protected function _read($key, $ids, $owner, array $fields,
147
 
                             array $blobFields = array())
148
 
    {
149
 
        $results = array();
150
 
 
151
 
        if (!$this->_authenticated) {
152
 
            return $results;
153
 
        }
154
 
 
155
 
        $ids = array_values($ids);
156
 
        $idCount = count($ids);
157
 
        $IMSPGroups = $members = $tmembers = array();
158
 
 
159
 
        for ($i = 0; $i < $idCount; ++$i) {
160
 
            $result = array();
161
 
 
162
 
            try {
163
 
                $temp = isset($IMSPGroups[$ids[$i]])
164
 
                    ? $IMSPGroups[$ids[$i]]
165
 
                    : $this->_imsp->getEntry($this->_bookName, $ids[$i]);
166
 
            } catch (Horde_Imsp_Exception $e) {
167
 
                continue;
168
 
            }
169
 
 
170
 
            $temp['fullname'] = $temp['name'];
171
 
            $isIMSPGroup = false;
172
 
            if (!isset($temp['__owner'])) {
173
 
                $temp['__owner'] = $GLOBALS['registry']->getAuth();
174
 
            }
175
 
 
176
 
            if ((isset($temp[$this->_groupField])) &&
177
 
                ($temp[$this->_groupField] == $this->_groupValue)) {
178
 
                if ($this->_noGroups) {
179
 
                    continue;
180
 
                }
181
 
                if (!isset($IMSPGroups[$ids[$i]])) {
182
 
                    $IMSPGroups[$ids[$i]] = $temp;
183
 
                }
184
 
                // move group ids to end of list
185
 
                if ($idCount > count($IMSPGroups) &&
186
 
                    $idCount - count($IMSPGroups) > $i) {
187
 
                    $ids[] = $ids[$i];
188
 
                    unset($ids[$i]);
189
 
                    $ids = array_values($ids);
190
 
                    --$i;
191
 
                    continue;
192
 
                }
193
 
                $isIMSPGroup = true;
194
 
            }
195
 
            // Get the group members that might have been added from other
196
 
            // IMSP applications, but only if we need more information than
197
 
            // the group name
198
 
            if ($isIMSPGroup &&
199
 
                array_search('__members', $fields) !== false) {
200
 
                if (isset($temp['email'])) {
201
 
                    $emailList = $this->_getGroupEmails($temp['email']);
202
 
                    $count = count($emailList);
203
 
                    for ($j = 0; $j < $count; ++$j) {
204
 
                        $needMember = true;
205
 
                        foreach ($results as $curResult) {
206
 
                            if (!empty($curResult['email']) &&
207
 
                                strtolower($emailList[$j]) == strtolower(trim($curResult['email']))) {
208
 
                                $members[] = $curResult['name'];
209
 
                                $needMember = false;
210
 
                            }
211
 
                        }
212
 
                        if ($needMember) {
213
 
                            $memberName = $this->_imsp->search
214
 
                                ($this->_bookName,
215
 
                                 array('email' => trim($emailList[$j])));
216
 
 
217
 
                            if (count($memberName)) {
218
 
                                $members[] = $memberName[0];
219
 
                            }
220
 
                        }
221
 
                    }
222
 
                }
223
 
                if (!empty($temp['__members'])) {
224
 
                    $tmembers = @unserialize($temp['__members']);
225
 
                }
226
 
 
227
 
                // TODO: Make sure that we are using the correct naming
228
 
                // convention for members regardless of if we are using
229
 
                // shares or not. This is needed to assure groups created
230
 
                // while not using shares won't be lost when transitioning
231
 
                // to shares and visa versa.
232
 
                //$tmembers = $this->_checkMemberFormat($tmembers);
233
 
 
234
 
                $temp['__members'] = serialize($this->_removeDuplicated(
235
 
                                               array($members, $tmembers)));
236
 
                $temp['__type'] = 'Group';
237
 
                $temp['email'] = null;
238
 
                $result = $temp;
239
 
            } else {
240
 
                // IMSP contact.
241
 
                $count = count($fields);
242
 
                for ($j = 0; $j < $count; ++$j) {
243
 
                    if (isset($temp[$fields[$j]])) {
244
 
                        $result[$fields[$j]] = $temp[$fields[$j]];
245
 
                    }
246
 
                }
247
 
            }
248
 
 
249
 
            $results[] = $result;
250
 
        }
251
 
 
252
 
        return $results;
253
 
    }
254
 
 
255
 
    /**
256
 
     * Adds the specified contact to the addressbook.
257
 
     *
258
 
     * @param array $attributes  The attribute values of the contact.
259
 
     * @param array $blob_fields TODO
260
 
     *
261
 
     * @throws Turba_Exception
262
 
     */
263
 
    protected function _add(array $attributes, array $blob_fields = array())
264
 
    {
265
 
        /* We need to map out Turba_Object_Groups back to IMSP groups before
266
 
         * writing out to the server. We need to array_values() it in
267
 
         * case an entry was deleted from the group. */
268
 
        if ($attributes['__type'] == 'Group') {
269
 
            /* We may have a newly created group. */
270
 
            $attributes[$this->_groupField] = $this->_groupValue;
271
 
            if (!isset($attributes['__members'])) {
272
 
                $attributes['__members'] = '';
273
 
                $attributes['email'] = ' ';
274
 
            }
275
 
            $temp = unserialize($attributes['__members']);
276
 
            if (is_array($temp)) {
277
 
                $members = array_values($temp);
278
 
            } else {
279
 
                $members = array();
280
 
            }
281
 
 
282
 
            // This searches the current IMSP address book to see if
283
 
            // we have a match for this member before adding to email
284
 
            // attribute since IMSP groups in other IMSP aware apps
285
 
            // generally require an existing conact entry in the current
286
 
            // address book for each group member (this is necessary for
287
 
            // those sources that may be used both in AND out of Horde).
288
 
            try {
289
 
                $result = $this->_read('name', $members, null, array('email'));
290
 
                $count = count($result);
291
 
                for ($i = 0; $i < $count; ++$i) {
292
 
                    if (isset($result[$i]['email'])) {
293
 
                        $contact = sprintf("%s<%s>\n", $members[$i],
294
 
                                           $result[$i]['email']);
295
 
                        $attributes['email'] .= $contact;
296
 
                    }
297
 
                }
298
 
            } catch (Turba_Exception $e) {}
299
 
        }
300
 
 
301
 
        unset($attributes['__type'], $attributes['fullname']);
302
 
        if (!$this->params['contact_ownership']) {
303
 
            unset($attributes['__owner']);
304
 
        }
305
 
 
306
 
        return $this->_imsp->addEntry($this->_bookName, $attributes);
307
 
    }
308
 
 
309
 
    /**
310
 
     * TODO
311
 
     */
312
 
    protected function _canAdd()
313
 
    {
314
 
        return true;
315
 
    }
316
 
 
317
 
    /**
318
 
     * Deletes the specified object from the IMSP server.
319
 
     *
320
 
     * @throws Turba_Exception
321
 
     */
322
 
    protected function _delete($object_key, $object_id)
323
 
    {
324
 
        try {
325
 
            $this->_imsp->deleteEntry($this->_bookName, $object_id);
326
 
        } catch (Horde_Imsp_Exception $e) {
327
 
            throw new Turba_Exception($e);
328
 
        }
329
 
    }
330
 
 
331
 
    /**
332
 
     * Deletes the address book represented by this driver from the IMSP server.
333
 
     *
334
 
     * @throws Turba_Exception
335
 
     */
336
 
     protected function _deleteAll()
337
 
     {
338
 
         try {
339
 
             $this->_imsp->deleteAddressbook($this->_bookName);
340
 
         } catch (Horde_Imsp_Exception $e) {
341
 
             throw new Turba_Exception($e);
342
 
         }
343
 
     }
344
 
 
345
 
    /**
346
 
     * Saves the specified object to the IMSP server.
347
 
     *
348
 
     * @param Turba_Object $object  The object to save/update.
349
 
     *
350
 
     * @return string  The object id, possibly updated.
351
 
     * @throws Turba_Exception
352
 
     */
353
 
    protected function _save($object)
354
 
    {
355
 
        list($object_key, $object_id) = each($this->toDriverKeys(array('__key' => $object->getValue('__key'))));
356
 
        $attributes = $this->toDriverKeys($object->getAttributes());
357
 
 
358
 
        /* Check if the key changed, because IMSP will just write out
359
 
         * a new entry without removing the previous one. */
360
 
        if ($attributes['name'] != $this->_makeKey($attributes)) {
361
 
            $this->_delete($object_key, $attributes['name']);
362
 
            $attributes['name'] = $this->_makeKey($attributes);
363
 
            $object_id = $attributes['name'];
364
 
        }
365
 
 
366
 
        $this->_add($attributes);
367
 
 
368
 
        return $object_id;
369
 
    }
370
 
 
371
 
    /**
372
 
     * Create an object key for a new object.
373
 
     *
374
 
     * @param array $attributes  The attributes (in driver keys) of the
375
 
     *                           object being added.
376
 
     *
377
 
     * @return string  A unique ID for the new object.
378
 
     */
379
 
    protected function _makeKey($attributes)
380
 
    {
381
 
        return $attributes['fullname'];
382
 
    }
383
 
 
384
 
    /**
385
 
     * Parses out $emailText into an array of pure email addresses
386
 
     * suitable for searching the IMSP datastore with.
387
 
     *
388
 
     * @param string $emailText  Single string containing email addressses.
389
 
     *
390
 
     * @return array  Pure email address.
391
 
     */
392
 
    protected function _getGroupEmails($emailText)
393
 
    {
394
 
        preg_match_all("(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,3})", $emailText, $matches);
395
 
        return $matches[0];
396
 
    }
397
 
 
398
 
    /**
399
 
     * Parses the search criteria, requests the individual searches from the
400
 
     * server and performs any necessary ANDs / ORs on the results.
401
 
     *
402
 
     * @param array  $criteria  Array containing the search criteria.
403
 
     * @param string $glue      Type of search to perform (AND / OR).
404
 
     *
405
 
     * @return array  Array containing contact names that match $criteria.
406
 
     */
407
 
    protected function _doSearch($criteria, $glue)
408
 
    {
409
 
        $results = array();
410
 
        foreach ($criteria as $vals) {
411
 
            if (!empty($vals['OR'])) {
412
 
                $results[] = $this->_doSearch($vals['OR'], 'OR');
413
 
            } elseif (!empty($vals['AND'])) {
414
 
                $results[] = $this->_doSearch($vals['AND'], 'AND');
415
 
            } else {
416
 
                /* If we are here, and we have a ['field'] then we
417
 
                 * must either do the 'AND' or the 'OR' search. */
418
 
                if (isset($vals['field'])) {
419
 
                    $results[] = $this->_sendSearch($vals);
420
 
                } else {
421
 
                    foreach ($vals as $test) {
422
 
                        if (!empty($test['OR'])) {
423
 
                            $results[] = $this->_doSearch($test['OR'], 'OR');
424
 
                        } elseif (!empty($test['AND'])) {
425
 
                            $results[] = $this->_doSearch($test['AND'], 'AND');
426
 
                        } else {
427
 
                            $results[] = $this->_doSearch(array($test), $glue);
428
 
                        }
429
 
                    }
430
 
                }
431
 
            }
432
 
        }
433
 
 
434
 
        return ($glue == 'AND')
435
 
            ? $this->_getDuplicated($results)
436
 
            : $this->_removeDuplicated($results);
437
 
    }
438
 
 
439
 
    /**
440
 
     * Sends a search request to the server.
441
 
     *
442
 
     * @param array $criteria  Array containing the search critera.
443
 
     *
444
 
     * @return array  Array containing a list of names that match the search.
445
 
     */
446
 
    function _sendSearch($criteria)
447
 
    {
448
 
        $names = '';
449
 
        $imspSearch = array();
450
 
        $searchkey = $criteria['field'];
451
 
        $searchval = $criteria['test'];
452
 
        $searchop = $criteria['op'];
453
 
        $hasName = false;
454
 
        $this->_noGroups = false;
455
 
        $cache = $GLOBALS['injector']->getInstance('Horde_Cache');
456
 
        $key = implode(".", array_merge($criteria, array($this->_bookName)));
457
 
 
458
 
        /* Now make sure we aren't searching on a dynamically created
459
 
         * field. */
460
 
        switch ($searchkey) {
461
 
        case 'fullname':
462
 
            if (!$hasName) {
463
 
                $searchkey = 'name';
464
 
                $hasName = true;
465
 
            } else {
466
 
                $searchkey = '';
467
 
            }
468
 
            break;
469
 
 
470
 
        case '__owner':
471
 
            if (!$this->params['contact_ownership']) {
472
 
                $searchkey = '';
473
 
                $hasName = true;
474
 
            }
475
 
            break;
476
 
        }
477
 
 
478
 
        /* Are we searching for only Turba_Object_Groups or Turba_Objects?
479
 
         * This is needed so the 'Show Lists' and 'Show Contacts'
480
 
         * links work correctly in Turba. */
481
 
        if ($searchkey == '__type') {
482
 
            switch ($searchval) {
483
 
            case 'Group':
484
 
                $searchkey = $this->_groupField;
485
 
                $searchval = $this->_groupValue;
486
 
                break;
487
 
 
488
 
            case 'Object':
489
 
                if (!$hasName) {
490
 
                    $searchkey = 'name';
491
 
                    $searchval = '';
492
 
                    $hasName = true;
493
 
                } else {
494
 
                    $searchkey = '';
495
 
                }
496
 
                $this->_noGroups = true;
497
 
                break;
498
 
            }
499
 
        }
500
 
 
501
 
        if (!$searchkey == '') {
502
 
            // Check $searchval for content and for strict matches.
503
 
            if (strlen($searchval) > 0) {
504
 
                if ($searchop == 'LIKE') {
505
 
                    $searchval = '*' . $searchval . '*';
506
 
                }
507
 
            } else {
508
 
                $searchval = '*';
509
 
            }
510
 
            $imspSearch[$searchkey] = $searchval;
511
 
        }
512
 
        if (!count($imspSearch)) {
513
 
            $imspSearch['name'] = '*';
514
 
        }
515
 
 
516
 
        /* Finally get to the command.  Check the cache first, since each
517
 
         * 'Turba' search may consist of a number of identical IMSP
518
 
         * searchaddress calls in order for the AND and OR parts to work
519
 
         * correctly.  15 Second lifetime should be reasonable for this. This
520
 
         * should reduce load on IMSP server somewhat.*/
521
 
        $results = $cache->get($key, 15);
522
 
 
523
 
        if ($results) {
524
 
            $names = unserialize($results);
525
 
        }
526
 
 
527
 
        if (!$names) {
528
 
            try {
529
 
                $names = $this->_imsp->search($this->_bookName, $imspSearch);
530
 
                $cache->set($key, serialize($names));
531
 
                return $names;
532
 
            } catch (Horde_Imsp_Exception $e) {
533
 
                $GLOBALS['notification']->push($names, 'horde.error');
534
 
            }
535
 
        } else {
536
 
            return $names;
537
 
        }
538
 
    }
539
 
 
540
 
    /**
541
 
     * Returns only those names that are duplicated in $names
542
 
     *
543
 
     * @param array $names  A nested array of arrays containing names
544
 
     *
545
 
     * @return array  Array containing the 'AND' of all arrays in $names
546
 
     */
547
 
    protected function _getDuplicated($names)
548
 
    {
549
 
        $matched = $results = array();
550
 
 
551
 
        /* If there is only 1 array, simply return it. */
552
 
        if (count($names) < 2) {
553
 
            return $names[0];
554
 
        }
555
 
 
556
 
        for ($i = 0; $i < count($names); ++$i) {
557
 
            if (is_array($names[$i])) {
558
 
                $results = array_merge($results, $names[$i]);
559
 
            }
560
 
        }
561
 
 
562
 
        $search = array_count_values($results);
563
 
        foreach ($search as $key => $value) {
564
 
            if ($value > 1) {
565
 
                $matched[] = $key;
566
 
            }
567
 
        }
568
 
 
569
 
        return $matched;
570
 
    }
571
 
 
572
 
    /**
573
 
     * Returns an array with all duplicate names removed.
574
 
     *
575
 
     * @param array $names  Nested array of arrays containing names.
576
 
     *
577
 
     * @return array  Array containg the 'OR' of all arrays in $names.
578
 
     */
579
 
    protected function _removeDuplicated($names)
580
 
    {
581
 
        $unames = array();
582
 
        for ($i = 0; $i < count($names); ++$i) {
583
 
            if (is_array($names[$i])) {
584
 
                $unames = array_merge($unames, $names[$i]);
585
 
            }
586
 
        }
587
 
 
588
 
        return array_unique($unames);
589
 
    }
590
 
 
591
 
    /**
592
 
     * Checks if the current user has the requested permission
593
 
     * on this source.
594
 
     *
595
 
     * @param integer $perm  The permission to check for.
596
 
     *
597
 
     * @return boolean  true if user has permission, false otherwise.
598
 
     */
599
 
    public function hasPermission($perm)
600
 
    {
601
 
        return $this->_perms & $perm;
602
 
    }
603
 
 
604
 
    /**
605
 
     * Converts an acl string to a Horde Permissions bitmask.
606
 
     *
607
 
     * @param string $acl  A standard, IMAP style acl string.
608
 
     *
609
 
     * @return integer  Horde Permissions bitmask.
610
 
     */
611
 
    protected function _aclToHordePerms($acl)
612
 
    {
613
 
        $hPerms = 0;
614
 
 
615
 
        if (strpos($acl, 'w') !== false) {
616
 
            $hPerms |= Horde_Perms::EDIT;
617
 
        }
618
 
        if (strpos($acl, 'r') !== false) {
619
 
            $hPerms |= Horde_Perms::READ;
620
 
        }
621
 
        if (strpos($acl, 'd') !== false) {
622
 
            $hPerms |= Horde_Perms::DELETE;
623
 
        }
624
 
        if (strpos($acl, 'l') !== false) {
625
 
            $hPerms |= Horde_Perms::SHOW;
626
 
        }
627
 
 
628
 
        return $hPerms;
629
 
    }
630
 
 
631
 
    /**
632
 
     * Creates a new Horde_Share and creates the address book
633
 
     * on the IMSP server.
634
 
     *
635
 
     * @param array  The params for the share.
636
 
     *
637
 
     * @return Horde_Share  The share object.
638
 
     * @throws Turba_Exception
639
 
     */
640
 
    public function createShare($share_id, $params)
641
 
    {
642
 
        $params['params']['name'] = $this->params['username'];
643
 
        if (!isset($params['default']) || $params['default'] !== true) {
644
 
            $params['params']['name'] .= '.' . $params['name'];
645
 
        }
646
 
 
647
 
        $result = Turba::createShare($share_id, $params);
648
 
        try {
649
 
            Horde_Core_Imsp_Utils::createBook($GLOBALS['cfgSources']['imsp'], $params['params']['name']);
650
 
        } catch (Horde_Imsp_Exception $e) {
651
 
            throw new Turba_Exception($e);
652
 
        }
653
 
 
654
 
        return $result;
655
 
    }
656
 
 
657
 
    /**
658
 
     * Helper function to count the occurances of the ':' * delimiter in group
659
 
     * member entries.
660
 
     *
661
 
     * @param string $in  The group member entry.
662
 
     *
663
 
     * @return integer  The number of ':' in $in.
664
 
     */
665
 
    protected function _countDelimiters($in)
666
 
    {
667
 
        $cnt = $pos = 0;
668
 
        while (($pos = strpos($in, ':', $pos + 1)) !== false) {
669
 
            ++$cnt;
670
 
        }
671
 
 
672
 
        return $cnt;
673
 
    }
674
 
 
675
 
    /**
676
 
     * Returns the owner for this contact. For an IMSP source, this should be
677
 
     * the name of the address book.
678
 
     *
679
 
     * @return string  TODO
680
 
     */
681
 
    protected function _getContactOwner()
682
 
    {
683
 
       return $this->params['name'];
684
 
    }
685
 
 
686
 
    /**
687
 
     * Check if the passed in share is the default share for this source.
688
 
     *
689
 
     * @see turba/lib/Turba_Driver#checkDefaultShare($share, $srcconfig)
690
 
     *
691
 
     * @return TODO
692
 
     */
693
 
    public function checkDefaultShare($share, $srcConfig)
694
 
    {
695
 
        $params = @unserialize($share->get('params'));
696
 
        if (!isset($params['default'])) {
697
 
            $params['default'] = ($params['name'] == $srcConfig['params']['username']);
698
 
            $share->set('params', serialize($params));
699
 
            $share->save();
700
 
        }
701
 
 
702
 
        return $params['default'];
703
 
    }
704
 
 
705
 
}