1: <?php
2: /**
3: * A structural handler for the tree of objects 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 methods to deal with the LDAP tree structure.
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_Structure_Ldap extends Horde_Kolab_Server_Structure_Base
29: {
30: /**
31: * Returns the set of objects supported by this structure.
32: *
33: * @return array An array of supported objects.
34: */
35: public function getSupportedObjects()
36: {
37: return array(
38: 'Horde_Kolab_Server_Object',
39: );
40: }
41:
42: /**
43: * Returns the set of search operations supported by this object type.
44: *
45: * @return array An array of supported search operations.
46: */
47: public function getSearchOperations()
48: {
49: $searches = array(
50: 'Horde_Kolab_Server_Search_Operation_Guid',
51: 'Horde_Kolab_Server_Search_Operation_Attributes',
52: 'Horde_Kolab_Server_Search_Operation_Children',
53: 'Horde_Kolab_Server_Search_Operation_Guidforcn',
54: );
55: return $searches;
56: }
57:
58: /**
59: * Determine the type of an object by its tree position and other
60: * parameters.
61: *
62: * @param string $guid The GUID of the object to examine.
63: *
64: * @return string The class name of the corresponding object type.
65: *
66: * @throws Horde_Kolab_Server_Exception If the object type is unknown.
67: */
68: public function determineType($guid)
69: {
70: $ocs = $this->getObjectClasses($guid);
71: return $this->_determineType($guid, $ocs);
72: }
73:
74: /**
75: * Determine the type of an object by its tree position and other
76: * parameters.
77: *
78: * @param string $guid The GUID of the object to examine.
79: * @param array $ocs The object classes of the object to examine.
80: *
81: * @return string The class name of the corresponding object type.
82: *
83: * @throws Horde_Kolab_Server_Exception If the object type is unknown.
84: */
85: protected function _determineType($guid, array $ocs)
86: {
87: $ocs = array_reverse($ocs);
88: foreach ($ocs as $oc) {
89: try {
90: $class_name = 'Horde_Kolab_Server_Object_' . ucfirst(strtolower($oc));
91: Horde_Kolab_Server_Object_Factory::loadClass($class_name);
92: return $class_name;
93: } catch (Horde_Kolab_Server_Exception $e) {
94: }
95: }
96: throw new Horde_Kolab_Server_Exception(
97: sprintf("Unknown object type for GUID %s.", $guid),
98: Horde_Kolab_Server_Exception::SYSTEM
99: );
100: }
101:
102: /**
103: * Generates a GUID for the given information.
104: *
105: * @param string $type The class name of the object to create.
106: * @param string $id The id of the object.
107: * @param array $info Any additional information about the object to create.
108: *
109: * @return string The GUID.
110: */
111: public function generateServerGuid($type, $id, array $info)
112: {
113: return sprintf('%s,%s', $id, $this->getComposite()->server->getBaseGuid());
114: }
115:
116: /**
117: * Get the LDAP object classes for the given GUID.
118: *
119: * This is meant to be a shortcut for the structure handler. It should be
120: * used when determining the object type.
121: *
122: * @param string $guid GUID of the object.
123: *
124: * @return array An array of object classes.
125: *
126: * @throws Horde_Kolab_Server_Exception If the object has no
127: * object classes.
128: */
129: protected function getObjectClasses($guid)
130: {
131: $object = $this->getComposite()->server->read(
132: $guid, array('objectClass')
133: );
134: if (!isset($object['objectClass'])) {
135: throw new Horde_Kolab_Server_Exception(
136: sprintf(
137: "The object %s has no %s attribute!",
138: $guid, 'objectClass'
139: ),
140: Horde_Kolab_Server_Exception::SYSTEM
141: );
142: }
143: $result = array_map(
144: 'strtolower',
145: $object['objectClass']
146: );
147: return $result;
148: }
149:
150: public function getExternalAttribute(
151: $name,
152: Horde_Kolab_Server_Object_Interface $object
153: ) {
154: $class = ucfirst(strtolower($name));
155: $object_attribute_class = 'Horde_Kolab_Server_Object_Attribute_'
156: . $class;
157: $structure_attribute_class = 'Horde_Kolab_Server_Structure_Attribute_'
158: . $class;
159:
160: if (class_exists($structure_attribute_class)) {
161: $structure_attribute = new $structure_attribute_class($object, $name);
162: } else {
163: switch ($name) {
164: case 'Firstnamelastname':
165: $structure_attribute = new Horde_Kolab_Server_Structure_Attribute_Double(
166: $object, array('givenName', 'sn')
167: );
168: break;
169: default:
170: $structure_attribute = new Horde_Kolab_Server_Structure_Attribute_Value(
171: $object, $name
172: );
173: break;
174: }
175: }
176:
177: switch ($name) {
178: case 'objectClass':
179: $structure_attribute = new Horde_Kolab_Server_Structure_Attribute_Locked(
180: $structure_attribute
181: );
182: default:
183: break;
184: }
185:
186:
187: if (class_exists($object_attribute_class)) {
188: $object_attribute = new $object_attribute_class($structure_attribute, $name);
189: } else {
190: switch ($name) {
191: default:
192: $object_attribute = new Horde_Kolab_Server_Object_Attribute_Value(
193: $structure_attribute, $name
194: );
195: break;
196: }
197: }
198:
199: /* case 'Guid': */
200: /* return 'dn'; */
201: /* case 'Uid': */
202: /* return 'uid'; */
203: /* case 'Mail': */
204: /* return 'mail'; */
205: /* case 'Alias': */
206: /* return 'alias'; */
207: /* case 'Delegate': */
208: /* return 'kolabDelegate'; */
209: /* case 'Firstnamelastname': */
210: /* return array('givenName', 'sn'); */
211: /* case 'Openldapaci': */
212: /* return 'openLDAPaci'; */
213: /* case 'Kolabhomeserver': */
214: /* return 'kolabHomeServer'; */
215: /* case 'Kolabfreebusyhost': */
216: /* //@todo: rename to kolabFreeBusyService(Url) */
217: /* return 'kolabFreeBusyServer'; */
218: /* case 'Createtimestamp': */
219: /* case 'Createtimestampdate': */
220: /* return 'createTimeStamp'; */
221: /* case 'Modifytimestamp': */
222: /* case 'Modifytimestampdate': */
223: /* return 'modifyTimeStamp'; */
224: /* case 'Id': */
225: /* return null; */
226: /* default: */
227: /* throw new Horde_Kolab_Server_Exception( */
228: /* sprintf('Undefined internal attribute "%s"', $external) */
229: /* ); */
230: /* } */
231:
232: return $object_attribute;
233: }
234:
235: /**
236: * Maps the external attribute name to its internal counterpart(s).
237: *
238: * @param string $external The external attribute name.
239: *
240: * @return string The internal attribute name(s).
241: */
242: private function _mapExternalToInternal($external)
243: {
244: switch ($external) {
245: case 'Guid':
246: return 'dn';
247: case 'Uid':
248: return 'uid';
249: case 'Mail':
250: return 'mail';
251: case 'Alias':
252: return 'alias';
253: case 'Delegate':
254: return 'kolabDelegate';
255: case 'Firstnamelastname':
256: return array('givenName', 'sn');
257: case 'Openldapaci':
258: return 'openLDAPaci';
259: case 'Kolabhomeserver':
260: return 'kolabHomeServer';
261: case 'Kolabfreebusyhost':
262: //@todo: rename to kolabFreeBusyService(Url)
263: return 'kolabFreeBusyServer';
264: case 'Createtimestamp':
265: case 'Createtimestampdate':
266: return 'createTimeStamp';
267: case 'Modifytimestamp':
268: case 'Modifytimestampdate':
269: return 'modifyTimeStamp';
270: case 'Id':
271: return null;
272: default:
273: return $external;
274: }
275: }
276:
277: /**
278: * Maps the external attribute name to its internal counterpart.
279: *
280: * @param string $external The external attribute name.
281: *
282: * @return string The internal attribute name.
283: */
284: public function mapExternalToInternalAttribute($external)
285: {
286: $internal = $this->_mapExternalToInternal($external);
287: if (is_string($internal)) {
288: return $internal;
289: } else if (is_array($internal)) {
290: throw new Horde_Kolab_Server_Exception('Multiple internal attributes!');
291: } else if ($internal === null) {
292: throw new Horde_Kolab_Server_Exception('No internal attribute mapping!');
293: }
294: throw new Horde_Kolab_Server_Exception(
295: sprintf(
296: 'Invalid internal attribute mapping: %s',
297: print_r($internal, true)
298: )
299: );
300: }
301:
302: /**
303: * Maps the external attribute names to their internal counterparts.
304: *
305: * @param string $external The external attribute names.
306: *
307: * @return string The internal attribute names.
308: */
309: public function mapExternalToInternalAttributes(array $external)
310: {
311: $result = array();
312: foreach ($external as $attribute) {
313: $internal = $this->_mapExternalToInternal($attribute);
314: $result = array_merge($result, (array) $internal);
315: }
316: $result = array_unique($result);
317: return $result;
318: }
319: }
320: