Overview

Packages

  • Kolab
    • Server

Classes

  • Horde_Kolab_Server_Composite
  • Horde_Kolab_Server_Connection_File
  • Horde_Kolab_Server_Connection_Mock
  • Horde_Kolab_Server_Connection_Mock_Ldap
  • Horde_Kolab_Server_Connection_Mock_Search
  • Horde_Kolab_Server_Connection_Simpleldap
  • Horde_Kolab_Server_Connection_Splittedldap
  • Horde_Kolab_Server_Decorator_Clean
  • Horde_Kolab_Server_Decorator_Count
  • Horde_Kolab_Server_Decorator_Log
  • Horde_Kolab_Server_Decorator_Map
  • Horde_Kolab_Server_Exception
  • Horde_Kolab_Server_Exception_Bindfailed
  • Horde_Kolab_Server_Exception_Novalue
  • Horde_Kolab_Server_Factory
  • Horde_Kolab_Server_Ldap
  • Horde_Kolab_Server_Ldap_Changes
  • Horde_Kolab_Server_Ldap_Filtered
  • Horde_Kolab_Server_Ldap_Standard
  • Horde_Kolab_Server_List_Base
  • Horde_Kolab_Server_Object_Attribute_Base
  • Horde_Kolab_Server_Object_Attribute_Createtimestamp
  • Horde_Kolab_Server_Object_Attribute_Createtimestampdate
  • Horde_Kolab_Server_Object_Attribute_Decorator
  • Horde_Kolab_Server_Object_Attribute_Default
  • Horde_Kolab_Server_Object_Attribute_Empty
  • Horde_Kolab_Server_Object_Attribute_External
  • Horde_Kolab_Server_Object_Attribute_Field
  • Horde_Kolab_Server_Object_Attribute_Firstnamelastname
  • Horde_Kolab_Server_Object_Attribute_Guid
  • Horde_Kolab_Server_Object_Attribute_Id
  • Horde_Kolab_Server_Object_Attribute_Internal
  • Horde_Kolab_Server_Object_Attribute_Locked
  • Horde_Kolab_Server_Object_Attribute_Modifytimestamp
  • Horde_Kolab_Server_Object_Attribute_Modifytimestampdate
  • Horde_Kolab_Server_Object_Attribute_Objectclass
  • Horde_Kolab_Server_Object_Attribute_Openldapaci
  • Horde_Kolab_Server_Object_Attribute_Required
  • Horde_Kolab_Server_Object_Attribute_Single
  • Horde_Kolab_Server_Object_Attribute_Value
  • Horde_Kolab_Server_Object_Attribute_Writelock
  • Horde_Kolab_Server_Object_Base
  • Horde_Kolab_Server_Object_Factory
  • Horde_Kolab_Server_Object_Groupofnames
  • Horde_Kolab_Server_Object_Hash
  • Horde_Kolab_Server_Object_Inetorgperson
  • Horde_Kolab_Server_Object_Kolab
  • Horde_Kolab_Server_Object_Kolab_Address
  • Horde_Kolab_Server_Object_Kolab_Administrator
  • Horde_Kolab_Server_Object_Kolab_Adminrole
  • Horde_Kolab_Server_Object_Kolab_Distlist
  • Horde_Kolab_Server_Object_Kolab_Domainmaintainer
  • Horde_Kolab_Server_Object_Kolab_Maintainer
  • Horde_Kolab_Server_Object_Kolab_User
  • Horde_Kolab_Server_Object_Kolabgermanbankarrangement
  • Horde_Kolab_Server_Object_Kolabgroupofnames
  • Horde_Kolab_Server_Object_Kolabinetorgperson
  • Horde_Kolab_Server_Object_Kolabpop3account
  • Horde_Kolab_Server_Object_Kolabsharedfolder
  • Horde_Kolab_Server_Object_Mcached
  • Horde_Kolab_Server_Object_Organizationalperson
  • Horde_Kolab_Server_Object_Person
  • Horde_Kolab_Server_Object_Top
  • Horde_Kolab_Server_Objects_Base
  • Horde_Kolab_Server_Query_Element_And
  • Horde_Kolab_Server_Query_Element_Approx
  • Horde_Kolab_Server_Query_Element_Begins
  • Horde_Kolab_Server_Query_Element_Contains
  • Horde_Kolab_Server_Query_Element_Ends
  • Horde_Kolab_Server_Query_Element_Equals
  • Horde_Kolab_Server_Query_Element_Greater
  • Horde_Kolab_Server_Query_Element_Group
  • Horde_Kolab_Server_Query_Element_Less
  • Horde_Kolab_Server_Query_Element_Mapped
  • Horde_Kolab_Server_Query_Element_Not
  • Horde_Kolab_Server_Query_Element_Or
  • Horde_Kolab_Server_Query_Element_Single
  • Horde_Kolab_Server_Query_Ldap
  • Horde_Kolab_Server_Result_Ldap
  • Horde_Kolab_Server_Schema_Base
  • Horde_Kolab_Server_Schema_Decorator_Cache
  • Horde_Kolab_Server_Search_Base
  • Horde_Kolab_Server_Search_Operation_Addressesforuidormail
  • Horde_Kolab_Server_Search_Operation_Attributes
  • Horde_Kolab_Server_Search_Operation_Base
  • Horde_Kolab_Server_Search_Operation_Children
  • Horde_Kolab_Server_Search_Operation_Constraint_Single
  • Horde_Kolab_Server_Search_Operation_Constraint_Strict
  • Horde_Kolab_Server_Search_Operation_Groupsformember
  • Horde_Kolab_Server_Search_Operation_Guid
  • Horde_Kolab_Server_Search_Operation_Guidforalias
  • Horde_Kolab_Server_Search_Operation_Guidforcn
  • Horde_Kolab_Server_Search_Operation_Guidforkolabusers
  • Horde_Kolab_Server_Search_Operation_Guidformail
  • Horde_Kolab_Server_Search_Operation_Guidformailoralias
  • Horde_Kolab_Server_Search_Operation_Guidforuid
  • Horde_Kolab_Server_Search_Operation_Guidforuidormail
  • Horde_Kolab_Server_Search_Operation_Guidforuidormailoralias
  • Horde_Kolab_Server_Search_Operation_Mailforuidormail
  • Horde_Kolab_Server_Search_Operation_Restrictgroups
  • Horde_Kolab_Server_Search_Operation_Restrictkolab
  • Horde_Kolab_Server_Structure_Attribute_Double
  • Horde_Kolab_Server_Structure_Attribute_Value
  • Horde_Kolab_Server_Structure_Base
  • Horde_Kolab_Server_Structure_Kolab
  • Horde_Kolab_Server_Structure_Ldap

Interfaces

  • Horde_Kolab_Server_Connection_Interface
  • Horde_Kolab_Server_Interface
  • Horde_Kolab_Server_List_Interface
  • Horde_Kolab_Server_Object_Attribute_Interface
  • Horde_Kolab_Server_Object_Interface
  • Horde_Kolab_Server_Object_Searches
  • Horde_Kolab_Server_Objects_Interface
  • Horde_Kolab_Server_Query_Element_Interface
  • Horde_Kolab_Server_Query_Interface
  • Horde_Kolab_Server_Result_Interface
  • Horde_Kolab_Server_Schema_Interface
  • Horde_Kolab_Server_Search_Interface
  • Horde_Kolab_Server_Search_Operation_Interface
  • Horde_Kolab_Server_Structure_Attribute_Interface
  • Horde_Kolab_Server_Structure_Interface
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * A driver for simulating a Kolab user database stored in LDAP.
  4:  *
  5:  * PHP version 5
  6:  *
  7:  * @category Kolab
  8:  * @package  Kolab_Server
  9:  * @author   Gunnar Wrobel <wrobel@pardus.de>
 10:  * @license  http://www.horde.org/licenses/lgpl21 LGPL 2.1
 11:  * @link     http://pear.horde.org/index.php?package=Kolab_Server
 12:  */
 13: 
 14: /**
 15:  * This class provides a class for testing the Kolab Server DB.
 16:  *
 17:  * Copyright 2008-2012 Horde LLC (http://www.horde.org/)
 18:  *
 19:  * See the enclosed file COPYING for license information (LGPL). If you
 20:  * did not receive this file, see http://www.horde.org/licenses/lgpl21.
 21:  *
 22:  * @category Kolab
 23:  * @package  Kolab_Server
 24:  * @author   Gunnar Wrobel <wrobel@pardus.de>
 25:  * @license  http://www.horde.org/licenses/lgpl21 LGPL 2.1
 26:  * @link     http://pear.horde.org/index.php?package=Kolab_Server
 27:  */
 28: class Horde_Kolab_Server_Connection_Mock_Ldap
 29: {
 30:     /**
 31:      * Connection parameters.
 32:      *
 33:      * @var array
 34:      */
 35:     private $_params;
 36: 
 37:     /**
 38:      * The current database data.
 39:      *
 40:      * @var array
 41:      */
 42:     private $_data;
 43: 
 44:     /**
 45:      * Is the connection bound via username / password?
 46:      *
 47:      * @var boolean
 48:      */
 49:     private $_bound = false;
 50: 
 51:     /**
 52:      * Constructor.
 53:      *
 54:      * @param array $params Connection parameters.
 55:      * @param array $data   Mockup LDAP data.
 56:      */
 57:     public function __construct(array $params, array $data)
 58:     {
 59:         $this->_params = $params;
 60:         $this->_data   = $data;
 61:     }
 62: 
 63:     /**
 64:      * Binds the LDAP connection with a specific user and pass.
 65:      *
 66:      * @param string $dn DN to bind with
 67:      * @param string $pw Password associated to this DN.
 68:      *
 69:      * @return NULL
 70:      *
 71:      * @throws Horde_Kolab_Server_Exception If the user does not exit, he has no
 72:      *                                      password, provided an incorrect
 73:      *                                      password or anonymous binding is not
 74:      *                                      allowed.
 75:      */
 76:     public function bind($dn = '', $pw = '')
 77:     {
 78:         if ($dn == '' && $pw == '') {
 79:             if (isset($this->_params['binddn'])
 80:                 && isset($this->_params['bindpw'])) {
 81:                 $dn = $this->_params['binddn'];
 82:                 $pw = $this->_params['bindpw'];
 83:             }
 84:         }
 85: 
 86:         if ($dn != '') {
 87:             if (!isset($this->_data[$dn])) {
 88:                 throw new Horde_Kolab_Server_Exception('User does not exist!');
 89:             }
 90: 
 91:             if (!isset($this->_data[$dn]['data']['userPassword'][0])) {
 92:                 throw new Horde_Kolab_Server_Exception('User has no password entry!');
 93:             }
 94:             if ($this->_data[$dn]['data']['userPassword'][0] != $pw) {
 95:                 throw new Horde_Kolab_Server_Exception_Bindfailed('Incorrect password!');
 96:             }
 97:         } else if (!empty($this->_params['no_anonymous_bind'])) {
 98:             throw new Horde_Kolab_Server_Exception('Anonymous bind is not allowed!');
 99:         }
100: 
101:         $this->_bound = true;
102:     }
103: 
104:     /**
105:     * Get a specific entry based on the DN
106:     *
107:     * @param string $dn   DN of the entry that should be fetched
108:     * @param array  $attr Array of Attributes to select. If ommitted, all attributes are fetched.
109:     *
110:     * @return Horde_Ldap_Entry|Horde_Ldap_Error    Reference to a Horde_Ldap_Entry object or Horde_Ldap_Error object
111:     * @todo Maybe check against the shema should be done to be sure the attribute type exists
112:     */
113:     public function getEntry($dn, $attr = array())
114:     {
115:         $this->_checkBound();
116: 
117:         if (!is_array($attr)) {
118:             $attr = array($attr);
119:         }
120:         $result = $this->search($dn, '(objectClass=*)',
121:                                 array('scope' => 'base', 'attributes' => $attr));
122:         if ($result->count() == 0) {
123:             throw new Horde_Kolab_Server_Exception('Could not fetch entry '.$dn.': no entry found');
124:         }
125:         $entry = $result->shiftEntry();
126:         if (false == $entry) {
127:             throw new Horde_Kolab_Server_Exception('Could not fetch entry (error retrieving entry from search result)');
128:         }
129:         return $entry;
130:     }
131: 
132:     /**
133:      * Search for object data.
134:      *
135:      * @param string $base   The search base
136:      * @param string $filter The LDAP search filter.
137:      * @param string $params Additional search parameters.
138:      *
139:      * @return array The result array.
140:      *
141:      * @throws Horde_Kolab_Server_Exception If the search operation encountered
142:      *                                      a problem.
143:      */
144:     public function search($base = null, $filter = null, $params = array())
145:     {
146:         $this->_checkBound();
147: 
148:         if (isset($params['attributes'])) {
149:             $attributes = $params['attributes'];
150:             if (!is_array($attributes)) {
151:                 $attributes = array($attributes);
152:             }
153:         } else {
154:             $attributes = array();
155:         }
156: 
157:         $result = array();
158: 
159:         if (!empty($filter)) {
160:             $filter = $this->parse($filter);
161:             $result = $this->doSearch($filter, $attributes);
162:         } else {
163:             if (!isset($params['scope']) || $params['scope'] == 'sub') {
164:                 foreach (array_keys($this->_data) as $dn) {
165:                     if (empty($attributes)) {
166:                         $result[] = $this->_data[$dn];
167:                     } else {
168:                         $selection = $this->_data[$dn];
169:                         foreach ($this->_data[$dn]['data']
170:                                  as $attr => $value) {
171:                             if (!in_array($attr, $attributes)) {
172:                                 unset($selection['data'][$attr]);
173:                             }
174:                         }
175:                         $result[] = $selection;
176:                     }
177:                 }
178:             } else if ($params['scope'] == 'base') {
179:                 if (isset($this->_data[$base])) {
180:                     $result[] = $this->_data[$base];
181:                 } else {
182:                     $result = array();
183:                 }
184:             } else if ($params['scope'] == 'one') {
185:                 throw new Horde_Kolab_Server_Exception('Not implemented!');
186:             }
187:         }
188: 
189:         if (empty($result)) {
190:             $search = new Horde_Kolab_Server_Connection_Mock_Search(array());
191:             return $search;
192:         }
193: 
194:         if (!empty($base)) {
195:             $subtree = array();
196:             foreach ($result as $entry) {
197:                 if (preg_match('/' . $base . '$/', $entry['dn'])) {
198:                     $subtree[] = $entry;
199:                 }
200:             }
201:             $result = $subtree;
202:         }
203: 
204:         $search = new Horde_Kolab_Server_Connection_Mock_Search($this->getEntries($result));
205:         return $search;
206:     }
207: 
208:     /**
209:      * Return the entries of a result.
210:      *
211:      * @param array $result The LDAP search result.
212:      *
213:      * @return mixed The entries of the result or false.
214:      */
215:     public function getEntries($result)
216:     {
217:         if (is_array($result)) {
218:             $data = array();
219:             foreach ($result as $entry) {
220:                 $t       = $entry['data'];
221:                 $t['dn'] = $entry['dn'];
222:                 $data[$entry['dn']]  = $t;
223:             }
224:             return $data;
225:         }
226:         return false;
227:     }
228: 
229:     /**
230:      * Parse LDAP filter.
231:      * Partially derived from Net_LDAP_Filter.
232:      *
233:      * @param string $filter The filter string.
234:      *
235:      * @return array An array of the parsed filter.
236:      *
237:      * @throws Horde_Kolab_Server_Exception If parsing the filter expression
238:      *                                      fails.
239:      */
240:     public function parse($filter)
241:     {
242:         $result = array();
243:         if (preg_match('/^\((.+?)\)$/', $filter, $matches)) {
244:             if (in_array(substr($matches[1], 0, 1), array('!', '|', '&'))) {
245:                 $result['op']  = substr($matches[1], 0, 1);
246:                 $result['sub'] = $this->parseSub(substr($matches[1], 1));
247:                 return $result;
248:             } else {
249:                 if (stristr($matches[1], ')(')) {
250:                     throw new Horde_Kolab_Server_Exception('Filter parsing error: invalid filter syntax - multiple leaf components detected!');
251:                 } else {
252:                     $filter_parts = preg_split('/(?<!\\\\)(=|=~|>|<|>=|<=)/',
253:                                                $matches[1], 2,
254:                                                PREG_SPLIT_DELIM_CAPTURE);
255:                     if (count($filter_parts) != 3) {
256:                         throw new Horde_Kolab_Server_Exception('Filter parsing error: invalid filter syntax - unknown matching rule used');
257:                     } else {
258:                         $result['att'] = $filter_parts[0];
259:                         $result['log'] = $filter_parts[1];
260:                         $val = Horde_Ldap_Util::unescapeFilterValue($filter_parts[2]);
261:                         $result['val'] = $val[0];
262:                         return $result;
263:                     }
264:                 }
265:             }
266:         } else {
267:             throw new Horde_Kolab_Server_Exception(sprintf("Filter parsing error: %s - filter components must be enclosed in round brackets",
268:                                                            $filter));
269:         }
270:     }
271: 
272:     /**
273:      * Parse a LDAP subfilter.
274:      *
275:      * @param string $filter The subfilter string.
276:      *
277:      * @return array An array of the parsed subfilter.
278:      *
279:      * @throws Horde_Kolab_Server_Exception
280:      */
281:     public function parseSub($filter)
282:     {
283:         $result  = array();
284:         $level   = 0;
285:         $collect = '';
286:         while (preg_match('/^(\(.+?\))(.*)/', $filter, $matches)) {
287:             if (in_array(substr($matches[1], 0, 2), array('(!', '(|', '(&'))) {
288:                 $level++;
289:             }
290:             if ($level) {
291:                 $collect .= $matches[1];
292:                 if (substr($matches[2], 0, 1) == ')') {
293:                     $collect   .= ')';
294:                     $matches[2] = substr($matches[2], 1);
295:                     $level--;
296:                     if (!$level) {
297:                         $result[] = $this->parse($collect);
298:                     }
299:                 }
300:             } else {
301:                 $result[] = $this->parse($matches[1]);
302:             }
303:             $filter = $matches[2];
304:         }
305:         return $result;
306:     }
307: 
308:     /**
309:      * Perform the search.
310:      *
311:      * @param array $filter     Filter criteria-
312:      * @param array $attributes Restrict the search result to
313:      *                          these attributes.
314:      *
315:      * @return array A LDAP serach result.
316:      *
317:      * @throws Horde_Kolab_Server_Exception If the search operation is not
318:      *                                      available.
319:      */
320:     public function doSearch($filter, $attributes = null)
321:     {
322:         if (isset($filter['log'])) {
323:             $result = array();
324:             foreach ($this->_data as $element) {
325:                 if (isset($element['data'][$filter['att']])) {
326:                     switch ($filter['log']) {
327:                     case '=':
328:                         $value = $element['data'][$filter['att']];
329:                         if (!empty($value) && is_array($value)) {
330:                             $keys = array_keys($value);
331:                             $first = $value[$keys[0]];
332:                         } else {
333:                             $first = $value;
334:                         }
335:                         if ((($filter['val'] == '*')
336:                              && !empty($value))
337:                             || $value == $filter['val']
338:                             || (substr($filter['val'], 0, 1) == '*'
339:                                 && substr($filter['val'], strlen($filter['val']) - 1) == '*'
340:                                 && strpos($first, substr($filter['val'], 1, strlen($filter['val']) - 2)) !== false)
341:                             || (is_array($value)
342:                                 && in_array($filter['val'], $value))) {
343:                             if (empty($attributes)) {
344:                                 $result[] = $element;
345:                             } else {
346:                                 $selection = $element;
347:                                 foreach ($element['data'] as $attr => $value) {
348:                                     if (!in_array($attr, $attributes)) {
349:                                         unset($selection['data'][$attr]);
350:                                     }
351:                                 }
352:                                 $result[] = $selection;
353:                             }
354:                         }
355:                         break;
356:                     default:
357:                         throw new Horde_Kolab_Server_Exception("Not implemented!");
358:                     }
359:                 }
360:             }
361:             return $result;
362:         } else {
363:             $subresult   = array();
364:             $filtercount = count($filter['sub']);
365:             foreach ($filter['sub'] as $subfilter) {
366:                 $subresult = array_merge($subresult,
367:                                          $this->doSearch($subfilter,
368:                                                          $attributes));
369:             }
370:             $result = array();
371:             $dns    = array();
372:             foreach ($subresult as $element) {
373:                 $dns[] = $element['dn'];
374: 
375:                 $result[$element['dn']] = $element;
376:             }
377:             switch ($filter['op']) {
378:             case '&':
379:                 $count     = array_count_values($dns);
380:                 $selection = array();
381:                 foreach ($count as $dn => $value) {
382:                     if ($value == $filtercount) {
383:                         $selection[] = $result[$dn];
384:                     }
385:                 }
386:                 return $selection;
387:             case '|':
388:                 return array_values($result);
389:             case '!':
390:                 $dns = array();
391:                 foreach ($result as $entry) {
392:                     if (!in_array($entry['dn'], $dns) ) {
393:                         $dns[] = $entry['dn'];
394:                     }
395:                 }
396:                 $all_dns = array_keys($this->_data);
397:                 $diff    = array_diff($all_dns, $dns);
398: 
399:                 $result = array();
400:                 foreach ($diff as $dn) {
401:                     if (empty($attributes)) {
402:                         $result[] = $this->_data[$dn];
403:                     } else {
404:                         $selection = $this->_data[$dn];
405:                         foreach ($this->_data[$dn]['data']
406:                                  as $attr => $value) {
407:                             if (!in_array($attr, $attributes)) {
408:                                 unset($selection['data'][$attr]);
409:                             }
410:                         }
411:                         $result[] = $selection;
412:                     }
413:                 }
414:                 return $result;
415:             default:
416:                 throw new Horde_Kolab_Server_Exception("Not implemented!");
417:             }
418:         }
419:     }
420: 
421:     /**
422:     * Add a new entryobject to a directory.
423:     *
424:     * @param Horde_Ldap_Entry $entry Horde_Ldap_Entry
425:     *
426:     * @return Horde_Ldap_Error|true Horde_Ldap_Error object or true
427:     */
428:     public function add($entry)
429:     {
430:         $this->_checkBound();
431: 
432:         $ldap_data = $this->toStorage($entry->getValues());
433: 
434:         $guid = $entry->getDn();
435: 
436:         $this->_data[$guid] = array(
437:             'dn' => $guid,
438:             'data' => array_merge($ldap_data,
439:                                   array('dn' => $guid)),
440:         );
441:     }
442: 
443:     /**
444:     * Modify an ldapentry directly on the server
445:     *
446:     * @param string|Horde_Ldap_Entry &$entry DN-string or Horde_Ldap_Entry
447:     * @param array                 $parms  Array of changes
448:     *
449:     * @access public
450:     * @return Horde_Ldap_Error|true Horde_Ldap_Error object or true
451:     */
452:     public function modify($entry, $data = array())
453:     {
454:         $this->_checkBound();
455: 
456:         $guid = $entry->getDn();
457: 
458:         if (isset($data['delete'])) {
459:             foreach ($data['delete'] as $k => $v) {
460:                 if (is_int($k)) {
461:                     if (isset($this->_data[$guid]['data'][$w])) {
462:                         /** Delete a complete attribute */
463:                         unset($this->_data[$guid]['data'][$w]);
464:                     }
465:                 } else {
466:                     if (isset($this->_data[$guid]['data'][$l])) {
467:                         if (!is_array($v)) {
468:                             $v = array($v);
469:                         }
470:                         foreach ($v as $w) {
471:                             $key = array_search($w, $this->_data[$guid]['data'][$l]);
472:                             if ($key !== false) {
473:                                 /** Delete a single value */
474:                                 unset($this->_data[$guid]['data'][$l][$key]);
475:                             }
476:                         }
477:                     }
478:                 }
479:             }
480:         }
481: 
482:         if (isset($data['replace'])) {
483:             $ldap_data = $this->toStorage($data['replace']);
484: 
485:             $this->_data[$guid] = array(
486:                 'dn' => $guid,
487:                 'data' => array_merge($this->_data[$guid]['data'],
488:                                       $ldap_data,
489:                                       array('dn' => $guid)),
490:             );
491:         }
492: 
493:         if (isset($data['add'])) {
494:             $ldap_data = $this->toStorage($data['add']);
495: 
496:             foreach ($ldap_data as $k => $v) {
497:                 if (is_array($v)) {
498:                     foreach ($v as $w) {
499:                         $this->_data[$guid]['data'][$k][] = $w;
500:                     }
501:                 } else {
502:                     $this->_data[$guid]['data'][$k][] = $v;
503:                 }
504:                 $this->_data[$guid]['data'][$k] = array_values($this->_data[$guid]['data'][$k]);
505:             }
506:         }
507:     }
508: 
509:     /**
510:      * Delete an object.
511:      *
512:      * @param string $uid The UID of the object to be deleted.
513:      *
514:      * @return NULL
515:      *
516:      * @throws Horde_Kolab_Server_Exception
517:      */
518:     public function delete($uid)
519:     {
520:         $this->_checkBound();
521: 
522:         if (isset($this->_data[$uid])) {
523:             unset($this->_data[$uid]);
524:         } else {
525:             throw new Horde_Kolab_Server_MissingObjectException(sprintf("No such object: %s",
526:                                                                         $uid));
527:         }
528:     }
529: 
530:     /**
531:      * Rename an object.
532:      *
533:      * @param string $uid The UID of the object to be renamed.
534:      * @param string $new The new UID of the object.
535:      *
536:      * @return NULL
537:      *
538:      * @throws Horde_Kolab_Server_Exception
539:      */
540:     public function move($uid, $new)
541:     {
542:         $this->_checkBound();
543: 
544:         if (isset($this->_data[$uid])) {
545:             $this->_data[$new] = $this->_data[$uid];
546:             unset($this->_data[$uid]);
547:         }
548:     }
549: 
550:     public function schema()
551:     {
552:         //@todo: implement
553:     }
554: 
555:     /**
556:      * Rewrite a data array to our internal storage format.
557:      *
558:      * @param array   $data    The attributes of the object to be added/replaced.
559:      *
560:      * @return array  The transformed data set.
561:      */
562:     protected function toStorage($data)
563:     {
564:         $ldap_data = array();
565:         foreach ($data as $key => $val) {
566:             if (!is_array($val)) {
567:                 $val = array($val);
568:             }
569:             $ldap_data[$key] = $val;
570:         }
571:         return $ldap_data;
572:     }
573: 
574:     /**
575:      * Check if the current connection is bound.
576:      *
577:      * @return NULL
578:      *
579:      * @throws Horde_Kolab_Server_Exception If the connection is not bound.
580:      */
581:     private function _checkBound()
582:     {
583:         if (!$this->_bound) {
584:             throw new Horde_Kolab_Server_Exception('Unbound connection!');
585:         }
586:     }
587: }
588: 
API documentation generated by ApiGen